Java – разница между SwingWorker и SwingUtilities.invokeLater()

SwingWorker используется для следующих целей:

  • Для запуска длительных задач в другом потоке, чтобы предотвратить зависание графического интерфейса.
  • Для обновления графического интерфейса с результатами, полученными в результате длительной задачи в конце задачи с помощью метода done().
  • Для периодического обновления GUI промежуточными результатами, полученными и опубликованными задачей с помощью методов publish() и process().

SwingUtilities.invokeLater() может выполнять перечисленные выше задачи следующим образом:

  • Вместо выполнения метода SwingWorker.execute() из EDT мы можем выполнить ExecutorService.submit(new MyRunnable()), поскольку он также создаст еще один поток, который может выполнять длительную задачу.
  • Для обновления графического интерфейса в конце задачи мы можем поместить код (написанный в done() методе case1) SwingUtilites.invokeLater(new RunnableToExecuteDoneMethodCode()) в конце задачи.
  • Для обновления графического интерфейса в середине задачи мы можем поместить код (написанный в process() методе case1) SwingUtilites.invokeLater(new RunnableToExecuteProcessMethodCode()) в то место, где мы вызвали publish() метод в case1.

Я задаю этот вопрос, потому что проблема, указанная в вопросе Java - SwingWorker - Можем ли мы вызвать один SwingWorker из другого SwingWorker вместо EDT можно решить с помощью SwingUtilities.invokeLater(), но нельзя решить с помощью SwingWorker


person Yatendra    schedule 13.05.2010    source источник
comment
Я не совсем уверен, что такое «вопрос».   -  person akf    schedule 13.05.2010
comment
@akf, если вы не уверены, оставьте это. Простой :)   -  person Yatendra    schedule 13.05.2010
comment
Проблема, о которой вы говорите, решается с помощью SwingWorker. Смотрите мой ответ там.   -  person Noel Ang    schedule 13.05.2010


Ответы (2)


SwingWorker — это вспомогательный класс — не то чтобы вам нужно его использовать, но использовать его гораздо проще и понятнее, чем выполнять ту же работу вручную. (Это также упрощает проверку прогресса.) Обратите внимание, что была добавлена ​​версия 6 - до этого некоторые люди использовали более простой класс, определенный в Swing Tutorial, или делали шаги, подобные тем, которые вы отметили.

person Kathy Van Stone    schedule 13.05.2010
comment
+1 Удобно, что для Java 5 существует совместимый с исходным кодом обратный порт. swingworker.dev.java.net - person trashgod; 14.05.2010

Важной особенностью класса SwingWorker версии 1.6+ является разница EDT (поток отправки событий) между doInBackground() и done(). Вы должны думать о 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.
person Java42    schedule 16.05.2014