6

SwingWorkerメインGUI内でネストされたクラスである必要があるかどうか疑問に思っています。GUIをプログラムロジックから明確に保つために、外部クラスにしたいです。

クラスを外部にしようとしましたがSwingWorker、これはプロセスで正常に機能しますが、残念ながら、SwingWorkerクラスからGUIフィールドにアクセスできません。SwingWorkerのメソッド内からラベルなどの属性にアクセスしようとするとdone()、nullPointer例外が発生します。

アドバイスをいただければ幸いです。


まずはジェフ、どうもありがとうございました!あなたが提示した2番目のオプションについてはフォローできませんでしたが、これまでのところ正常に機能しています。私のバックグラウンドタスクの1つは、特定のサイズ(長い値)を計算するので、GUIからその値を取得すると便利です。

ゲッターとセッターを使用することを提案しましたが、残念ながら、SwingWorkerクラスでそれらを実装する方法がわかりません。

私はこのようにそれを試しました:

public void setSize(long totalSize) {
     this.totalSize = totalSize;
}
public long getTotalSize() {
     return totalSize;
}

セッターはdoInBackground()メソッドの最後に呼び出されます。残念ながらget()、GUIからこのメソッドを使用することはできません。

final MySwingWorker w = new MySwingWorker();
Runnable r = new Runnable() {
    public void run() {
        // do something with w.get()
    }
};
w.setRunnable(r);
w.execute();

コンストラクターがRunnableのオブジェクトを必要とするため、私の場合、「w」のオブジェクト作成は機能しません。私は何かが足りないのですか?SwingWorkerを使用するのは初めてです。:)繰り返しになりますが、ご協力いただきありがとうございます。

4

1 に答える 1

6

SwingWorkerを外部クラスにすることができます。ただし、他のクラスと同様に、変数(設定するラベルなど)が表示されない場合は、もちろん設定できません。実行できることの1つは、完了時に実行されるRunnableをワーカーに渡すことです。

public class MySwingWorker extends SwingWorker {

   private final Runnable r;
   public MySwingWorker(Runnable r) {
       this.r = r;
   }
   public void doInBackground() {...}
   public void done() { r.run(); }
 }

GUIから、次のようなことを行うことができます

Runnable updateLabel = new Runnable() {
       public void run() {
           label.setText("myValue");
       }
};
SwingWorker w = new MySwingWorker(updateLabel);
w.execute();

SwingWorkerの結果を使用したい場合、これは少し注意が必要ですが、可能です。Runnableをswingworkerのコンストラクターに渡すのではなく、setterメソッドを使用すると、次のようになります。

final MySwingWorker w = new MySwingWorker();
Runnable r = new Runnable() {
    public void run() {
        // do something with w.get()
    }
};
w.setRunnable(r);
w.execute();

いずれの場合も、Runnableは、ワーカーが終了したときに実行されるクロージャーと同様に機能します。

于 2010-02-18T12:49:23.280 に答える