SwingWorker
![]() | В этой статье есть несколько проблем. Пожалуйста, помогите улучшить его или обсудите эти проблемы на странице обсуждения . ( Узнайте, как и когда удалять эти шаблонные сообщения )
|
SwingWorker — это служебный класс , разработанный Sun Microsystems для Swing библиотеки языка программирования Java . SwingWorker обеспечивает правильное использование потока диспетчеризации событий . Начиная с Java 6 , SwingWorker включен в JRE . [ 1 ]
Несколько несовместимых неофициальных версий SwingWorker были выпущены с 1998 по 2006 год, и необходимо проявлять осторожность, чтобы избежать обильной документации по этим версиям, предшествующей Java 6.
Использование в Java 6.0
[ редактировать ]Проблема с потоком диспетчеризации событий
[ редактировать ]SwingWorker полезен, когда после события взаимодействия с пользователем необходимо выполнить трудоемкую задачу (например, анализ огромного XML-файла при нажатии JButton). Самый простой способ сделать это:
private Document doc;
...
JButton button = new JButton("Open XML");
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
doc = loadXML();
}
});
Это сработает, но, к сожалению, loadXML()
метод будет вызываться в том же потоке , что и основной поток Swing ( поток диспетчеризации событий ), поэтому, если методу требуется время для выполнения, графический интерфейс на это время зависает.
Решение SwingWorker
[ редактировать ]Эта проблема характерна не только для Java, но характерна для многих моделей с графическим интерфейсом . SwingWorker
предлагает способ решения этой проблемы, выполняя трудоемкую задачу в другом фоновом потоке, сохраняя графического интерфейса в это время отзывчивость .
Создание работника
[ редактировать ]Следующий код определяет SwingWorker, который инкапсулирует loadXML()
вызов метода:
SwingWorker worker = new SwingWorker<Document, Void>() {
@Override
public Document doInBackground() {
Document intDoc = loadXML();
return intDoc;
}
};
Исполнение рабочего
[ редактировать ]Выполнение начинается с помощью
SwingWorker.execute()
метод.
Получение результата
[ редактировать ]Результат можно получить с помощью SwingWorker.get()
метод.
Как звоню get()
в потоке диспетчеризации событий блокирует обработку всех событий, включая перерисовки, до завершения задачи, поэтому следует избегать его вызова до завершения длительной операции. Получить результат после завершения задачи можно двумя способами:
- отменить
SwingWorker.done()
метод. Этот метод вызывается в главном потоке диспетчеризации событий .
private Document doc;
...
SwingWorker<Document, Void> worker = new SwingWorker<Document, Void>() {
@Override
public Document doInBackground() {
Document intDoc = loadXML();
return intDoc;
}
@Override
public void done() {
try {
doc = get();
} catch (InterruptedException ex) {
ex.printStackTrace();
} catch (ExecutionException ex) {
ex.printStackTrace();
}
}
}
- зарегистрировать прослушиватель с помощью работника
SwingWorker.addPropertyChangeListener(PropertyChangeListener)
метод. Слушатель будет уведомлен об изменениях в рабочем состоянии.
Полный пример работника
[ редактировать ]private Document doc;
...
JButton button = new JButton("Open XML");
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
SwingWorker<Document, Void> worker
= new SwingWorker<Document, Void>() {
@Override
public Document doInBackground() {
Document intDoc = loadXML();
return intDoc;
}
@Override
public void done() {
try {
doc = get();
} catch (InterruptedException ex) {
ex.printStackTrace();
} catch (ExecutionException ex) {
ex.printStackTrace();
}
}
};
worker.execute();
}
});
История: использование до Java 6.0.
[ редактировать ]SwingWorker является частью Java SE только начиная с Java 6.0. Sun выпустила версии для использования с более ранними JDK, хотя это были неофициальные версии, которые не входили в состав Java SE и не упоминались в документации стандартной библиотеки. [ 2 ] Самая последняя из этих версий датируется 2003 годом и часто называется SwingWorker версии 3. [ 3 ] К сожалению, JDK 6.0 SwingWorker и SwingWorker версии 3 используют разные имена методов и несовместимы. Версия Backport (см. ниже) теперь рекомендуется для использования до Java 6.
Пример создания экземпляра SwingWorker 3 показан ниже:
SwingWorker worker = new SwingWorker() {
public Object construct() {
... //add the code for the background thread
}
public void finished() {
... //code that you add here will run in the UI thread
}
};
worker.start(); //Start the background thread
The start()
Метод выполняет код, добавленный в методstruct(), в отдельном потоке.
Чтобы получить предупреждение о завершении фонового потока, достаточно переопределить finished()
метод. construct()
метод может возвращать результат, который позже можно будет получить с помощью метода SwingWorker. get()
метод.
Резервное копирование Java 6 SwingWorker
[ редактировать ]Резервная копия SwingWorker из Java 6 в Java 5 доступна по адресу http://swingworker.java.net/. [ постоянная мертвая ссылка ] . Помимо имени пакета ( org.jdesktop.swingworker
), он совместим с Java 6 SwingWorker.
Эквиваленты
[ редактировать ]System.ComponentModel.BackgroundWorker
- .NET Frameworkflash.system.Worker
- Адобе Флэшandroid.os.AsyncTask
- Андроид
Ссылки
[ редактировать ]- ^
SwingWorker
- ^ См .
javax.swing
сводка пакета до и после J2SE 6.0. Также обратите внимание, что класс SwingWorker не указан на индексных страницах документации до версии 6.0: [1] , [2] . - ^ Вы можете скачать его. «Свингворкер 3» . Интернет-архив. Архивировано из оригинала 26 июня 2012 года.
Внешние ссылки
[ редактировать ]- Документация класса SwingWorker для Java 7.
- Рабочие потоки и SwingWorker из руководства Oracle по параллелизму Java в Swing .
- Улучшение производительности приложений с помощью SwingWorker в Java SE 6 , Джон О'Коннер, январь 2007 г.