56

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

4

5 に答える 5

52

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

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

ただし、EDT を使用しておらず、GUI の更新を行いたい場合 (タイマー スレッドやネットワーク スレッドなどから GUI を更新する場合)、EDT によって更新が実行されるようにスケジュールする必要があります。 . そのためのメソッドです。

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

于 2011-08-25T20:41:54.073 に答える
14
Swing is single threaded and all changes to the GUI must be done on EDT 

の基本的な使い方invokeLater()

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

  2. EventQueueアクション/イベントを,の最後まで遅延 (ただし非同期)

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

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

  5. 基本的なこと: Swing での並行性

  6. バックグラウンド タスクからのすべての出力は、invokeLater()

于 2011-08-25T21:00:10.737 に答える
7

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

  1. アプリケーションを実行するメインスレッド
  2. EDT (Event Dispatching Thread) は、UI を更新するスレッドです (したがって、UI はフリーズしません)。

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

于 2011-08-25T20:57:10.357 に答える
7

今回の私の質問は、SwingUtilities.invokeLaterいつ使用すればよいですか?に関するものです。

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

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

ほとんどのアプリケーションではこれで十分です。

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

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

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

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

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

于 2011-08-25T20:57:56.247 に答える
3

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

于 2011-08-25T20:57:17.197 に答える