私の質問はSwingUtilities.invokeLater
に関連しています。いつ使用すべきですか? GUIコンポーネントを更新する必要があるたびに使用する必要がありますか?それは正確に何をしますか?それは直感的に聞こえず、一見不要なコードを追加するため、それに代わるものはありますか?
GUIコンポーネントを更新するたびに使用する必要がありますか?
いいえ。既にイベントディスパッチスレッド(EDT)を使用している場合は、クリックや選択などのユーザーが開始したイベントに応答するときに常に発生します。 (actionPerformed
メソッドなどは、常にEDTによって呼び出されます。)
EDTでnotであり、GUI更新を行いたい場合(タイマースレッドまたはネットワークからGUIを更新する場合)スレッドなど)、EDTによって実行される更新をscheduleする必要があります。それがこの方法の目的です。
Swingは基本的にスレッドセーフではありません。つまり、そのAPIとのすべての対話は、単一のスレッド(EDT)で実行する必要があります。別のスレッド(タイマースレッド、ネットワークスレッドなど)からGUI更新を行う必要がある場合は、言及したメソッド(SwingUtilities.invokeLater、SwingUtilities.invokeAndWait、...)などのメソッドを使用する必要があります。
_Swing is single threaded and all changes to the GUI must be done on EDT
_
invokeLater()
の基本的な使用法
メインメソッドは常にinvokeLater()
でラップする必要があります
EventQueue
の終わりまでの遅延(ただし非同期)アクション/イベント、
EDTが存在しない場合は、invokeLater()
を使用して新しいEDTを作成する必要があります。 if (SwingUtilities.isEventDispatchThread()) {...
でテストできます
invokeAndWait()
が存在しますが、今日まで(私の見解では)invokeAndWait()
の代わりにinvokeLater()
を使用する理由を見つけることができません。 JTree&JTable)、ただし Substance L&F のみ(EDTでのイベントの一貫性のテストに優れています)
基本的なもの: Swingの並行性
バックグラウンドタスクからのすべての出力は、invokeLater()
でラップする必要があります
すべてのSwingアプリケーションには、少なくとも2つのスレッドがあります。
UIを更新する場合は、EDT内でコードを実行する必要があります。 SwingUtilities.invokeLater、SwingUtilities.invokeAndWait、EventQueue.invokeLater、EventQueue.invokeAndWaitなどのメソッドを使用すると、EDTでコードを実行できます。
今回の私の質問は_
SwingUtilities.invokeLater
_に関連しています:いつ使用すべきですか?
重要なことは、JavaにはSwing関連のイベントを処理する個別のスレッド(EDT)があることです。
invokeLater()
を使用して、現在のスレッドで実行するのではなく、デスクトップアプリケーションのメインJFrame
を表示する必要があります(たとえば)。また、後でアプリケーションを正常に閉じるためのコンテキストも作成します。
ほとんどのアプリケーションでこれで終わりです。
GUIコンポーネントを更新する必要があるたびに使用する必要がありますか?それは正確に何をしますか?
いいえ。GUIコンポーネントを変更すると、Swingが後でディスパッチするために登録されたイベントがトリガーされます。このイベントのリスナーがある場合、EDTスレッドはそれをどこかで呼び出します。 invokeLater()
を使用する必要はありません。コンポーネントのリスナーを適切に設定するだけです。
このスレッドは、画面上にフレームなどを描く同じスレッドであることに注意してください。したがって、リスナーは複雑/長時間/ CPU集中型のタスクを実行しないでください。実行すると、画面がフリーズします。
それは直感的に聞こえず、一見不要なコードを追加するため、それに代わるものはありますか?
コンポーネントに関心のあるinvokeLater()
+リスナーを使用してアプリケーションを表示するよりも多くのコードを記述する必要はありません。残りはSwingによって処理されます。
ユーザーが開始するほとんどのイベント(クリック、キーボード)はすでにEDT上にあるため、そのためにSwingUtilitiesを使用する必要はありません。これは、EDTを更新するmain()スレッドとワーカースレッドを除いて、多くのケースをカバーしています。