Spec-Zone.ru › OpenJDK 17

Класс SwingWorker<T,V>

java.lang.Object
javax.swing.SwingWorker<T,V>
Type Parameters:
T - тип результата, возвращаемый этим SwingWorker's doInBackground и get методами
V - тип, используемый для переноса промежуточных результатов этим SwingWorker's publish и process методами
Все реализованные интерфейсы:
Runnable, Future<T>, RunnableFuture<T>
public abstract class SwingWorker<T,V> extends Object implements RunnableFuture<T>
Абстрактный класс для выполнения длительных задач взаимодействия с GUI в фоновом потоке. Для выполнения таких задач могут использоваться несколько фоновых потоков. Однако точная стратегия выбора потока для любой конкретной SwingWorker не определена и на ней нельзя полагаться.

При написании многопоточного приложения, использующего Swing, следует учитывать два ограничения: (см. Конкурентность в Swing для получения дополнительной информации):

  • Задачи, требующие много времени, не должны выполняться в потоке обработки событий. В противном случае приложение перестанет отвечать.
  • Компоненты Swing должны обращаться только к потоку обработки событий.

Эти ограничения означают, что приложение GUI с ресурсоёмкими вычислениями нуждается как минимум в двух потоках: 1) поток для выполнения длительной задачи и 2) поток обработки событий (EDT) для всех операций, связанных с GUI. Это предполагает межпоточное взаимодействие, которое может быть трудно реализовать.

SwingWorker предназначен для ситуаций, когда требуется запуск длительной задачи в фоновом потоке и предоставление обновлений в интерфейсе пользователя, либо по завершении, либо во время обработки. Подклассы SwingWorker должны реализовать метод doInBackground() для выполнения вычислений в фоновом режиме.

Порядок работы

В жизненном цикле SwingWorker участвуют три потока:

  • Текущий поток: В этом потоке вызывается метод execute(). Он планирует SwingWorker для выполнения в рабочем потоке и возвращается немедленно. Дождаться завершения SwingWorker можно с помощью методов get.

  • Рабочий поток: В этом потоке вызывается метод doInBackground(). Здесь должны происходить все фоновые действия. Для уведомления PropertyChangeListeners о изменениях свойств используйте методы firePropertyChange и getPropertyChangeSupport(). По умолчанию доступны два связанных свойства: state и progress.

  • Поток обработки событий: Все операции, связанные со Swing, происходят в этом потоке. SwingWorker вызывает методы process и done() и уведомляет любых PropertyChangeListeners в этом потоке.

Часто Текущий поток — это Поток обработки событий.

Перед вызовом метода doInBackground в рабочем потоке, SwingWorker уведомляет любых PropertyChangeListeners об изменении свойства state на StateValue.STARTED. После завершения метода doInBackground выполняется метод done. Затем SwingWorker уведомляет любых PropertyChangeListeners об изменении свойства state на StateValue.DONE.

SwingWorker предназначен для выполнения только один раз. Выполнение SwingWorker более одного раза не приведёт к двукратному вызову метода doInBackground.

Пример использования

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

Предположим, что мы хотим найти «Смысл Жизни» и отобразить результат в JLabel.

   final JLabel label;
   class MeaningOfLifeFinder extends SwingWorker<String, Object> {
       @Override
       public String doInBackground() {
           return findTheMeaningOfLife();
       }

       @Override
       protected void done() {
           try {
               label.setText(get());
           } catch (Exception ignore) {
           }
       }
   }

   (new MeaningOfLifeFinder()).execute();
 

Следующий пример полезен в ситуациях, когда вы хотите обрабатывать данные по мере их готовности в потоке обработки событий.

Теперь мы хотим найти первые N простых чисел и отобразить результаты в JTextArea. Пока это происходит, мы хотим обновлять наш прогресс в JProgressBar. Наконец, мы также хотим вывести простые числа в System.out.

 class PrimeNumbersTask extends
         SwingWorker<List<Integer>, Integer> {
     PrimeNumbersTask(JTextArea textArea, int numbersToFind) {
         //initialize
     }

     @Override
     public List<Integer> doInBackground() {
         while (! enough && ! isCancelled()) {
                 number = nextPrimeNumber();
                 publish(number);
                 setProgress(100 * numbers.size() / numbersToFind);
             }
         }
         return numbers;
     }

     @Override
     protected void process(List<Integer> chunks) {
         for (int number : chunks) {
             textArea.append(number + "\n");
         }
     }
 }

 JTextArea textArea = new JTextArea();
 final JProgressBar progressBar = new JProgressBar(0, 100);
 PrimeNumbersTask task = new PrimeNumbersTask(textArea, N);
 task.addPropertyChangeListener(
     new PropertyChangeListener() {
         public  void propertyChange(PropertyChangeEvent evt) {
             if ("progress".equals(evt.getPropertyName())) {
                 progressBar.setValue((Integer)evt.getNewValue());
             }
         }
     });

 task.execute();
 System.out.println(task.get()); //prints all prime numbers we have got
 

Поскольку SwingWorker реализует Runnable, SwingWorker можно отправить на выполнение в Executor.

Since:
1.6

Краткое описание вложенных классов

Модификатор и тип Класс Описание
static enum  SwingWorker.StateValue
Значения для связанного свойства state.

Краткое описание конструкторов

Конструктор Описание
SwingWorker()
Создаёт этот SwingWorker.

Краткое описание методов

Модификатор и тип Метод Описание
final void addPropertyChangeListener(PropertyChangeListener listener)
Добавляет PropertyChangeListener в список слушателей.
final boolean cancel(boolean mayInterruptIfRunning)
Попытка отменить выполнение этой задачи.
protected abstract T doInBackground()
Вычисляет результат или выбрасывает исключение, если это невозможно.
protected void done()
Выполняется в потоке обработки событий после завершения метода doInBackground.
final void execute()
Планирует выполнение этого SwingWorker в рабочем потоке.
final void firePropertyChange(String propertyName, Object oldValue, Object newValue)
Сообщает о событии изменения связанного свойства зарегистрированным слушателям.
final T get()
Ждёт, если необходимо, завершения вычислений, а затем извлекает свой результат.
final T get(long timeout, TimeUnit unit)
Ждёт, если необходимо, не более заданного времени, завершения вычислений, а затем извлекает результат, если он доступен.
final int getProgress()
Возвращает связанное свойство progress.
final PropertyChangeSupport getPropertyChangeSupport()
Возвращает PropertyChangeSupport для этого SwingWorker.
final SwingWorker.StateValue getState()
Возвращает связанное свойство состояния SwingWorker.
final boolean isCancelled()
Возвращает true если эта задача была отменена до её нормального завершения.
final boolean isDone()
Возвращает true если эта задача завершилась.
protected void process(List<V> chunks)
Получает фрагменты данных из метода publish асинхронно в потоке обработки событий.
protected final void publish(V... chunks)
Отправляет фрагменты данных в метод process(java.util.List<V>).
final void removePropertyChangeListener(PropertyChangeListener listener)
Удаляет PropertyChangeListener из списка слушателей.
final void run()
Устанавливает для этого Future значение результата вычислений, если она не была отменена.
protected final void setProgress(int progress)
Устанавливает связанное свойство progress.

Методы, объявленные в классе java.lang.Object

clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait

Подробное описание конструкторов

SwingWorker

public SwingWorker()
Создаёт этот SwingWorker.

Подробное описание методов

doInBackground

protected abstract T doInBackground() throws Exception
Вычисляет результат или выбрасывает исключение, если это невозможно.

Обратите внимание, что этот метод выполняется только один раз.

Примечание: этот метод выполняется в фоновом потоке.

Возвращает:
вычисленный результат
Выбрасывает:
Exception - если невозможно вычислить результат

run

public final void run()
Устанавливает этот Future в результат вычисления, если он не был отменён.
Устанавливается по:
run в интерфейсе Runnable
Устанавливается по:
run в интерфейсе RunnableFuture<T>
См. также:
  • Thread.run()

publish

@SafeVarargs protected final void publish(V... chunks)
Отправляет фрагменты данных методу process(java.util.List<V>). Этот метод предназначен для использования внутри метода doInBackground, чтобы передавать промежуточные результаты для обработки в потоке обработки событий внутри метода process.

Поскольку метод process вызывается асинхронно в потоке обработки событий, несколько вызовов метода publish могут произойти до выполнения метода process. В целях производительности все эти вызовы объединяются в один вызов с конкатенированными аргументами.

Например:

 publish("1");
 publish("2", "3");
 publish("4", "5", "6");
 
может привести к:
 process("1", "2", "3", "4", "5", "6")
 

Пример использования. Этот фрагмент кода загружает некоторые табличные данные и обновляет DefaultTableModel этими данными. Обратите внимание, что безопасно изменять tableModel внутри метода process, поскольку он вызывается в потоке обработки событий.

 class TableSwingWorker extends
         SwingWorker<DefaultTableModel, Object[]> {
     private final DefaultTableModel tableModel;

     public TableSwingWorker(DefaultTableModel tableModel) {
         this.tableModel = tableModel;
     }

     @Override
     protected DefaultTableModel doInBackground() throws Exception {
         for (Object[] row = loadData();
                  ! isCancelled() && row != null;
                  row = loadData()) {
             publish((Object[]) row);
         }
         return tableModel;
     }

     @Override
     protected void process(List<Object[]> chunks) {
         for (Object[] row : chunks) {
             tableModel.addRow(row);
         }
     }
 }
 
Параметры:
chunks - промежуточные результаты для обработки
См. также:
  • process(java.util.List<V>)

process

protected void process(List<V> chunks)
Получает фрагменты данных из метода publish асинхронно в потоке обработки событий.

Подробнее см. метод publish(V...).

Параметры:
chunks - промежуточные результаты для обработки
См. также:
  • publish(V...)

done

protected void done()
Выполняется в потоке обработки событий после завершения метода doInBackground. Стандартная реализация ничего не делает. Подклассы могут переопределить этот метод для выполнения действий завершения в потоке обработки событий. Обратите внимание, что вы можете запросить состояние внутри реализации этого метода, чтобы определить результат этой задачи или была ли эта задача отменена.
См. также:
  • doInBackground()
  • isCancelled()
  • get()

setProgress

protected final void setProgress(int progress)
Устанавливает свойство progress. Значение должно быть от 0 до 100.

Поскольку PropertyChangeListener уведомляются асинхронно в потоке обработки событий, несколько вызовов метода setProgress могут произойти до вызова любых PropertyChangeListeners. В целях производительности все эти вызовы объединяются в один вызов с последним аргументом вызова.

Например, следующие вызовы:

 setProgress(1);
 setProgress(2);
 setProgress(3);
 
могут привести к одному PropertyChangeListener уведомлению со значением 3.
Параметры:
progress - значение прогресса для установки
Выбрасывает:
IllegalArgumentException - если значение не от 0 до 100

getProgress

public final int getProgress()
Возвращает свойство progress.
Возвращает:
свойство прогресса.

execute

public final void execute()
Планирует эту SwingWorker для выполнения в рабочем потоке. Доступно несколько рабочих потоков. В случае, если все рабочие потоки заняты обработкой других SwingWorkers, эта SwingWorker помещается в очередь ожидания.

Примечание: SwingWorker предназначена для выполнения только один раз. Выполнение SwingWorker более одного раза не приведёт к вызову метода doInBackground дважды.

cancel

public final boolean cancel(boolean mayInterruptIfRunning)
Попытка отмены выполнения этой задачи. Этот метод не имеет эффекта, если задача уже завершена или отменена, или не может быть отменена по другой причине. В противном случае, если эта задача ещё не началась, когда вызывается cancel, она никогда не должна выполняться. Если задача уже началась, то параметр mayInterruptIfRunning определяет, прерывается ли поток, выполняющий эту задачу (если он известен реализации), в попытке остановить задачу.

Значение возврата из этого метода не обязательно указывает, отменена ли задача; используйте Future.isCancelled().

Устанавливается по:
cancel в интерфейсе Future<T>
Параметры:
mayInterruptIfRunning - true если поток, выполняющий эту задачу, должен быть прерван (если поток известен реализации); в противном случае текущие задачи могут завершиться
Возвращает:
false если задача не могла быть отменена, обычно потому, что она уже завершена; true в противном случае. Если две или более потоки вызывают отмену задачи, то по крайней мере один из них возвращает true. Реализации могут обеспечивать более сильные гарантии.

isCancelled

public final boolean isCancelled()
Возвращает true если эта задача была отменена до её нормального завершения.
Устанавливается по:
isCancelled в интерфейсе Future<T>
Возвращает:
true если эта задача была отменена до её завершения

isDone

public final boolean isDone()
Возвращает true если эта задача завершена. Завершение может быть вызвано нормальным завершением, исключением или отменением — во всех этих случаях этот метод вернёт true.
Устанавливается по:
isDone в интерфейсе Future<T>
Возвращает:
true если эта задача завершена

get

public final T get() throws InterruptedException, ExecutionException
Если необходимо, ожидает завершения вычисления, а затем извлекает его результат.

Примечание: вызов get в потоке обработки событий блокирует все события, включая перерисовки, от обработки, пока эта SwingWorker не завершится.

Если вы хотите, чтобы SwingWorker блокировался в потоке обработки событий, рекомендуется использовать модальное диалоговое окно.

Например:

 class SwingWorkerCompletionWaiter implements PropertyChangeListener {
     private JDialog dialog;

     public SwingWorkerCompletionWaiter(JDialog dialog) {
         this.dialog = dialog;
     }

     public void propertyChange(PropertyChangeEvent event) {
         if ("state".equals(event.getPropertyName())
                 && SwingWorker.StateValue.DONE == event.getNewValue()) {
             dialog.setVisible(false);
             dialog.dispose();
         }
     }
 }
 JDialog dialog = new JDialog(owner, true);
 swingWorker.addPropertyChangeListener(
     new SwingWorkerCompletionWaiter(dialog));
 swingWorker.execute();
 //the dialog will be visible until the SwingWorker is done
 dialog.setVisible(true);
 
Устанавливается по:
get в интерфейсе Future<T>
Возвращает:
вычисленный результат
Выбрасывает:
CancellationException - если вычисление было отменено
InterruptedException - если текущий поток был прерван во время ожидания
ExecutionException - если вычисление вызвало исключение

get

public final T get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException
Если необходимо, ждёт не более заданного времени завершения вычисления, а затем извлекает его результат, если он доступен.

Подробнее см. get().

Устанавливается по:
get в интерфейсе Future<T>
Параметры:
timeout - максимальное время ожидания
unit - единица измерения времени аргумента таймаута
Возвращает:
вычисленный результат
Выбрасывает:
CancellationException - если вычисление было отменено
InterruptedException - если текущий поток был прерван во время ожидания
ExecutionException - если вычисление вызвало исключение
TimeoutException - если ожидание истекло

addPropertyChangeListener

public final void addPropertyChangeListener(PropertyChangeListener listener)
Добавляет PropertyChangeListener в список слушателей. Слушатель регистрируется для всех свойств. Один и тот же объект слушателя может быть добавлен более одного раза и будет вызван столько раз, сколько он добавлен. Если listener является null, исключение не выбрасывается и никаких действий не выполняется.

Примечание: это просто удобная обёртка. Вся работа делегируется PropertyChangeSupport из getPropertyChangeSupport().

Параметры:
listener - добавляемый PropertyChangeListener

removePropertyChangeListener

public final void removePropertyChangeListener(PropertyChangeListener listener)
Удаляет PropertyChangeListener из списка слушателей. Это удаляет PropertyChangeListener зарегистрированный для всех свойств. Если listener был добавлен более одного раза к одному источнику событий, он будет уведомлён на одно уведомление меньше после удаления. Если listener является null, или никогда не добавлялся, исключение не выбрасывается и никаких действий не выполняется.

Примечание: это просто удобная обёртка. Вся работа делегируется PropertyChangeSupport из getPropertyChangeSupport().

Параметры:
listener - удаляемый PropertyChangeListener

firePropertyChange

public final void firePropertyChange(String propertyName, Object oldValue, Object newValue)
Сообщает о обновлении связанного свойства всем зарегистрированным слушателям. Событие не генерируется, если old и new равны и не равны null.

Этот SwingWorker будет источником любых сгенерированных событий.

При вызове вне потока обработки событий PropertyChangeListeners уведомляются асинхронно в потоке обработки событий.

Примечание: Это просто удобная обёртка. Вся работа делегируется PropertyChangeSupport из getPropertyChangeSupport().

Parameters:
propertyName - программируемое имя свойства, которое было изменено
oldValue - старое значение свойства
newValue - новое значение свойства

getPropertyChangeSupport

public final PropertyChangeSupport getPropertyChangeSupport()
Возвращает PropertyChangeSupport для этого SwingWorker. Этот метод используется, когда необходим гибкий доступ к поддержке связанных свойств.

Этот SwingWorker будет источником любых сгенерированных событий.

Примечание: Возвращённый PropertyChangeSupport уведомляет любых PropertyChangeListener асинхронно в потоке обработки событий в случае, если firePropertyChange или fireIndexedPropertyChange вызываются вне потока обработки событий.

Returns:
PropertyChangeSupport для этого SwingWorker

getState

public final SwingWorker.StateValue getState()
Возвращает связанное свойство состояния SwingWorker.
Returns:
текущее состояние

© 1993, 2021, Oracle and/or its affiliates. All rights reserved.
Documentation extracted from Debian's OpenJDK Development Kit package.
Licensed under the GNU General Public License, version 2, with the Classpath Exception.
Various third party code in OpenJDK is licensed under different licenses (see Debian package).
Java and OpenJDK are trademarks or registered trademarks of Oracle and/or its affiliates.
https://docs.oracle.com/en/java/javase/17/docs/api/java.desktop/javax/swing/SwingWorker.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API