14

Swing と、GUI の更新に EDT を使用することに関して、いくつか質問があります。私はちょうどこのことについて読み始めたので、私はこの分野の完全な初心者です:

  1. EDT で実行する必要がある操作はどれですか? そうでない場合は、単に例外が発生していますか?
  2. 実際にEDTに自動的に入る特定の時間はありますか?
  3. を使用してタスクをスケジュールする場合、SwingUtilities.invokeLaterそれを GUI 更新タスク (EDT) の現在のキューに入れますよね?
  4. 上記のキューへのアクセスは同期されているか、同時収集が使用されていると思われますが、2 つのバックグラウンド スレッドから 2 つの GUI 更新タスクをスケジュールすると、どちらが最初に追加されるかわかりません。たとえば、スレッド 1 FIRST が JLable のテキストを「yes」に設定するタスクを送信し、その後すぐに 2 番目のスレッドが来て、その値を「no」に設定するタスクを送信した場合、次のことが保証されます。結果は「はい」になりますか、それとも単に OS によってこれらがどのようにスケジュールされているかの問題ですか?
  5. done()SwingWorker は、メソッドが EDT で実行されることをどのように保証しますか? 次のコードを設定します。

      future = new FutureTask<T>(callable) {
                   @Override
                   protected void done() {
                       doneEDT();
                       setState(StateValue.DONE);
                   }
               };
    

それで、FutureTaskが何らかの方法でそれinvokeLaterが呼び出されることを確認するかどうか疑問に思っていましたか?

ご回答ありがとうございます。

4

4 に答える 4

18
  1. 良いルールは、すべての操作(アクセス/更新/ ...)がEDTで行われるべきであるということです。javadoc(特定のクラスの特定のメソッド)で言及されているいくつかの例外がありますが、それらを覚えるのは非常に難しいため、「EDTですべてを実行する」アプローチに固執する方が簡単です。例外は発生しません(幸い、JavaFXはこの欠点を修正しました)。カスタムを使用してRepaintManager、これらの違反のほとんどを検出できます。この記事を参照してください。

  2. ユーザーによってトリガーされたものはすべてEDTで処理されます。たとえば、ユーザーがボタンをクリックするactionPerformedと、対応するActionまたはActionListenerのがEDTで呼び出されます。

  3. 正しい

  4. 最初にスケジュールしたものが最初に実行されます。invokeLater呼び出しRunnableは、キューの最後にを追加するだけです。invokeLater少し後でもう一度使用するとRunnable、以前にスケジュールされたの後にこの新しいものが追加されRunnableます。

  5. のコードを見てくださいdoneEDT

     private void doneEDT() {
         Runnable doDone = 
             new Runnable() {
                 public void run() {
                     done();
                 }
             };
         if (SwingUtilities.isEventDispatchThread()) {
             doDone.run();
         } else {
             doSubmit.add(doDone);
         }
     }
    
于 2012-08-06T09:14:21.043 に答える
8
  1. 基本的に、Swing コンポーネントまたは Swing コンポーネントのモデルを使用するたびに、EDT で実行する必要があります。そうしないと、例外は発生しません。動作する可能性がありますが、動作しない、動作が不安定になる、データが破損するなどの可能性もあります。
  2. すべての Swing イベント リスナーは、EDT で呼び出されます。基本的に、main メソッドを除いて、明示的にスレッドを開始したり、SwingWorker を使用したりしない限り、Swing アプリケーションのすべてのコード行はデフォルトで EDT で実行されます。
  3. はい。
  4. SwingUtilities.invokeLater() に送信されたタスクは、送信された順序と同じ順序で実行されます。
  5. 内部的には、SwingUtilities.invokeLater() または同様のメソッドを使用します。FutureTask は Swing とは何の関係もありません。done メソッドが EDT で実行されることを保証するのは SwingWorker です。このdoneEDT()メソッドには次のコメントがあります: Invokes done on the EDT .
于 2012-08-06T09:12:36.833 に答える
0

SwingWorker は、次のコードを使用して、EDT で done() メソッドが実行されるようにします。

    Runnable doDone =
        new Runnable() {
            public void run() {
                done();
            }
        };
    if (SwingUtilities.isEventDispatchThread()) {
        doDone.run();
    } else {
        doSubmit.add(doDone);
    }

実際には doDone 変数を AccumulativeRunnable doSubmit に追加し、

以下のコードがあることがわかる AccumulativeRunnable.java のソース コードを参照してください。

保護されたボイド送信(){

SwingUtilities.invokeLater(これ);

}

そのため、swingworker はメソッド done() が EDT で実行されるようにします。

于 2016-01-21T02:47:43.380 に答える
-1

1. Java GUI アプリケーションでは、main()メソッドは長生きしません。で GUI の構築をスケジュールした後 Event Dispatcher Threadmain() メソッドは終了します...そして、GUI を処理するのは EDT の責任です。

2. EDT でアプリを起動する必要はありません。自動的に行われます。

3常に UI 作業を UI スレッドで維持し、非 UI 作業を非 UI スレッドで維持します。

そのため、GUI 作業専用の GUI スレッドである EDT スレッドを常に維持してください。

例えば:

public static void main(String[] args){
    EventQueue.invokeLater(new Runnable(){
          public void run(){    
            myframe.setVisible(true);
         }
     }
}

4.時間がかかるメソッドを処理するために、別の非 UI スレッドを作成します。

5.Thread Java に特別に導入されたまたは を使用SwingWorkerして、UI スレッドと非 UI スレッドを同期することができます。

6. SwingWorker は done() メソッドが EDT で実行されることを保証しませんが、その出力を GUI スレッドである EDT スレッドに同期します。

于 2012-08-06T09:07:39.463 に答える