0

私は JFrame/JPanelsrepaint();などをいじろうとしていますが、スレッドを開始し、run while true を介して repaint を呼び出すと、System.out.println("as");ループが実行されているかどうかを確認するために配置した行だけが吐き出されます。

質問は次のとおりです。ループで再描画を呼び出すと、図面が消えるのはなぜですか? (/のJFrame付いたのみが表示されているようで、パネルなどはありません。)canvas_widthheight

public static void main(String[] args) {

    JFrame frame = new JFrame();
    frame.setSize(CANVAS_WIDTH, CANVAS_HEIGHT);
    frame.setPreferredSize(new Dimension(CANVAS_WIDTH, CANVAS_HEIGHT));
    frame.setVisible(true);
    frame.setResizable(false);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    JPanel p = new JPanel(new GridLayout());

    frame.getContentPane().add(p);
    Something s = new Something();

    p.add(s);
    p.setBackground(Color.black);
    frame.pack();

}

そして何かクラス:

public class Something extends JPanel implements Runnable {


public Something(){
    Thread t = new Thread();
    t.start();
    run();

}


@Override
public void paintComponent(Graphics g){
    super.paintComponent(g);
    g.setColor(Color.cyan);
    g.fillRect(0, 0, getWidth()-150, getHeight()-100);
    g.setColor(Color.BLACK);
    g.fillOval(10, 10, 25, 25);

}


@Override
public void run() {
    while(true){
    repaint();
    System.out.println("as");

    try {
        Thread.sleep(1);
    } catch (InterruptedException e){}
    }
}
}

contentpaneこれが正しく行われたかどうか確信が持てないため、に関するヘルプをいただければ幸いです。

4

2 に答える 2

3

を呼び出す代わりに、タスクを繰り返すための Swing を実装Thread.sleep(n)します。これにより、イベント ディスパッチ スレッドで確実に呼び出されます。ThreadTimerrepaint()

詳細については、Swingでの同時実行を参照してください。

また、1 ミリ秒ごとに再描画することは非常に楽観的です。

作業中の SSCCE EG (このバージョンでは、結果として生じるペイント操作の座標が実際に変更されることに注意してください。これは、何かが起こっていることを知るためです!

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class Something extends JPanel {

    static final int CANVAS_WIDTH = 400;
    static final int CANVAS_HEIGHT = 100;
    private int xDelta = 0;

public Something(){
    ActionListener animater = new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent ae) {
            repaint();
        }
    };
    Timer t = new Timer(10,animater);
    t.start();
}


@Override
public void paintComponent(Graphics g){
    super.paintComponent(g);
    g.setColor(Color.cyan);
    g.fillRect(0, 0, getWidth()-(xDelta--), getHeight()-100);
    g.setColor(Color.BLACK);
    g.fillOval(xDelta, 10, 25, 25);

    if (xDelta<0) {
        xDelta = CANVAS_WIDTH;
    }
}

@Override
public Dimension getPreferredSize() {
    return new Dimension(CANVAS_WIDTH, CANVAS_HEIGHT);
}

public static void main(String[] args) {

    JFrame frame = new JFrame();

    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    JPanel p = new JPanel(new GridLayout());

    frame.getContentPane().add(p);
    Something s = new Something();

    p.add(s);
    p.setBackground(Color.black);
    frame.pack();
    frame.setResizable(false);
    frame.setVisible(true);
}
}
于 2013-05-03T07:33:09.587 に答える
1
  1. 新しい Thread で Runnable を開始するには、java.lang.Thread.Thread( Runnable )コンストラクターを使用します。
  2. Swing イベント ループの外側で GUI コンポーネントのメソッドを呼び出すことはお勧めできません。代わりにSwing タイマーを使用してください。

コードは次のようになります。

public static void main(String[] args) {
   ...
   new Timer( 40, new ActionListener() {
      public void actionPerformed(ActionEvent evt) {
         repaint
      }
   }).start();
   ...
}
于 2013-05-03T07:21:54.633 に答える