I have been seeing the following exception after cancelling SwingWorke
task.
Exception in thread "AWT-EventQueue-0" java.util.concurrent.CancellationException
After searching the net I found below comment from Oracle
Note: If get is invoked on a SwingWorker object after its background task has been cancelled, java.util.concurrent.CancellationException is thrown.
This is my code that generates the exception.
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JProgressBar;
import javax.swing.SwingWorker;
public class JasperReportGenerator {
private JButton cancel;
private JProgressBar pbar;
private int count = 0;
private JFrame dialog;
public JasperReportGenerator() {
init();
//Here we do the background task
SwingWorker<Boolean, Integer> worker = new SwingWorker<Boolean, Integer>() {
@Override
protected Boolean doInBackground() throws Exception {
for (int i = 0; i < 10; i++) {
publish(i * 10);
Thread.sleep(1000);
}
return true;
}
@Override
protected void done() {
try {
dialog.dispose();
JOptionPane.showMessageDialog(null, "Done", get().toString(), JOptionPane.INFORMATION_MESSAGE);
} catch (InterruptedException ex) {
Logger.getLogger(JasperReportGenerator.class.getName()).log(Level.SEVERE, null, ex);
} catch (ExecutionException ex) {
Logger.getLogger(JasperReportGenerator.class.getName()).log(Level.SEVERE, null, ex);
}
}
@Override
protected void process(List<Integer> list) {
pbar.setValue(list.get(list.size() - 1));
pbar.setString(list.get(list.size() - 1) + "%");
}
};
worker.execute();
//cancel the process
cancel.addActionListener((ActionEvent e) -> {
worker.cancel(true);
dialog.dispose();
System.out.println("bg task cancelled...");
});
}
private void init() {
dialog = new JFrame("Progress Report");
dialog.setLocationRelativeTo(null);
cancel = new JButton("Cancel");
pbar = new JProgressBar(0, 100);
pbar.setStringPainted(true);
pbar.setIndeterminate(false);
dialog.setPreferredSize(new Dimension(400, 250));
dialog.setLayout(new FlowLayout());
dialog.getContentPane().add(pbar);
dialog.getContentPane().add(cancel);
dialog.pack();
dialog.setVisible(true);
}
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(() -> {
new JasperReportGenerator();
});
}
}
I search of a solution I saw this and this but I could not fit
them in my case.
This is what I have done in my done()
method to solve the problem
@Override
protected void done() {
try {
if (!isCancelled()) {
JOptionPane.showMessageDialog(null, "Done", get().toString(), JOptionPane.INFORMATION_MESSAGE);
dialog.dispose();
}
} catch (InterruptedException ex) {
Logger.getLogger(JasperReportGenerator.class.getName()).log(Level.SEVERE, null, ex);
} catch (ExecutionException ex) {
Logger.getLogger(JasperReportGenerator.class.getName()).log(Level.SEVERE, null, ex);
}
}
With my done()
designed as above, the exception is not throw.
Now I would like to know if this is a nice
solution? What are the implications of this code?