SwingWorker 必须是嵌套类吗?

发布于 2024-08-21 14:56:27 字数 998 浏览 8 评论 0原文

我想知道 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。 :) 再次非常感谢您的帮助!

I'm wondering if SwingWorker has to be a nested class within my main GUI. I'd rather make it an external class to keep the GUI clear from any of my programs logic.

I tried to make the SwingWorker class external, which works fine for the process, unfortunately I can't access any of my GUI fields from the SwingWorker class.
Whenever I try to access an attribute, such like a label or whatever from within SwingWorker's done() method I get a nullPointer exception.

Any advice would be much appreciated!


First of all thank you very much Jeff! Works fine so far, even though I could not follow you on the second option you presented.
One of my background tasks calculates a certain size (long value), so it would be nice to get that value from my GUI.

You suggested to work with getters and setters but unfortunately I've got no idea on how to implement them in the SwingWorker class.

I tried it like this:

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

The setter is invoked at the end of the doInBackground() method. Unfortunately I can't use the get() method from my GUI.

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

The object creation of "w" does not work in my case as the constructor requires an object of Runnable.
Am I missing something?
Please go easy on me, it's the first time I work with SwingWorker. :)
Again, thank you very much for your help!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

乜一 2024-08-28 14:56:27

您可以将 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 的结果,这会变得有点棘手,尽管这是可能的。您将拥有一个 setter 方法,而不是将 Runnable 传递给 swing Worker 的构造函数,然后它会类似于:

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

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

You can make the SwingWorker an external class. However, just like any other class, if it can't see the variables (e.g. the label you want to set), of course it won't be able to set it. One thing you could do is pass the worker a Runnable that it executes when it is complete.

public class MySwingWorker extends SwingWorker {

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

Now from the GUI, you might do something like

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

This gets a bit trickier if you want to use the result of the SwingWorker, though it is possible. Rather than passing the Runnable to the swing worker's constructor, you would have a setter method and then it would be something like:

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

In either case, the Runnable is functioning similarly to a closure that is executed when the worker is finished.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文