Обычно SwingWorker используется для выполнения долгосрочных задач в Swing.
Выполнение долгосрочных задач в потоке диспетчеризации событий (EDT) может привести к блокировке графического интерфейса, поэтому было сделано только одно из следующих действий: SwingUtilities.invokeLater
и invokeAndWait
, который поддерживает реагирование графического пользовательского интерфейса, который определяет приоритет других событий AWT перед запуском требуемой задачи (в форме Runnable
).
Однако проблема с SwingUtilities
заключается в том, что он не позволяет возвращать данные из выполненного Runnable
в исходный метод. Это то, что SwingWorker
было предназначено для решения.
В руководстве по Java есть раздел, посвященный SwingWorker .
Вот пример, где SwingWorker
используется для выполнения трудоемкой задачи в отдельном потоке и через секунду отображает окно сообщения с ответом.
Во-первых, будет расширен класс SwingWorker
:
class AnswerWorker extends SwingWorker<Integer, Integer>
{
protected Integer doInBackground() throws Exception
{
// Do a time-consuming task.
Thread.sleep(1000);
return 42;
}
protected void done()
{
try
{
JOptionPane.showMessageDialog(f, get());
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
Тип возврата методов doInBackground
и get
указывается как первый тип SwingWorker
, а второй тип - это тип, используемый для возврата для методов publish
и process
, которые не используются в этом примере.
Затем, чтобы вызвать SwingWorker
, вызывается метод execute
. В этом примере мы подключим ActionListener
к JButton
для выполнения AnswerWorker
:
JButton b = new JButton("Answer!");
b.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e)
{
new AnswerWorker().execute();
}
});
Вышеупомянутая кнопка может быть добавлена к JFrame
и нажата, чтобы через секунду получить окно сообщения. Для инициализации графического интерфейса для приложения Swing можно использовать следующее:
private void makeGUI()
{
final JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.getContentPane().setLayout(new FlowLayout());
// include: "class AnswerWorker" code here.
// include: "JButton" b code here.
f.getContentPane().add(b);
f.getContentPane().add(new JButton("Nothing"));
f.pack();
f.setVisible(true);
}
После запуска приложения появятся две кнопки. Один с надписью "Ответ!" и еще одно «Ничего». Когда один нажимает на «Ответить!» кнопка, сначала ничего не произойдет, но нажатие на кнопку «Ничего» будет работать и продемонстрирует, что графический интерфейс отзывчив.
И через секунду результат AnswerWorker
появится в окне сообщения.