3

重複の可能性:
スイングでボタンをクリックしてラベルテキストを何度か変更しても機能しない

Java Swing を使用して、2 つのコンポーネント JButton と JLabel を使用する GUI を開発しています。JLabel のテキストは、最初は「ボタンをクリックしてください」に設定されています。ボタンをクリックした後、JLabelのテキストを「処理中」に変更し、最後に「処理済み」に変更します

したがって、ボタンをクリックすると、コントロールは ActionPerformed になり、 setText() メソッドを使用して JLabel のテキストを「処理中」に設定しました。ActionPerformed の最後のステートメントは、setText() を使用して JLabel のテキストを「処理済み」に設定しています。

プログラムを実行すると、ラベルに「ボタンをクリックしてください」と表示されます。最終的には「処理済み」に変わります。ただし、「処理中」と表示されることはありません。

4

2 に答える 2

9

現在動作していない理由は、GUI の更新を処理する Java スレッドがリスナーのイベントも処理するためです。そのため、メソッドを呼び出すと、GUI スレッド (イベント ディスパッチ スレッドの EDT と呼ばれます) にコンポーネントを更新するように指示しますが、EDT は現在コードを実行するメソッドsetText()内にあるため、現時点では実行できません。actionPerformed()

だから、どんな仕事でもするコードを入れて、新しいスレッドで JLabel のテキストを変更するべきだと思います。したがって、EDT は で開始し、actionPerformed()JLabel のテキストが変更されたときに自由に GUI を更新できます。

このようなもの:(runメソッドを実装する必要があります)

public void actionPerformed(ActionEvent e) {
    Thread t = new Thread(new Runnable() {
        @Override
        public void run() {
            myLabel.setText("Processing");
            //Do the job
            myLabel.setText("Processed");
        }     
    });
    t.start();
}

理想的にはsetText()、コンポーネントを変更するメソッドなどは、バグを回避するために EDT 自体から呼び出す必要があります...これは、私が示した例には当てはまりません。やりたい場合は、次の方法を使用します。

SwingUtilities.invokeLater(new Runnable() {
    public void run() {
        myLabel.setText("my text");
    }
});
于 2012-11-06T22:16:05.890 に答える
1

「処理中」と「処理済み」のテキストの設定には遅延が必要JLabelです。そうしないと、テキストの変更が速すぎて観察できなくなります。

これを行う1つの方法は、2つの呼び出しの間にスイングタイマーを使用することです。setTextあなたJButton ActionListenerはこのように見えるかもしれません:

public void actionPerformed(ActionEvent e) {
    label.setText("Processing...");

    ActionListener taskPerformer = new ActionListener() {
        public void actionPerformed(ActionEvent evt) {
            label.setText("Processed");
        }
    };
    Timer timer = new Timer(1000, taskPerformer); // delay one sec
    timer.setRepeats(false);
    timer.start();
}
于 2012-11-06T22:08:22.507 に答える