public class Worker extends SwingWorker<Integer, String> {
private JLabel screen;
public Worker(JLabel screen) {
this.screen = screen;
}
@Override
protected Integer doInBackground() throws Exception {
for (; ; ) {
publish(String.valueOf(Calendar.getInstance().getTimeInMillis()));
}
}
@Override
protected void process(List<String> chunks) {
screen.setText(chunks.get(0));
}
}
И в форме:
public class Form extends JPanel{
private JButton startButton;
private JPanel rootPanel;
private JButton stopButton;
private JLabel screen;
private Worker worker;
public Form() {
startButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
worker = new Worker(screen);
worker.execute();
}
});
stopButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
worker.cancel(true);
System.out.println(worker.isDone());
System.out.println(worker.isCancelled());
}
});
}
private void createUIComponents() {
rootPanel = this;
}
}
Я пытался написать тот же код с Tread, но он тоже не работает. И вывод консоли после нажатия на stopButton:
true
true
Итак, рабочий выполнен, но программа продолжает показывать миллисекунды. Что такое посмертная жизнь? И в случае использования Thread то же самое: метод isAlive() возвращает «false».
SwingWorker должен вызвать метод isCancelled(), чтобы определить, был ли рабочий процесс отменен, а затем выйти из цикла while в методе doInBackground().




Судя по вашему коду, похоже, что вам нужен рабочий процесс с циклом, который будет продолжать работать до тех пор, пока главный поток не сообщит ему о прекращении работы, что и делается с помощью worker.cancel(true);. Проблема в том, что вы отменяете его, но ничего не делаете, чтобы сигнализировать самому циклу о прекращении итерации. Чтобы исправить это, вы должны изменить
for (; ; ) {
publish(String.valueOf(Calendar.getInstance().getTimeInMillis()));
}
к
while(!isCancelled()){
publish(String.valueOf(Calendar.getInstance().getTimeInMillis()));
}
Обратите внимание на формулировку «isCancelled» из документации по Java:
isCancelled()Returns true if this task was canceled before it completed normally. Since the loop never closes on its' own, it will never complete normally.
ваш цикл никогда не завершается, поэтому рабочий никогда не останавливается. Вместо
for( ; ; )попробуйтеwhile (!Thread.interrupted())(метод публикации не проверяет)