Допустим, у нас есть длинная / тяжелая задача, которая должна выполняться в фоновом режиме и публиковать свой прогресс или что-то еще в графическом интерфейсе. Я знаю, что эта публикация должна происходить в потоке отправки событий. Вот почему мы используем SwingWorker
для этой задачи.
Итак, что мы делаем, это примерно так:
public class WorkerTest {
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
JFrame frame = new JFrame("test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new FlowLayout());
JLabel label = new JLabel();
frame.add(label);
startWorker(label);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
});
}
private static void startWorker(JLabel label) {
new SwingWorker<Integer, Integer>() {
@Override
protected Integer doInBackground() throws Exception {
for (int i = 0; i < 500; i++) {
publish(i);
Thread.sleep(500); //Simulate long task
}
return null;
}
@Override
protected void process(List<Integer> chunks) {
Integer integer = chunks.get(0);
label.setText(String.valueOf(integer));
}
}.execute();
}
}
У меня вопрос, чем вышеизложенное отличается от этого:
private static void startWorker(JLabel label) {
new SwingWorker<Integer, Integer>() {
@Override
protected Integer doInBackground() throws Exception {
for (int i = 0; i < 500; i++) {
int i2 = i;
SwingUtilities.invokeLater(() -> {
label.setText(String.valueOf(i2));
});
Thread.sleep(500); //Simulate long task
}
return null;
}
}.execute();
}
В обоих случаях label.setText()
, который является обновлением графического интерфейса пользователя, запускается в потоке отправки событий. Насколько они разные?
Конечно, возникает вопрос, почему я должен реализовать метод done()
для рабочего, а не вызвать SwingUtilities.invokeLater
в конце метода doInBackground
? Помимо обработки исключения, которое может быть выдано в doInBackground
методе.
invokeLater
я используюinvokeAndWait
. Даже при небольшом снижении производительности события публикуются так, как я хочу, и в правильном порядке. Итак, я полагаю, используяThread
изinvokeAndWait
, я могу добиться поведенияSwingWorker
. Я прав? - person George Z.   schedule 23.10.2020