2010-02-18 72 views
5

我想知道SwingWorker必须是我的主GUI中的嵌套类。我宁愿让它成为一个外部类,让我的任何程序逻辑都清楚GUI。SwingWorker必须是嵌套类吗?

我试图让SwingWorker类是外部的,对于这个过程来说工作正常,但不幸的是我无法从SwingWorker类访问任何我的GUI字段。 每当我尝试访问一个属性,比如标签或SwingWorker的done()方法中的任何内容,我都会得到一个nullPointer异常。

任何意见将不胜感激!


首先非常感谢你杰夫!到目前为止工作得很好,尽管我不能跟随你提出的第二种选择。 我的后台任务之一会计算一定的大小(长整型值),所以从我的GUI中获取该值是很好的选择。

你建议与getter和setters一起工作,但不幸的是我不知道如何在SwingWorker类中实现它们。

我尝试了这样的:

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

设定器是在doInBackground()方法的结束时被调用。不幸的是,我无法使用我的GUI中的get()方法。

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合作。 :) 再次,非常感谢您的帮助!

回答

6

您可以使SwingWorker成为外部类。但是,就像任何其他类一样,如果它看不到变量(例如您想设置的标签),当然它将无法设置它。你可以做的一件事是传递一个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到摆动工人的构造函数,你将有一个setter方法,然后它会是这样的:

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

在这两种情况下,可运行在类似的功能,以执行一个闭合当工人完成。

+0

也可以简单地在构造函数中传递Label而不是在Runnable中传递。为每个小动作定义一个新的工作者子类可能会过度杀伤。匿名类非常适合解决这个将一个非常小的,紧密耦合的对象放在一起的特殊问题。 – 2010-02-18 15:15:57

+0

这真的取决于这是否是单个用例。如果你在很多地方做这个抽象的话,这个抽象就行得通。哦,关闭会有帮助。 – 2010-02-18 15:52:31