2011-08-25 7 views
51

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

+2

これは、 'Control.BeginInvoke'と同じです。 – SLaks

+0

@SLaksそれは、私はそれを使用する必要はありません1つのスレッドを持っていることを意味ですか? – FadelMS

+4

@FadelMS Swingフレームワークは独自のスレッド(EDT)を生成するので、常にそのスレッドがあります。 (あなたはユーザーのクリックなどを処理する "メッセージチェック"ループを持っていません、そうでしょう、様々な 'actionPerformed'メソッドはどのように呼び出されますか?EDTによって!)あなたは* *スレッド、私はあなたが* EDTを持っている(つまり、GUIを投げてメインメソッドの端から落ちた)ように私はintepretする必要があります。その場合、いいえ、* invokeLaterを使う必要はありません。しかし、あなたは "バックグラウンド"処理を行うことはできません。そうすれば、GUIは完全にロックされます... – aioobe

答えて

52

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

いいえ、あなたは、このようなクリックや選択などのユーザーが開始したイベントに応答するときに、常にそうであるイベントディスパッチスレッド(EDT)に、すでにしている場合。 (actionPerformed方法などは、必ずEDTによって呼び出されます。)

あなたはしかし、EDT上ないだとGUIの更新(あなたには、いくつかのタイマースレッドからGUIを更新する場合、またはからをしたい場合いくつかのネットワークスレッドなど)、スケジュール EDTによって実行される更新が必要です。これがこの方法です。

スイングは基本的にスレッドが安全ではありません。つまり、そのAPIとのすべてのやりとりは、1つのスレッド(EDT)で実行する必要があります。別のスレッド(タイマースレッド、ネットワーキングスレッドなど)からGUI更新を行う必要がある場合は、上記のようなメソッド(SwingUtilities.invokeLater、SwingUtilities.invokeAndWait、...)を使用する必要があります。

+0

@ Jens:つまり、同じスレッド(Swing)や実行時に何かをしていると、私はそれをやることができません。 – FadelMS

+1

さて、「実行時にやっていること」はあまり正確ではありません。実行時に、タイマースレッドで、そうでない場合は、これらのメソッドがないと実行できません。 – aioobe

+0

aioobeありがとう、それを得た。 – FadelMS

7

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

  • EDT(ユーザーインターフェイススレッド)を実行し、メインスレッドがUIを更新したスレッドである(そのUIが凍結しない

    1. を)。

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

  • +0

    シンプルでわかりやすい、ありがとうございます – Yahya

    3

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

    +0

    ほとんど、_all_ – kleopatra

    +0

    ユーザーは、GUIを更新するスレッドによって監視されているファイルを更新することができました。 –

    +1

    うーん...ユーザーが開始したイベント:ユーザーがファイル(スイング内、EDT上)を更新し、EDT上のボタンをクリックして保存します。これにより、OSがトリガーされますファイル更新イベント(外部スイング、オフEDT)通知、その通知はEDT上のGUIの更新を担当するモニター(オフEDT)に届きます – kleopatra

    7

    私の質問は今回はSwingUtilities.invokeLaterに関連しています:いつ使用しますか?

    Javaには、Swing関連のイベントを処理する別のスレッド(EDT)があります。

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

    これはほとんどのアプリケーションで使用できます。

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

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

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

    直感的に聞こえないようで、一見不必要なコードが追加されているので、代替手段はありますか?

    アプリケーションをinvokeLater() +コンポーネントで興味のあるリスナーで表示するよりもコードを書く必要はありません。残りはSwingによって処理されます。

    12
    Swing is single threaded and all changes to the GUI must be done on EDT 
    

    invokeLater()

    1. 主な方法は、常にEventQueueの終わりにinvokeLater()

    2. 遅延

      (ただし、非同期)アクション/イベントに包まれるべきために基本的な使い方、

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

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

    5. で基本的なもの:Concurrency in Swing

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

      に包まれなければなりません
    関連する問題