4

SwingでUIを実装しています。1つのコンポーネントが作業を行うため、時間がかかる場合があるため、を使用しますSwingUtilities.invokeLater。しかし、私はいくつかの古いコードを読んでいて、これをActionListener:で見つけました

if (!SwingUtilities.isEventDispatchThread()) {
    SwingUtilities.invokeLater(new Runnable() {
         public void run() {
             // code X
         }
    });
} else {
   // code X
}

code XEDTから分離しているので理にかなっていると思いました。しかし、何度か使用したことがあり、どちらの場合もelseパーツを忘れてしまったため、エラーが発生しやすいことがわかりました。

問題は、SwingUtilities.isEventDispatchThread()チェックが必要かどうかです。または、私はEDTに参加しておらず、常に使用していると想定invokeLaterできますか?

どうもありがとう。

4

4 に答える 4

14

EDTを使用している場合でも、後で呼び出すことは問題ありませんが、イベントのタイミングが確実に変わるため、EDTを使用しているときに、ここでコードのシーケンスに依存していないことを確認する必要があります。そうは言っても、elseを忘れないようにする簡単な方法は、呼び出しをユーティリティメソッドでラップすることです。

public static void invokeInDispatchThreadIfNeeded(Runnable runnable) {
    if (EventQueue.isDispatchThread()) {
        runnable.run();
    } else {
        SwingUtilities.invokeLater(runnable);
    }
}

そうすれば、あなたは決して忘れませんelse

また、一般的に、あなたのidomで繰り返すことcode xは非常に悪い考えです。後で、そのコードを修正または改善する必要があり、一方の場所でのみそれを行い、もう一方の場所にバグを残すことに気付くかもしれません。

于 2010-04-21T15:32:37.423 に答える
2

あなたの特定のユースケースでは、チェックは不要だと思います。isEventDispatchThread()直接呼び出すinvokeLater()と新しいスレッドが作成されないため、パフォーマンスが低下することはありません。

于 2010-04-21T15:11:53.253 に答える
0

コードは、EDT上にあるかどうか(関連する場合)を実際に知る必要があります。したがってjava.awt.EventQueue.isDispatchThread、アサーションに任せる必要があります。

于 2010-04-21T15:47:13.463 に答える
0

コードにEDTによるthread(A)launchがあり、そのthread(A)にGUIを変更する必要のある別のthread(B)がある場合は、thread(B)でinvokeLaterを使用する必要があります。 )。ただし、GUIの変更が最初のスレッド(A)によって行われている場合は、invokeLaterを使用する必要はありません。

于 2017-11-06T17:49:05.967 に答える