私の質問は に関連していSwingUtilities.invokeLater
ます。いつ使用すればよいですか?GUI コンポーネントを更新する必要があるたびに使用する必要がありますか? それは正確に何をしますか?直感的に聞こえず、一見不要なコードを追加するため、それに代わるものはありますか?
5 に答える
GUI コンポーネントを更新する必要があるたびに使用する必要がありますか?
いいえ、イベント ディスパッチ スレッド (EDT) を既に使用している場合は、クリックや選択などのユーザーが開始したイベントに応答するときに常に発生します。(actionPerformed
メソッドなどは常に EDT によって呼び出されます。)
ただし、EDT を使用しておらず、GUI の更新を行いたい場合 (タイマー スレッドやネットワーク スレッドなどから GUI を更新する場合)、EDT によって更新が実行されるようにスケジュールする必要があります。 . そのためのメソッドです。
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 が存在しない場合は、を使用して新しい EDT を作成する必要があります
invokeLater()
。あなたはそれをテストすることができますif (SwingUtilities.isEventDispatchThread()) {...
は存在しますが、今日まで、GUI (JTree & JTable) へのハードな変更を除いて、私 (私の見解)の代わりに
invokeAndWait()
使用する理由を見つけることができませんが 、 Substance L&F (EDT でのイベントの一貫性をテストするのに優れています) を使用するだけです。invokeAndWait()
invokeLater()
基本的なこと: Swing での並行性
バックグラウンド タスクからのすべての出力は、
invokeLater()
すべての Swing アプリケーションには、少なくとも 2 つのスレッドがあります。
- アプリケーションを実行するメインスレッド
- EDT (Event Dispatching Thread) は、UI を更新するスレッドです (したがって、UI はフリーズしません)。
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() スレッドとワーカー スレッドを除いて、多くのケースをカバーしています。