Spec-Zone.ru › OpenJDK 27

Класс SwingWorker<T,V>

java.lang.Object
javax.swing.SwingWorker<T,V>
Параметры типа:
T - the result type returned by this SwingWorker's doInBackground and get methods
V - the type used for carrying out intermediate results by this SwingWorker's publish and process methods
Все реализуемые интерфейсы:
Runnable, Future<T>, RunnableFuture<T>
public abstract class SwingWorker<T,V> extends Object implements RunnableFuture<T>
Абстрактный класс для выполнения длительных задач взаимодействия с графическим интерфейсом в фоновом потоке. Для выполнения таких задач могут использоваться несколько фоновых потоков. Однако точная стратегия выбора потока для любой конкретной SwingWorker не определена, и полагаться на неё не следует.

При написании многопоточного приложения с использованием Swing следует учитывать два ограничения (подробнее см. в разделе Параллельность в Swing ):

  • Длительные задачи не следует выполнять в потоке диспетчеризации событий. Иначе приложение перестанет отвечать на запросы.
  • Доступ к компонентам Swing разрешён только из потока диспетчеризации событий.

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

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.

Начиная с версии:
1.6

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

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

Вложенные классы/интерфейсы, объявленные в интерфейсе Future

Future.State
Модификатор и тип Интерфейс Описание
static enum  Future.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(List).
final void removePropertyChangeListener(PropertyChangeListener listener)
Удаляет PropertyChangeListener из списка слушателей.
final void run()
Устанавливает для этого Future результат вычисления, если задача не была отменена.
protected final void setProgress(int progress)
Устанавливает связанное свойство progress.

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

clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
Модификатор и тип Метод Описание
protected Object clone()
Создаёт и возвращает копию этого объекта.
boolean equals(Object obj)
Указывает, равен ли этот объект некоторому другому объекту.
protected void finalize()
Устарело и подлежит удалению: этот элемент API может быть удалён в будущей версии.
Финализация объявлена устаревшей и подлежит удалению в одном из будущих выпусков.
final Class<?> getClass()
Возвращает класс времени выполнения этого Object.
int hashCode()
Возвращает хеш-код этого объекта.
final void notify()
Пробуждает один поток, ожидающий на мониторе этого объекта.
final void notifyAll()
Пробуждает все потоки, ожидающие на мониторе этого объекта.
String toString()
Возвращает строковое представление объекта.
final void wait()
Заставляет текущий поток ожидать пробуждения, обычно посредством уведомления или прерывания.
final void wait(long timeoutMillis)
Заставляет текущий поток ожидать пробуждения, обычно посредством уведомления или прерывания, либо до истечения заданного промежутка реального времени.
final void wait(long timeoutMillis, int nanos)
Заставляет текущий поток ожидать пробуждения, обычно посредством уведомления или прерывания, либо до истечения заданного промежутка реального времени.

Методы, объявленные в интерфейсе Future

exceptionNow, resultNow, state
Модификатор и тип Метод Описание
default Throwable exceptionNow()
Возвращает исключение, выброшенное задачей, не ожидая её завершения.
default T resultNow()
Возвращает вычисленный результат, не ожидая завершения вычисления.
default Future.State state()
Возвращает состояние вычисления.

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

SwingWorker

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

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

doInBackground

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

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

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

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

run

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

publish

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

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

Например:

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(List)

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.

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

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

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().

Параметры:
propertyName - программное имя изменённого свойства
oldValue - старое значение свойства
newValue - новое значение свойства

getPropertyChangeSupport

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

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

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

Возвращает:
PropertyChangeSupport для этого SwingWorker

getState

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

Сообщить об ошибке или предложить улучшение
Дополнительные справочные материалы по API и документацию для разработчиков см. в разделе Документация Java SE, содержащем более подробные описания для разработчиков, включая концептуальные обзоры, определения терминов, обходные решения и рабочие примеры кода. Другие версии.
Java является товарным знаком или зарегистрированным товарным знаком Oracle и/или её дочерних компаний в США и других странах.
Авторские права © 1993, 2026, Oracle и/или её дочерние компании, 500 Oracle Parkway, Redwood Shores, CA 94065 USA.
Все права защищены. Использование регулируется условиями лицензии и политикой распространения документации.

© 1993, 2025, 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.

Spec-Zone.ru

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