You need to keep a reference to your SwingWorker, then you use that reference to cancel the worker thread.
MySwingWorker myWorker = new MySwingWorkerClass(args).execute();
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e)
{
// Stop the swing worker thread
myWorker.cancel(true);
}
});
Here is a full example:
public class WorkerDemo extends JFrame {
private boolean isStarted = false;
private JLabel counterLabel = new JLabel("Not started");
private Worker worker = new Worker();
private JButton startButton = new JButton(new AbstractAction("Start") {
@Override
public void actionPerformed(ActionEvent arg0) {
if(!isStarted) {
worker.execute();
isStarted = false;
}
}
});
private JButton stopButton = new JButton(new AbstractAction("Stop") {
@Override
public void actionPerformed(ActionEvent arg0) {
worker.cancel(true);
}
});
public WorkerDemo() {
add(startButton, BorderLayout.WEST);
add(counterLabel, BorderLayout.CENTER);
add(stopButton, BorderLayout.EAST);
pack();
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
}
class Worker extends SwingWorker<Void, Integer> {
int counter = 0;
@Override
protected Void doInBackground() throws Exception {
while(true) {
counter++;
publish(counter);
Thread.sleep(60);
}
}
@Override
protected void process(List<Integer> chunk) {
// get last result
Integer counterChunk = chunk.get(chunk.size()-1);
counterLabel.setText(counterChunk.toString());
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new WorkerDemo();
}
});
}
}
You need to periodically check its cancelled flag (i.e. isCancelled()
). SwingWorker
leaves how to handle the interrupt up to you.
For more information, see Cancelling Background Tasks.
you can try overidding the done() method and put it in try catch and catch the java.util.concurrent.CancellationException. Something like
. . .
@Overide
done() {
try {
get();
} catch (CancellationException e) {
// Do your task after cancellation
}
}
. . .
I think you have to restart the counter after every stop.
For startButton, you have to have worker restarted as in
private JButton startButton = new JButton(new AbstractAction("Start") {
@Override
public void actionPerformed(ActionEvent arg0) {
if(!isStarted) {
worker = new Worker(); // New line
worker.execute();
isStarted = false;
}
}
});
To stop you can use
worker.setStopFlag(); // in stopButton actionPerformed block.
in Worker class private boolean stopFlag = false;
and add
if( stopFlag)
break;
after Thread.sleep(60); and finally put setter for stopFlag at the end of Worker class as
void setStopFlag(){
stopFlag = true;
}
By the way, you can use cancel(true) if you want to have exception exit.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With