Java – SwingWorker和SwingUtilities.invokeLater()之间的区别
SwingWorker
用于以下目的:
- 用于在不同的线程中运行长时间运行的任务,以防止GUI无响应
- 用于通过
done()
方法在任务结束时使用长时间运行的任务生成的结果更新GUI。 - 用于在不依赖于
publish()
和process()
方法的情况下由任务生成和发布的中间结果来不时更新GUI。
SwingUtilities.invokeLater()
可以执行上述任务,如下所示:
- 我们可以执行
ExecutorService.submit(new MyRunnable())
,而不是从EDT执行SwingWorker.execute()
方法,因为它还会创建另一个可以执行长时间运行任务的线程。 - 为了在任务结束时更新GUI,我们可以在任务结束时放置代码(用case1的
done()
方法编写)SwingUtilites.invokeLater(new RunnableToExecuteDoneMethodCode())
。 - 为了在任务中间更新GUI,我们可以将代码(在case1的
process()
方法中编写)SwingUtilites.invokeLater(new RunnableToExecuteProcessMethodCode())
放在我们在case1中调用publish()
方法的地方。
我问这个问题是因为Java-SwingWorker中指定的问题- 我们可以从其他SwingWorker调用一个SwingWorker而不是EDT可以通过SwingUtilities.invokeLater()
解决但是无法用SwingWorker
解决
SwingWorker
是一个帮助类 – 它不是你需要使用它,但使用它比手工完成相同的工作要简单得多,也更清晰。 (它还使检查进度更容易。)请注意,它已添加版本6 – 之前有些人使用了Swing Tutorial中定义的更简单的类,或者执行了类似于您注意到的步骤。
1.6+ SwingWorker类的一个重要特性是doInBackground()和done()之间的EDT(Event Dispatch Thread)区别。 您应该将doInBackground()视为doWorkOutsideEDT()和done()作为doWorkInsideEDT()。 运行此教学示例以查看不同的示例。
System.out.println("TID=" + Thread.currentThread().getId() + " (main)"); final SwingWorker x = new SwingWorker() { @Override protected String doInBackground() throws Exception { final long tid = Thread.currentThread().getId(); System.out.println(""); System.out.println("TID=" + tid + " doInBackground() isEventDispatchThread=" + SwingUtilities.isEventDispatchThread()); System.out.println("Long running code goes here."); return ""; } @Override protected void done() { final long tid = Thread.currentThread().getId(); System.out.println(""); System.out.println("TID=" + tid + " done() isEventDispatchThread=" + SwingUtilities.isEventDispatchThread()); System.out.println("GUI updates/changes go here."); } }; x.execute(); x.get();
输出:
TID=1 (main) TID=9 doInBackground() isEventDispatchThread=false Long running code goes here. TID=16 done() isEventDispatchThread=true GUI updates/changes go here.