假设我们有一个必须在后台运行的长/繁重的任务,并将其进度或其他任何内容发布到 GUI。我知道这个发布必须发生在事件调度线程上。这就是我们将 aSwingWorker
用于任务的原因。
所以,我们所做的是这样的:
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();
}
在这两种情况下,作为label.setText()
对 GUI 的更新,都会运行到事件调度线程。它们有何不同?
当然,问题还在于为什么我应该在方法结束时done()
对工作人员实施方法而不是调用?除了处理方法中可能抛出的异常。SwingUtilities.invokeLater
doInBackground
doInBackground