Java 在SwingWorker上使用done方法或更改侦听器更好吗?

Java 在SwingWorker上使用done方法或更改侦听器更好吗?,java,swing,user-interface,swingworker,Java,Swing,User Interface,Swingworker,我有一个任务,当它完成时,会更新一个swing GUI,告诉它已经完成了。我看到的是,您可以使用done()方法或附加PropertyChangeListener并侦听对done状态的更改 使用什么更好?为什么?或者它们是一样的 例如,这: public class Foo implements PropertyChangeListener { public void propertyChange(PropertyChangeEvent evt) { if ("sta

我有一个任务,当它完成时,会更新一个swing GUI,告诉它已经完成了。我看到的是,您可以使用
done()
方法或附加
PropertyChangeListener
并侦听对
done
状态的更改

使用什么更好?为什么?或者它们是一样的

例如,这:

public class Foo implements PropertyChangeListener {

    public void propertyChange(PropertyChangeEvent evt) {

        if ("state".equals(evt.getPropertyName())
                && (SwingWorker.StateValue.DONE.equals(evt.getNewValue()))) {

            this.updateTheGuiAndOtherThings();

        }

    }
}
或者这个:

public class W extends SwingWorker {

    protected Boolean doInBackground() throws Exception {...}

    protected void done() {
        otherClass.updateTheGuiAndOtherThings();
    }
}

在我的情况下,没有必要提高效率,我要求正确的代码编写

在SwingWorker上使用done方法或更改侦听器更好吗

一般来说,这两种方法都是正确的和等价的

但是,使用
PropertyChangeListener
的主要优点是,您可以将多个侦听器连接到SwingWorker,这样您就可以将任务拆分为小的代码单元,而不是一个
done()
代码块。例如,如果您必须更新多个Swing组件,并且希望将这些更新保持一致分离,那么这非常有用

此外,使用监听器还减少了SwingWorker和GUI组件之间的耦合:它不知道后台线程完成后会发生什么,一切正常。通过重写
done()

在侦听
StateValue.DONE
或重写
DONE()
方法时,要做的一件重要事情是调用
get()
方法,以便捕获和处理
doInBackground()
处理过程中可能引发的任何异常。见与此相关的内容

对于其他人来说,没有什么大的区别。为了可伸缩性,我会选择侦听器

更新
根据@mKorbel在下面的评论,你可能也想看看这个主题:甚至在使用SwingWorker时也要注意。我个人没有遇到任何问题,但很高兴知道与此问题的多线程性质相关的可能错误。

是的,1+。我还喜欢使用侦听器如何减少耦合,因为SwingWorker现在必须完全不知道调用代码,而使用
done()
方法则正好相反。你是对的,我已经忘记了解耦和责任分离。我将在我的回答中补充这一点。谢谢@HoverCraftfullOfelsDone()有漏洞,然后是StateValue.done,关于SwingWorker从未以done()结束,然后事件也是StateValue.done不…,来自Java6的旧漏洞从未测试过,因为Oracle去年在Swing中丢弃了漏洞历史的重要部分,只有在谷歌上才能进行搜索,而且幸运的是,如果要监听
SwingWorker.StateValue.done
,请务必在SwingWorker上调用
get()
,无论是在
done()
中还是在您的PropertyChangeListener中。这将有助于捕获在worker运行时可能抛出的异常。对于您的问题,这是一个不太清楚的正确答案(问题是Java中有两个最差的API组合,Futore和SeingWorker,两者都是不可管理的,没有跟踪,等等,其他flamewars),我建议不要使用PropertyChangeListener中的事件而不是done(),以避免使用发布/进程或(使用第二个绑定属性)SetProgress的错误在我的情况下不需要更高的效率,我要求更多正确的代码编写。==将Runnable#Thread与invokeLater一起使用(仅用于Swing API中实现的方法),而不是阴影化的、不可管理的SwingWorker@mKorbel:我听说过这些bug,但我还没有遇到它们,并且与我的SwingWorkers广泛使用了propertchangelistener。我确保要做的一件事是在侦听器中对我的SwingWorker调用
get()
,如果侦听的是
SwingWorker.StateValue.DONE
,这样我就可以捕获所有抛出的异常。@Hovercraft上满是鳗鱼,但你来自另一个…:-),Pete,恕我直言,但我仍然认为,带有invokeLater的Runnable#Thread是为生产代码指定的,尽管我测试八个LotusDominos节点的代码中有一个异常运行了三年,没有重新启动环境(从Solaris),get()确实是必需的+++,@气垫船上满是鳗鱼,真是虫子的一部分,是关于get()的,第二。关于在doInBackground中生成重要Java异常的动态代码(我认为JVM在curernt线程中被停止,因为JVM的抛出/抛出以get()结束)和第三个。关于重载(可能的)线程数,来自java.util.concurrent.Executor/Executors的一个新的并发运行的SwingWorker instaces