如何解决有什么区别吗? SwingWorker#publish vs SwingUtilities#invokeLater
比方说,我们有一个繁重的任务必须在后台运行,并将其进度或任何内容发布到GUI。我知道此发布必须在事件分发线程上进行。这就是为什么我们将SwingWorker
用于任务。
所以,我们要做的就是这样:
public class WorkerTest {
public static void main(String[] args) {
SwingUtilities.invokelater(() -> {
JFrame frame = new JFrame("test");
frame.setDefaultCloSEOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new FlowLayout());
JLabel label = new JLabel();
frame.add(label);
startWorker(label);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
});
}
private static void startWorker(JLabel label) {
new SwingWorker<Integer,Integer>() {
@Override
protected Integer doInBackground() throws Exception {
for (int i = 0; i < 500; i++) {
publish(i);
Thread.sleep(500); //Simulate long task
}
return null;
}
@Override
protected void process(List<Integer> chunks) {
Integer integer = chunks.get(0);
label.setText(String.valueOf(integer));
}
}.execute();
}
}
我的问题是,以上内容与此不同:
private static void startWorker(JLabel label) {
new SwingWorker<Integer,Integer>() {
@Override
protected Integer doInBackground() throws Exception {
for (int i = 0; i < 500; i++) {
int i2 = i;
SwingUtilities.invokelater(() -> {
label.setText(String.valueOf(i2));
});
Thread.sleep(500); //Simulate long task
}
return null;
}
}.execute();
}
在两种情况下,作为GUI的更新的label.setText()
都运行到事件分发线程。它们有什么不同?
当然,问题还在于为什么我应该为工作人员实现done()
方法,而不是在SwingUtilities.invokelater
方法末尾调用doInBackground
?除了处理可能在doInBackground
方法中引发的异常。
解决方法
在类publish()
中查看方法SwingWorker
的 javadoc 。
因为处理方法是在事件调度线程上异步调用的,所以在执行处理方法之前可能会多次调用publish方法。为了提高性能,所有这些调用都被合并为一个带有串联参数的调用。
根据问题代码,直接从方法SwingUtilities.invokeLater()
调用doInBackground()
不会执行合并。也许您可以想到需要合并的原因?另请参阅Tasks that Have Interim Results
关于类done()
中的方法SwingWorker
,您也曾问过,再次请您参考 javadoc
在doInBackground方法完成之后,在事件调度线程上执行。默认实现不执行任何操作。子类可以重写此方法,以对事件调度线程执行完成操作。请注意,您可以在此方法的实现内部查询状态,以确定此任务的结果或此任务是否已取消。
因此,您不必重写方法done()
。就个人而言,我通常向我的SwingWorker
对象添加一个属性侦听器,以处理[SwingWorker
]任务完成后需要执行的任务。当然,YMMV。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。