1

いくつかのメソッドを持つ Swing コンポーネントを作成しました。このクラスのすべてのメソッドを Swing イベント ディスパッチ スレッド (EDT) で実行し、呼び出し側はワーカー スレッドで実行したいと考えています。現在私の頭にある唯一の解決策はこれです:

このクラスの各メソッドについて:

public void a(params)

名前を次のように変更する必要があります。

private void aOnEDT(params)

別のメソッドを追加します。

public void a(params) {
    SwingUtilities.invokeAndWait(new Runnable(){
        public void run() {
            aOnEDT(params);
        }
    });
}

でもこれ、まずくないですか?どうすればいいですか?

4

7 に答える 7

3

通話が現在 EDT で行われているかどうかをテストし、そうでない場合はドロップRunnableすることができます。SwingUtilites.invokeLater()

public void myMethod() {
       if (SwingUtilities.isEventDispatchThread()) {
            //... your code
       } else {
           SwingUtilities.invokeLater(
                  new Runnable(){
                     public void run() {
                           myMethod();
                     }
                  });
       {
  }                   

これにより、EDT を使用している場合は、メソッドをイベント キューの最後に配置せずに実行し続けることができます。

于 2010-06-23T14:54:18.107 に答える
2

イベントディスパッチスレッドで何かを実行したいときはいつでも、を使用する必要がありますSwingUtilities.invokeLater(Runnable doRun)

Javadoc からの抜粋:

AWT イベント ディスパッチ スレッドで doRun.run() が非同期的に実行されるようにします。これは、保留中のすべての AWT イベントが処理された後に発生します。このメソッドは、アプリケーション スレッドが GUI を更新する必要がある場合に使用する必要があります。

于 2010-06-23T14:39:15.870 に答える
1

EDT で実行する必要があるすべてのメソッドで、メソッド本体を次のコードでラップする必要があります。

SwingUtilities.invokeLater(new Runnable(){public void run(){


    // All code placed in here will be ran asynchronously on the EDT


}});

これにより、メソッド内のすべてが EDT で実行されます。EDT でコードを実行しているため、長時間ブロックするようなことはしないでください。(ファイル IO、長い計算など) そうしないと、GUI がフリーズして応答しなくなります。

invokeLater()javadoc

于 2010-06-23T14:42:27.977 に答える
0

SwingWorkerを使用して、done()メソッドでGUIコンポーネントを更新します。donInBackground()メソッドでバックグラウンド作業を行います。

于 2010-06-23T15:09:51.807 に答える
0

これを達成した 1 つの方法は、AspectJ を使用することです。ボイラープレート コードは、コンパイル中に @OnEDT で注釈が付けられたすべてのメソッドに挿入されます。結果のコードはスリムで非常に便利です。

当然のことながら、そのための注釈、ポイントカット、およびアスペクトを作成する必要がありましたが、それはほとんど簡単なことではありませんでした。

興味がある場合は、関連するリンクをいくつか次に示します。

http://www.eclipse.org/aspectj/

http://www.eclipse.org/ajdt/EclipseCon2006/

http://www.cs.wustl.edu/~mdeters/doc/slides/aspectjtutorial.pdf

于 2010-06-23T20:13:22.577 に答える
0

ご回答ありがとうございます。最後に、コンポーネントのラッパー クラスを作成しました。このラッパーはすべての呼び出しを受け取り、ランナブルを作成し (run() 内で実際のメソッドを呼び出します)、このランナブルを invokeLater() に送信します。
これはすべて、リフレクション ライブラリを使用するとそれほど複雑ではないように思われます。出発点は、インターフェースのインスタンスを動的に作成する java.lang.reflect.Proxy クラスです。

于 2010-06-27T03:49:59.347 に答える