我的问题是基于理论的问题,但它确实满足了我的特定需求。
当您的 SwingWorker 抛出异常时,您 a) 可以预见并且 b) 需要恢复并继续,但您想通知用户此错误已经发生,您会怎么做?如何捕获预期的异常并通知用户而不违反“No Swing code fromdoInBackground()
" rule?
考虑到这个问题,我开发了一个SSCCE,我想将其与下面的问题一起提出。
SSCCE:
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.concurrent.ExecutionException;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JProgressBar;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
public class Test {
public static void main(String args[]) {
final JFrame frame = new JFrame();
JButton go = new JButton("Go.");
go.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
new Task(frame);
}
});
frame.add(go);
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
static class Task extends SwingWorker<Void, Void> {
JFrame parent;
JDialog dialog;
public Task(JFrame parent) {
this.parent = parent;
dialog = new JDialog(parent);
JProgressBar jpb = new JProgressBar();
jpb.setIndeterminate(true);
dialog.add(jpb);
dialog.setLocationRelativeTo(null);
dialog.setVisible(true);
execute();
}
@Override
protected Void doInBackground() throws Exception {
for(int i = 0; i < 100000; i++) {
System.out.println(i);
try {
if(i == 68456) throw new IllegalStateException("Yikes! i = 68456.");
} catch (final IllegalStateException e) {
SwingUtilities.invokeAndWait(new Runnable() {
@Override
public void run() {
JOptionPane.showMessageDialog(parent, "Error: " + e.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
}
});
}
}
return null;
}
@Override
protected void done() {
if (!isCancelled()) {
try {
get();
} catch (ExecutionException | InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("done");
dialog.dispose();
}
}
}
拨打电话是否有效SwingUtilities.invokeAndWait()
内doInBackground()
method?我对此做了一些线程分析,结果如下:
一旦按下“Go”按钮,SwingWorker-pool-1-thread-1
线程变绿。 THEN,当满足if条件时,抛出错误,并显示错误对话框,线程进入yellow,并且确实有一个绿色的“光点”AWT-EventQueue-0
线程,表明 EDT 已被调用。我等了大约 10 秒钟,按下“确定”,然后SwingWorker
线程再次变绿。
做这样的事情有任何潜在的陷阱吗?有谁有从实时通知用户计算错误的经验吗?SwingWorker
?
老实说,这种方法让我感到怀疑。它seems非正统,但我不能肯定地说这是否是一个坏主意。