SwingWorker必须是嵌套类吗?

Pet*_*ter 5 java user-interface nested-class swingworker

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

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

任何建议将不胜感激!


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

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

我试过这样的:

public void setSize(long totalSize) {
     this.totalSize = totalSize;
}
public long getTotalSize() {
     return totalSize;
}
Run Code Online (Sandbox Code Playgroud)

doInBackground()方法结束时调用setter .不幸的是我无法使用get()GUI中的方法.

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

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

Jef*_*rey 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(); }
 }
Run Code Online (Sandbox Code Playgroud)

现在从GUI,你可能会做类似的事情

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

如果你想使用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();
Run Code Online (Sandbox Code Playgroud)

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