取消SwingWorke
任务后,我一直看到以下异常。
Exception in thread "AWT-EventQueue-0" java.util.concurrent.CancellationException
搜索网后,我发现below comment from Oracle
注意:如果在其背景之后在SwingWorker对象上调用get 任务已被取消,java.util.concurrent.CancellationException是 抛出。
这是我生成异常的代码。
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();
});
}
}
我搜索了一个我看到this和this的解决方案,但在我的情况下我无法fit
。
这是我用done()
方法解决问题的方法
@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);
}
}
使用上面设计的done()
,异常不会抛出。
现在我想知道这是否是nice
解决方案?这段代码的含义是什么?
答案 0 :(得分:1)
您的解决方案不完善,因为在您调用isCancelled()和调用get()之间可能会发生取消,这很少会导致异常。最好是捕获CancellationException并处理它。