1

このJLabelをこのJPanel間で移動するのに問題がありますか?以下にコードを入れます。基本的に起こるはずのことは、「男」と呼ばれるJLabelがゆっくりと右に移動することです。唯一の問題は、JLabelが更新されていないことです。最初に移動すると、JLabelが消えてしまいます。

public class Window extends JFrame{

    JPanel panel = new JPanel();
    JLabel guy = new JLabel(new ImageIcon("guy.gif"));
    int counterVariable = 1;

    //Just the constructor that is called once to set up a frame.
    Window(){
        super("ThisIsAWindow");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        add(panel);
        panel.setLayout(null);
    }

    //This method is called once and has a while loop to  exectue what is inside.
    //This is also where "counterVariable" starts at zero, then gradually
    //goes up. The variable that goes up is suposed to move the JLabel "guy"...
    public void drawWorld(){
        while(true){
            guy.setBounds(counterVariable,0,50,50);
            panel.add(guy);
            counterVarialbe++;
            setVisible(true);
            try{Thread.sleep(100)}catch(Exception e){}
        }

    }

変数「counterVariable」を変更した後、JLabelが右に移動するのではなく、消えてしまう理由についての考え。-ありがとう!:)

4

1 に答える 1

4

コードが原因で、Swingイベントスレッドで長時間実行プロセスが実行され、このスレッドが必要なアクション(GUIをペイントしてユーザー入力に応答する)を実行できなくなっています。これにより、GUI全体が効果的にスリープ状態になります。

問題と提案:

  • Thread.sleep(...)SwingイベントディスパッチスレッドまたはEDTを呼び出さないでください。
  • while (true)EDTには絶対にありません。
  • 代わりに、これらすべてにスイングタイマーを使用してください。
  • JLabelをJPanelに追加し続ける必要はありません。JPanelに追加されると、そこに残ります。
  • setVisible(true)同様に、JLabelを呼び出し続ける必要はありません。表示されると、表示されたままになります。
  • repaint()移動したJLabelを保持しているコンテナを呼び出して、コンテナとその子を再描画するように要求します。

例えば、

public void drawWorld(){
  guy.setBounds(counterVariable,0,50,50);
  int timerDelay = 100;
  new javax.swing.Timer(timerDelay, new ActionListener() {
    public void actionPerformed(ActionEvent evt) {
      countVariable++;
      guy.setBounds(counterVariable,0,50,50);
      panel.repaint();
    }
  }).start;
}

警告:コードはコンパイル、実行、またはテストされていません

于 2012-06-17T02:51:04.780 に答える