web-dev-qa-db-ja.com

SwingUtilities.invokeLater

私の質問はSwingUtilities.invokeLaterに関連しています。いつ使用すべきですか? GUIコンポーネントを更新する必要があるたびに使用する必要がありますか?それは正確に何をしますか?それは直感的に聞こえず、一見不要なコードを追加するため、それに代わるものはありますか?

52
FadelMS

GUIコンポーネントを更新するたびに使用する必要がありますか?

いいえ。既にイベントディスパッチスレッド(EDT)を使用している場合は、クリックや選択などのユーザーが開始したイベントに応答するときに常に発生します。 (actionPerformedメソッドなどは、常にEDTによって呼び出されます。)

EDTでnotであり、GUI更新を行いたい場合(タイマースレッドまたはネットワークからGUIを更新する場合)スレッドなど)、EDTによって実行される更新をscheduleする必要があります。それがこの方法の目的です。

Swingは基本的にスレッドセーフではありません。つまり、そのAPIとのすべての対話は、単一のスレッド(EDT)で実行する必要があります。別のスレッド(タイマースレッド、ネットワークスレッドなど)からGUI更新を行う必要がある場合は、言及したメソッド(SwingUtilities.invokeLater、SwingUtilities.invokeAndWait、...)などのメソッドを使用する必要があります。

52
aioobe
_Swing is single threaded and all changes to the GUI must be done on EDT 
_

invokeLater()の基本的な使用法

  1. メインメソッドは常にinvokeLater()でラップする必要があります

  2. EventQueueの終わりまでの遅延(ただし非同期)アクション/イベント、

  3. EDTが存在しない場合は、invokeLater()を使用して新しいEDTを作成する必要があります。 if (SwingUtilities.isEventDispatchThread()) {...でテストできます

  4. invokeAndWait()が存在しますが、今日まで(私の見解では)invokeAndWait()の代わりにinvokeLater()を使用する理由を見つけることができません。 JTree&JTable)、ただし Substance L&F のみ(EDTでのイベントの一貫性のテストに優れています)

  5. 基本的なもの: Swingの並行性

  6. バックグラウンドタスクからのすべての出力は、invokeLater()でラップする必要があります

14
mKorbel

すべてのSwingアプリケーションには、少なくとも2つのスレッドがあります。

  1. アプリケーションを実行するメインスレッド
  2. EDT(イベントディスパッチスレッド)は、UIを更新するスレッドです(UIはフリーズしません)。

UIを更新する場合は、EDT内でコードを実行する必要があります。 SwingUtilities.invokeLater、SwingUtilities.invokeAndWait、EventQueue.invokeLater、EventQueue.invokeAndWaitなどのメソッドを使用すると、EDTでコードを実行できます。

7
Ammar

今回の私の質問は_SwingUtilities.invokeLater_に関連しています:いつ使用すべきですか?

重要なことは、JavaにはSwing関連のイベントを処理する個別のスレッド(EDT)があることです。

invokeLater()を使用して、現在のスレッドで実行するのではなく、デスクトップアプリケーションのメインJFrameを表示する必要があります(たとえば)。また、後でアプリケーションを正常に閉じるためのコンテキストも作成します。

ほとんどのアプリケーションでこれで終わりです。

GUIコンポーネントを更新する必要があるたびに使用する必要がありますか?それは正確に何をしますか?

いいえ。GUIコンポーネントを変更すると、Swingが後でディスパッチするために登録されたイベントがトリガーされます。このイベントのリスナーがある場合、EDTスレッドはそれをどこかで呼び出します。 invokeLater()を使用する必要はありません。コンポーネントのリスナーを適切に設定するだけです。

このスレッドは、画面上にフレームなどを描く同じスレッドであることに注意してください。したがって、リスナーは複雑/長時間/ CPU集中型のタスクを実行しないでください。実行すると、画面がフリーズします。

それは直感的に聞こえず、一見不要なコードを追加するため、それに代わるものはありますか?

コンポーネントに関心のあるinvokeLater() +リスナーを使用してアプリケーションを表示するよりも多くのコードを記述する必要はありません。残りはSwingによって処理されます。

7

ユーザーが開始するほとんどのイベント(クリック、キーボード)はすでにEDT上にあるため、そのためにSwingUtilitiesを使用する必要はありません。これは、EDTを更新するmain()スレッドとワーカースレッドを除いて、多くのケースをカバーしています。

3
Garrett Hall