SwingWorker必须是嵌套类吗?

时间:2010-02-18 12:41:00

标签: java user-interface nested-class swingworker

我想知道SwingWorker是否必须是我主GUI中的嵌套类。我宁愿把它作为一个外部类来保持GUI与我的任何程序逻辑清晰。

我尝试将SwingWorker类设为外部,这对于该过程很有效,遗憾的是我无法访问SwingWorker类中的任何GUI字段。 每当我尝试从SwingWorker的done()方法中访问属性(如标签或其他内容)时,我都会收到nullPointer异常。

非常感谢任何建议!


首先非常感谢杰夫!到目前为止工作正常,即使我无法关注你提出的第二个选项。 我的一个后台任务计算一定的大小(长值),所以从我的GUI中获取该值会很好。

您建议使用getter和setter但不幸的是我不知道如何在SwingWorker类中实现它们。

我试过这样:

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

doInBackground()方法的末尾调用setter。不幸的是,我无法使用GUI中的get()方法。

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

“w”的对象创建在我的情况下不起作用,因为构造函数需要Runnable的对象。 我错过了什么吗? 请放轻松,这是我第一次使用SwingWorker。 :) 再次,非常感谢你的帮助!

1 个答案:

答案 0 :(得分:6)

您可以将SwingWorker设为外部类。但是,就像任何其他类一样,如果它看不到变量(例如您要设置的标签),当然它将无法设置它。你可以做的一件事就是将worker传递给它在完成时执行的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传递给swing工作者的构造函数,而是使用setter方法,然后它会是这样的:

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

在任何一种情况下,Runnable的功能都与工作完成时执行的闭包类似。