在 SwingWorker 上使用 done 方法还是更改侦听器更好?

Is it better to use done method or a change listener on SwingWorker?

我有一个任务,完成后它会更新一个 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();
    }
}

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

Is it better to use done method or a change listener on SwingWorker?

一般来说这两种方式都是正确且等价的。

然而,使用 PropertyChangeListener 的主要优点是您可以将多个侦听器附加到 SwingWorker,这允许您将任务拆分为小代码单元,而不是只有一个 done() 代码块。这很有用,例如,如果您必须更新多个 Swing 组件并且您希望保持这些更新紧密分离。

此外,使用侦听器减少了 SwingWorker 和 GUI 组件之间的耦合:它不知道后台线程完成时会发生什么,但没关系。通过重写 done() 方法,这将不再适用。

一件重要的事情 - 当监听 StateValue.DONE 或覆盖 done() 方法时 - 是调用 get() 方法以捕获和处理可能抛出的任何异常在 doInBackground() 处理期间。请参阅与此相关的 this Q&A

其余没有太大区别。我会选择听众只是为了可扩展性。

更新

根据下面@mKorbel 的评论,您可能也想看看这个主题:Is a swingWorker guaranteed to throw a state property change event on completion? 甚至 recosinder 使用 SwingWorker。我个人没有遇到任何问题,但很高兴了解与此事的多线程性质相关的可能错误。