В чем смысл SwingWorker? - PullRequest
       16

В чем смысл SwingWorker?

6 голосов
/ 11 ноября 2008

Для того, что я могу прочитать, он используется для отправки нового потока в свинг-приложении для выполнения некоторой "фоновой" работы, но какая выгода от использования этого, а не "нормального" потока?

Разве это не то же самое, если использовать новый поток, а когда он закончится, вызвать какой-нибудь метод графического интерфейса, используя SwingUtilities.invokeLater? ...

Что мне здесь не хватает?

http://en.wikipedia.org/wiki/SwingWorker

http://java.sun.com/products/jfc/tsc/articles/threads/threads2.html

Ответы [ 7 ]

10 голосов
/ 11 ноября 2008

Да, вы можете выполнить то, что SwingWorker делает с ванильными потоками + invokeLater. SwingWorker предоставляет предсказуемый, интегрированный способ выполнения задач в фоновом потоке и отчета о результатах в EDT. SwingWorker дополнительно добавляет поддержку для промежуточных результатов. Опять же, вы можете сделать все это самостоятельно, но иногда легко использовать интегрированное и предсказуемое решение, особенно когда речь идет о параллелизме.

3 голосов
/ 12 ноября 2008

Пример кода:

import org.jdesktop.swingx.util.SwingWorker; // This one is from swingx
                                             // another one is built in 
                                             // since JDK 1.6 AFAIK?

public class SwingWorkerTest {

  public static void main( String[] args ) {

    /**
      * First method
      */
    new Thread() {

      public void run() {

        /** Do work that would freeze GUI here */

        final Object result = new Object();
        java.awt.EventQueue.invokeLater( new Runnable() {

          public void run() {
          /** Update GUI here */
          }
        } );

      }
    }.start();

    /**
      * Second method
      */
    new SwingWorker< Object , Object >() {

      protected Object doInBackground() throws Exception {
        /** Do work that would freeze GUI here */

        return null;
      }

      protected void done() {
        try {
          Object result = get();
          /** Update GUI here */
        }
        catch ( Exception ex ) {
          ex.printStackTrace();
          if ( ex instanceof java.lang.InterruptedException )
            return;
        }
      }
    }.execute();
  }

}

Выбор всегда зависит от личных предпочтений и варианта использования.

Второй метод имеет преимущество при рефакторинге. Вы можете легче преобразовать анонимный класс во внутренний класс, когда метод, в котором он используется, слишком велик.

Мои личные предпочтения касаются второго, поскольку мы создали фреймворк, в который можно добавлять SwingWorkers и запускать их один за другим ...

2 голосов
/ 11 ноября 2008

SwingWorker является реализацией общего шаблона (в .Net я читал, что есть GuiWorker BackgroundWorker для этого), где вам нужно выполнить некоторую работу в программе с графическим интерфейсом, но поддерживать графический интерфейс реагировать. Проблема заключается в том, что часто библиотеки GUI не являются многопоточными, поэтому обычным способом реализации таких работников является использование цикла сообщений библиотеки для передачи сообщений в цикл событий приложения.

Эти классы позволяют легко обновлять графический интерфейс. Обычно они имеют метод update(int status), который вызывается потоком, отправляется классом и обрабатывается графическим интерфейсом, пока поток продолжает свою работу.

Используя обычные потоки, для этой задачи вам потребуется кодировать свои собственные события или какой-либо другой механизм обмена сообщениями, что может быть затруднительно, если вам часто нужны эти функции. Используя invokeLater в Java, например, вы бы смешали код для обновления графического интерфейса в код для выполнения работы. SwingWorker позволяет вам хранить вещи отдельно.

1 голос
/ 03 июня 2009

При работе с Swing важно знать, что основная обработка свинга (т. Е. Рендеринг) происходит в одном потоке (который не является вашим основным потоком). Это часто называют потоком событий Swing или AWT. Те, кто знаком с JDK pre 1.6, запомнят ошибку «серый прямоугольник», если вы потратили слишком много времени в диспетчере событий для компонента Swing. Что это значит. В любом свинг-приложении у вас будет запущено 2 потока, с которыми вам теперь придется иметь дело. Обычно, если все ваши операции в диспетчере событий (код, который запускается, скажем, при нажатии кнопки) короткие (т. Е. Изменение состояния кнопки), вы можете просто запустить это внутри диспетчера событий. Если ваше приложение будет вызывать веб-службу или базу данных, или состояние вашего приложения определяется внешними событиями (например, jms), или вы просто хотите сделать свой пользовательский интерфейс более интерактивным (например, создать список элементов и иметь возможность сделайте что-нибудь еще) вы должны использовать поток, отличный от потока событий awt (основной свинг). Таким образом, в этих случаях вы создаете новый поток и делаете то, что вам нужно, и когда результаты наконец возвращаются, вам нужно каким-то образом создать событие, которое может выполнить диспетчер awt / swing. SwingWorker - это отличный маленький шаблон проектирования, который позволяет вам сделать это (другой способ - SwingUtilities). Это особенно полезно для извлечения данных из внешних источников или, например, для длинных вычислений (рендеринг графической сцены). Это помогает автоматизировать отправку и последующую реинтеграцию результатов из внешнего потока (кроме потока AWT). Для асинхронных событий (т. Е. Событие из JMS должно обновить результат, используйте SwingUtilities).

1 голос
/ 11 ноября 2008

чтобы ответить на ваш вопрос, вы ничего не пропустили. этот класс - просто удобная утилита для обобщения функциональности, которую вы описали (запустите другой поток, чтобы выполнить фоновую работу, а затем вызовите какое-то последнее действие в EDT с результатами).

0 голосов
/ 16 ноября 2008

SwingWorker гораздо проще, чем копаться в ваших собственных потоках, потому что он дает вам две вещи, которые трудно обрабатывать вручную, координацию потоков между пользовательским интерфейсом и фоновым процессом и эффективную циклическую работу, фоновую работу, которая продолжает работать и отправляет обновления обратно Пользовательский интерфейс постепенно, например, обрабатывает большой объем данных или загружает большой список. Недостаток (или преимущество) зависит от того, как вы на это смотрите, заключается в том, что он скрывает базовую реализацию, поэтому будущая версия может иметь другое поведение, производительность и т. Д., Что может быть нежелательным. Я нашел это весьма полезным, поскольку связующее звено между событием пользовательского интерфейса и моим собственным кодом команды, SwingWorker поддерживает связь с пользовательским интерфейсом и мой код перекачивает данные.

0 голосов
/ 12 ноября 2008

SwingWorker делает простой пример кода более лаконичным. Однако это создает шар грязи. Связь с графическим интерфейсом и от него, а также выполненная логика объединены. Поэтому я бы не хотел, чтобы он использовался в реальном производственном коде.

...