T
- тип результата возвратился этим SwingWorker's
doInBackground
и get
методыV
- тип, используемый для того, чтобы выполнить промежуточное звено, заканчивается этим SwingWorker's
publish
и process
методыpublic abstract class SwingWorker<T,V> extends Object implements RunnableFuture<T>
SwingWorker
является неуказанным и не должен быть положен. При записи многопоточного приложения, используя Swing, есть два ограничения, чтобы иметь в виду: (обратитесь к
Эти ограничения означают что приложение GUI со временем интенсивные вычислительные потребности по крайней мере два потока: 1) поток, чтобы выполнить длинную задачу и 2) Событие Диспетчеризирует Поток (EDT) для всех связанных с GUI действий. Это включает передачу межпотока, которая может быть хитрой, чтобы реализовать.
SwingWorker
разрабатывается для ситуаций, где Вам нужно было выполнить длинную выполняющуюся задачу в фоновом потоке и обеспечить обновления для UI или когда сделано, или обрабатывая. Подклассы SwingWorker
должен реализовать doInBackground()
метод, чтобы выполнить фоновое вычисление.
Поток операций
Есть три потока, включенные в жизненный цикл a 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
только разрабатывается, чтобы быть выполненным однажды. Выполнение a SwingWorker
не раз не будет приводить к вызову doInBackground
метод дважды.
Демонстрационное Использование
Следующий пример иллюстрирует самый простой вариант использования. Некоторая обработка делается в фоновом режиме, и когда сделано Вы обновляете компонент Swing.
Скажите, что мы хотим найти "Значение Жизни" и вывести на экран результат в a 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 и вывести на экран результаты в a JTextArea
. В то время как это является вычислительным, мы хотим обновить наше продвижение a 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
, a SwingWorker
может быть представлен Executor
для выполнения.
Модификатор и Тип | Класс и Описание |
---|---|
static class |
SwingWorker. StateValue
Значения для
state связанное свойство. |
Конструктор и Описание |
---|
SwingWorker()
Конструкции это
SwingWorker . |
Модификатор и Тип | Метод и Описание |
---|---|
void |
addPropertyChangeListener(PropertyChangeListener listener)
Добавляет a
PropertyChangeListener к списку слушателя. |
boolean |
cancel(boolean mayInterruptIfRunning)
Попытки отменить выполнение этой задачи.
|
protected abstract T |
doInBackground()
Вычисляет результат, или выдает исключение если неспособный, чтобы сделать так.
|
protected void |
done()
Выполняемый на Событии Диспетчеризируют Поток после
doInBackground метод заканчивается. |
void |
execute()
Расписания это
SwingWorker для выполнения на рабочем потоке. |
void |
firePropertyChange(String propertyName, Object oldValue, Object newValue)
Сообщает связанное обновление свойства любым зарегистрированным слушателям.
|
T |
get()
Ожидает в случае необходимости вычисления, чтобы завершиться, и затем получает его результат.
|
T |
get(long timeout, TimeUnit unit)
Ожидает в случае необходимости в течение самое большее данного времени для вычисления, чтобы завершиться, и затем получает его результат, при наличии.
|
int |
getProgress()
Возвраты
progress связанное свойство. |
PropertyChangeSupport |
getPropertyChangeSupport()
Возвраты
PropertyChangeSupport для этого SwingWorker . |
SwingWorker. StateValue |
getState()
Возвраты
SwingWorker утвердите связанное свойство. |
boolean |
isCancelled()
true возвратов, если эта задача была отменена прежде, чем это обычно завершалось.
|
boolean |
isDone()
true возвратов, если эта задача завершалась.
|
protected void |
process(List<V> chunks)
Получает блоки данных из
publish метод асинхронно на Событии Диспетчеризирует Поток. |
protected void |
publish(V... chunks)
Отправляет блоки данных
process(java.util.List<V>) метод. |
void |
removePropertyChangeListener(PropertyChangeListener listener)
Удаляет a
PropertyChangeListener от списка слушателя. |
void |
run()
Наборы это
Future к результату вычисления, если это не было отменено. |
protected void |
setProgress(int progress)
Наборы
progress связанное свойство. |
protected abstract T doInBackground() throws Exception
Отметьте, что этот метод выполняется только однажды.
Отметьте: этот метод выполняется в фоновом потоке.
Exception
- если неспособный вычислить результатpublic final void run()
Future
к результату вычисления, если это не было отменено.run
в интерфейсе Runnable
run
в интерфейсе RunnableFuture<T>
Thread.run()
@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>)
protected void process(List<V> chunks)
publish
метод асинхронно на Событии Диспетчеризирует Поток. Пожалуйста, обратитесь к publish(V...)
метод для большего количества деталей.
chunks
- промежуточное звено заканчивается, чтобы обработатьpublish(V...)
protected void done()
doInBackground
метод заканчивается. Реализация по умолчанию ничего не делает. Подклассы могут переопределить этот метод, чтобы выполнить действия завершения на Событии, Диспетчеризируют Поток. Отметьте, что можно запросить состояние в реализации этого метода, чтобы определить результат этой задачи или была ли эта задача отменена.doInBackground()
, isCancelled()
, get()
protected final void setProgress(int progress)
progress
связанное свойство. Значение должно быть от 0 до 100. Поскольку PropertyChangeListener
s уведомляются асинхронно на Событии, Диспетчеризируют Поток многократные вызовы setProgress
метод мог бы произойти перед любым PropertyChangeListeners
вызываются. В целях производительности все эти вызовы объединяются в один вызов с последним параметром вызова только.
Например, следующий invokations:
setProgress(1); setProgress(2); setProgress(3);мог бы привести к синглу
PropertyChangeListener
уведомление со значением 3
.progress
- значение продвижения, чтобы установитьIllegalArgumentException
- значение не от 0 до 100public final int getProgress()
progress
связанное свойство.public final void execute()
SwingWorker
для выполнения на рабочем потоке. Есть много доступных рабочих потоков. В конечном счете все рабочие потоки заняты, обрабатывая другой SwingWorkers
это SwingWorker
помещается в ожидающую очередь. Отметьте: SwingWorker
только разрабатывается, чтобы быть выполненным однажды. Выполнение a SwingWorker
не раз не будет приводить к вызову doInBackground
метод дважды.
public final boolean cancel(boolean mayInterruptIfRunning)
После этого метода возвраты, последующие звонки Future.isDone()
будет всегда возвращать true. Последующие звонки Future.isCancelled()
будет всегда возвращать true если этот метод возвращенный true.
cancel
в интерфейсе Future<T>
mayInterruptIfRunning
- true, если поток, выполняющий эту задачу, должен быть прерван; иначе, происходящим задачам позволяют завершитьсяpublic final boolean isCancelled()
isCancelled
в интерфейсе Future<T>
public final boolean isDone()
public final T get() throws InterruptedException, ExecutionException
Отметьте: вызов get
на Событии Диспетчеризируют блоки Потока все события, включая перекрашивания, от того, чтобы быть обработанным до этого SwingWorker
полно.
Когда Вы хотите SwingWorker
чтобы блокировать на Событии Диспетчеризируют Поток, мы рекомендуем, чтобы Вы использовали модальное диалоговое окно.
Например:
class SwingWorkerCompletionWaiter extends 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>
InterruptedException
- если текущий поток был прерван, ожидаяExecutionException
- если вычисление выдавало исключениеpublic final T get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException
Пожалуйста, обратитесь к get()
для большего количества деталей.
get
в интерфейсе Future<T>
timeout
- максимальное время, чтобы ожидатьunit
- единица измерения времени параметра тайм-аутаInterruptedException
- если текущий поток был прерван, ожидаяExecutionException
- если вычисление выдавало исключениеTimeoutException
- если ожидание синхронизированногоpublic final void addPropertyChangeListener(PropertyChangeListener listener)
PropertyChangeListener
к списку слушателя. Слушатель регистрируется для всех свойств. Тот же самый объект слушателя может быть добавлен не раз, и будет вызван так много раз, как он добавляется. Если listener
null
, никакое исключение не выдается, и никакие меры не предпринимаются. Отметьте: Это - просто обертка удобства. Вся работа делегируется к PropertyChangeSupport
от getPropertyChangeSupport()
.
listener
- PropertyChangeListener
быть добавленнымpublic final void removePropertyChangeListener(PropertyChangeListener listener)
PropertyChangeListener
от списка слушателя. Это удаляет a PropertyChangeListener
это было зарегистрировано для всех свойств. Если listener
был добавлен не раз к тому же самому источнику события, он будет уведомлен один меньше времени, будучи удаленным. Если listener
null
, или никогда не добавлялся, никакое исключение не выдается, и никакие меры не предпринимаются. Отметьте: Это - просто обертка удобства. Вся работа делегируется к PropertyChangeSupport
от getPropertyChangeSupport()
.
listener
- PropertyChangeListener
быть удаленнымpublic final void firePropertyChange(String propertyName, Object oldValue, Object newValue)
old
и new
являются равными и ненулевыми. Это SwingWorker
будет источник для любых сгенерированных событий.
Когда отозвано Событие Диспетчеризирует Поток
PropertyChangeListeners
уведомляются асинхронно на Событии, Диспетчеризируют Поток.
Отметьте: Это - просто обертка удобства. Вся работа делегируется к PropertyChangeSupport
от getPropertyChangeSupport()
.
propertyName
- программируемое имя свойства, которое было измененоoldValue
- старое значение свойстваnewValue
- новое значение свойстваpublic final PropertyChangeSupport getPropertyChangeSupport()
PropertyChangeSupport
для этого SwingWorker
. Этот метод используется, когда гибкий доступ к связанной поддержке свойств необходим. Это SwingWorker
будет источник для любых сгенерированных событий.
Отметьте: возвращенный PropertyChangeSupport
уведомляет любого PropertyChangeListener
s асинхронно на Событии Диспетчеризируют Поток когда firePropertyChange
или fireIndexedPropertyChange
отзываются Событие Диспетчеризирует Поток.
PropertyChangeSupport
для этого SwingWorker
public final SwingWorker.StateValue getState()
SwingWorker
утвердите связанное свойство.
Для дальнейшей ссылки API и документации разработчика, см. Java Документация SE. Та документация содержит более подробные, предназначенные разработчиком описания, с концептуальными краткими обзорами, определениями сроков, обходных решений, и рабочих примеров кода.
Авторское право © 1993, 2013, Oracle и/или его филиалы. Все права защищены.
Проект сборка-b92