9

EventQueuejavadoc には、キューに入れられたイベントが順番に順番にディスパッチされる必要があると記載されています。

Runnableエンキューされた sはEventQueue.invokeLater、後続のユーザー イベント (たとえば a ) の前にディスパッチされることが保証されているのは正しいMouseEventですか? Runnableつまり、ユーザー イベントが の後に発生した場合、キューに入れられた の前にイベント ハンドラを実行できますEventQueue.invokeLater

ありがとう!

4

2 に答える 2

10

API ドキュメントには、イベントは

キューに入れられたのと同じ順序で。

しかし、ソース コードを確認すると、ほとんどの目的ではほぼ正しいのですが、常にそうであるとは限らないことがわかります。

于 2013-01-25T17:28:57.163 に答える
6

おそらく、何をしようとしているのかを説明するのが最善です。一般に、イベント ディスパッチ システムは、その内部を知らず、気にする必要がないように設計されています。UI を直接更新するイベント ハンドラーを作成している場合は、Runnable を使用せずに更新をインラインで実行することが理にかなっている場合があります。ただし、イベント ハンドラーが不確定な時間のかかる計算や処理を実行する場合は、最終的に Swing.invokeLater 呼び出しで Runnable を使用して UI 更新を実行するスレッドを使用する必要があります。ディスパッチされたイベントのシーケンスを知る必要があるということは、おそらくどこかに属しているロジックの仮定を構築しようとしていることを意味します。

たとえば、スレッドで大量の処理 (ネットワーク ダウンロードまたは DBMS クエリ) を実行し、後で UI のテキスト ラベルを更新するマウス クリック イベント ハンドラーを考えてみましょう。クリックが処理されるあいまいさを避けるために、ユーザーが UI の他の場所をクリックする前に、処理と UI の更新が確実に行われるようにする必要があります。このような場合、最初のマウス クリック イベントで UI または UI の特定のクリック可能な部分をすぐに無効にして、UI の応答性を維持しながら、元のクリック イベントが完全に処理されるまで onMouse ハンドラーが再入力されないように保護します。(次のスニペットは、Swing を作成してから何年も経っているため、疑似コードのようなものであることをお許しください。)

void setUIEnabled(boolean enable) {
   for(Button eachUIButton : getAllClickableButtons()) {
      eachUIButton.setEnabled(enable);
   }
}

void onMouseClick(MouseEvent event) {
   setUIEnabled(false);
   new Thread(
      new Runnable() {
         public void run() {
            final String result = doLengthyProcessing();
            enableRunnable = new Runnable() {
               public void run() {
                  setUIEnabled(true);
                  updateTextLabelFromLengthyProcess(result);
               }
            };
            Swing.invokeLater(enableRunnable);
         }
      }
   ).start();
}

ここでの考え方は、イベントがディスパッチされるランダムな順序に依存しないようにロジックを記述し、次の着信マウス イベントよりも処理に時間がかかる可能性が高いことを認識し、そのようなタイミングを準備することです。微妙な改善として、進行状況インジケーターまたは進行状況スピナーを描画して、ユーザーに対して作業が行われていることを示すこともできます。

于 2013-01-25T17:38:17.847 に答える