Java - SwingWorker和SwingUtilities.invokeLater()的区别

10

SwingWorker用于以下目的:

  • 在不同的线程中运行长时间运行的任务,以防止GUI无响应
  • 通过done()方法,在任务结束时使用由长时间运行的任务生成的结果更新GUI。
  • 使用publish()process()方法发布和处理任务生产的中间结果,从而定期更新GUI。

SwingUtilities.invokeLater()可执行以下任务:

  • 不需要从EDT执行SwingWorker.execute()方法,可以执行ExecutorService.submit(new MyRunnable()),因为它还将创建另一个线程,该线程可以执行长时间运行的任务。
  • 要在任务结束时更新GUI,我们可以将代码(编写在Case1的done()方法中)放置在任务的末尾:SwingUtilites.invokeLater(new RunnableToExecuteDoneMethodCode())
  • 要在任务执行过程中更新GUI,我们可以将代码(编写在Case1的process()方法中)放置在我们在Case1中调用publish()方法的位置:SwingUtilites.invokeLater(new RunnableToExecuteProcessMethodCode())

我提出这个问题是因为在问题Java-SwingWorker-我们可以从其他SwingWorker而不是EDT调用一个SwingWorker吗中指定的问题可以通过SwingUtilities.invokeLater()来解决,但无法使用SwingWorker解决。


1
我不太确定“问题”是什么。 - akf
@akf 如果你不确定,那就不要操作。简单明了 :) - Amit
你所提到的问题可以通过使用SwingWorker来解决。请参考我的回答。 - Noel Ang
2个回答

7

SwingWorker 是一个帮助类,你并不一定需要使用它,但是使用它比手动实现同样的功能更加简单明了。同时,使用它也能更方便地检查进度。需要注意的是,该类是在 Java 6 版本中添加的,在此之前,有些人使用 Swing 教程中定义的较为简单的类,或者采用类似于你提到的方法来进行实现。


方便的是,Java 5有一个与源代码兼容的后备版本。https://swingworker.dev.java.net/ - trashgod

1

SwingWorker类1.6+的一个重要特性是doInBackground()和done()之间的EDT(事件分派线程)差异。你应该把doInBackground()看作是doWorkOutsideEDT(),而将done()看作是doWorkInsideEDT()。运行这个指导示例来看到不同之处。

    System.out.println("TID=" + Thread.currentThread().getId() + " (main)");
    final SwingWorker<String, String> x = new SwingWorker<String, String>() {
        @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.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接