1

これの初心者として、スレッドとグラフィックスを同時に使用する方法についての説明が必要です。私がやりたいことは非常に基本的なことです: フレーム内で 2 つのボールを同時に動かすだけです。これが私が試したものです:

public class Main extends JFrame
{
    private static final long serialVersionUID = 1L;
    private static final int _HEIGHT = 320, _WIDTH = 480;
    private MyPanel panel;

    public Main()
    {
        super("Test");

        panel = new MyPanel();

        this.setContentPane(panel);
        this.setBounds(350,100,_HEIGHT,_WIDTH);
        this.setDefaultCloseOperation(EXIT_ON_CLOSE);
        this.setVisible(true);
    }

    public static void main(String[] args)
    {
        new Main();
    }
}


public class MyPanel extends JPanel
{
    private static final long serialVersionUID = 1L;
    ArrayList<Ball> listBalls;

    public MyPanel()
    {
        this.setBackground(Color.WHITE);
        listBalls = new ArrayList<Ball>();
        listBalls.add(new Ball(30,30));     
    }

    @Override
    public void paint(Graphics gr)
    {
        Graphics2D g = (Graphics2D) gr;
        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g.setStroke(new BasicStroke(3f));
        super.paint(g);
        synchronized (listBalls) {
            for(Ball b : listBalls)
            {
                b.drawItself(g);
            }   
        }
    }
}



public class Ball extends JPanel implements Runnable
{
    private static final long serialVersionUID = 1L;
    private int x, y;
    private Thread thread;

    public Ball(int x, int y)
    {
        this.x = x;
        this.y = y;
    }

    public void drawItself(Graphics2D g)
    {
        g.setColor(Color.BLACK);
        g.fillOval(x, y, 13, 13);
    }

    public void run() 
    {
        Thread currentThread = Thread.currentThread();
        while (thread == currentThread) 
        {
            x+=2;
            y+=2;
            repaint();
            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

しかし、これは機能しません (ボールが表示されません)。どうすればよいかわかりません。助けてください!

4

1 に答える 1

2
  1. Ball拡張する必要はありJPanelません。子からの機能やその子の機能を使用していませんJPanel
  2. オーバーライドしないでください。代わりにpaint使用することをお勧めします。多くの理由がありますが、あなたが好きになるのは、二重バッファリングされていないpaintComponentという事実ですが、ちらつきの可能性は低いですpaintpaintComponent
  3. 必要な場合Threadは、シングルを使用してそのThread中のすべてのボールを更新してから、表示を更新することをお勧めします。これにより、通常、使用しているリソースの数が減り、よりスケーラブルになります。
  4. を開始することはありませんThread。つまり、のrunメソッドがBall呼び出されることはありません。

Swingの並行性には特別な懸念があります。概要については、Swingの並行性を確認することをお勧めします。

更新しました

SOには多くの優れた例がありますが、これは私が過去に行ったいくつかの例です...

于 2013-02-04T21:01:12.010 に答える