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));
}
}
And in Form:
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;
}
}
I tried to write same code with Tread, but it doesn't work too. And console output after click on stopButton:
true
true
So, worker have done, but program still continue show milliseconds. What is a post-death life? And in case of using Thread same thing: method isAlive() return "false".
Based on your code, it looks like you need a worker with a loop to keep running until the master thread tells it to stop running, which is done with worker.cancel(true);
. The problem is that you are canceling it, but doing nothing to signal the loop itself to stop iterating. To fix this, you should change
for (; ; ) {
publish(String.valueOf(Calendar.getInstance().getTimeInMillis()));
}
to
while(!isCancelled()){
publish(String.valueOf(Calendar.getInstance().getTimeInMillis()));
}
Note the phrasing of 'isCancelled' from the java docs:
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.