1

単純なJButtonを作成しようとしています。これをクリックすると、単純なJLabelがテキストを「2番目のテキスト」に変更します。その後、現在のスレッドを数秒間スリープさせ、最後にJLabelがテキストを再度変更します。 「3番目のテキスト」への時間。私はここでそれを行ったと思いますが、それは私が望むようには機能しません。以下に示すコードは、JButtonを押したままにしたかのように、指定した時間枠でフリーズさせます。その後、ラベルは3番目の状態に変わります。つまり、「秒のテキスト」は表示されません。

どうすればいいのか教えてください。

ありがとうございました。

package testPackage;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class Demo {

    public static void main(String[] args) throws InterruptedException {
        JFrame frame = new JFrame();
        JButton button = new JButton("Click me!");
        final JLabel label = new JLabel("first text");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(600, 600);
        JPanel panel = new JPanel();
        panel.add(button);
        panel.add(label);
        button.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                label.setText("second text");
                try {
                    Thread.currentThread();
                    Thread.sleep(4000);
                } catch (InterruptedException exc) {
                    System.out.println("Erorrrrr");
                }

            }
        });

        frame.add(panel);
        frame.setVisible(true);
    }

}
4

4 に答える 4

2

Javaの内部を考えるときに、結果を確認するために実行する必要があるのは、テキストプロパティの変更だけではありません。コントロールも再描画する必要があります(無効になっている可能性があります)。

sleepを呼び出すことにより、JavaGUI内部ワーカーが変更したコントロールを再描画するのを実際に停止します。それは睡眠が終わった後にのみ起こることができます。

于 2013-03-05T13:51:32.627 に答える
0

GUIはスレッド上で実行されます。そのスレッドをx秒間スリープすると、GUIがx秒間フリーズします。

Markoのコメントに記載されているように、「代わりに、javax.swing.Timerを使用して遅延イベントをスケジュールする必要があります」

于 2013-03-05T13:50:06.117 に答える
0

イベントディスパッチスレッド(GUIイベントを処理するスレッド)でスリープすると、GUIがフリーズします。アクションリスナーからそこでスリープするまでのバックグラウンドスレッドを開始できます。

public void actionPerformed(ActionEvent e)
{{
    label.setText( "text 1");
    new Thread(new Runnable()
    {{
        public void run()
        {{
            試す {
                Thread.sleep(1000);
            } catch(InterruptedException ignore){}

            //EDTで実行するためにSwingコードをキューに入れます
            EventQueue.invokeLater(new Runnable()
            {{
                public void run()
                {{
                    label.setText( "text2");
                }
            });
        }
    })。始める();
}
于 2013-03-05T13:53:20.370 に答える
0

アクション実行メソッドでは、変更を行うためにメインGUIスレッドを解放する必要があります。

したがって、actionPerformedメソッドで新しいスレッドを開くと、メインGUIスレッドが解放され、スリープ後にlabel.setText( "third text")が呼び出され、ラベルが2番目のテキストに変更されます。最初に4秒間待機してから、次のように変更します。 3番目のテキスト

       @Override
        public void actionPerformed(ActionEvent e) {
            label.setText("second text");
            new Thread(){
              public void run(){
                try {
                  //Thread.currentThread();
                  Thread.sleep(4000);
                  label.setText("third text");
               } catch (InterruptedException exc) {
                System.out.println("Erorrrrr");
             }
           }
         }.start();

        }
于 2013-03-05T14:04:52.217 に答える