2010-05-13 5 views
9

SwingWorker используется для следующих целей:Java - Разница между SwingWorker и SwingUtilities.invokeLater()

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

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

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

Я задаю этот вопрос, потому что проблема, указанная в вопросе Java - SwingWorker - Can we call one SwingWorker from other SwingWorker instead of EDT может быть решена с помощью SwingUtilities.invokeLater(), но не может быть решена с SwingWorker

+1

Я не совсем уверен, что 'вопрос' есть. – akf

+0

@akf, если вы не уверены, а затем оставьте его. Simple :) –

+0

Проблема, о которой вы говорите, разрешима с помощью SwingWorker. Смотрите мой ответ. –

ответ

6

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

+0

+1 Удобно, есть совместимый с исходным кодом back-port для Java 5. https://swingworker.dev.java.net/ – trashgod

1

Важной особенностью класса 1.6+ SwingWorker является разность EDT (Event Dispatch Thread) между 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.