私の質問は理論に基づいた質問ですが、私が持っている特定のニーズを満たしています。
SwingWorker が a) 予期できる例外をスローし、b) 回復して続行する必要があるが、このエラーが発生したことをユーザーに通知したい場合はどうしますか? doInBackground()
「No Swing code from 」ルールに違反することなく、予想される例外を取得してユーザーに通知するにはどうすればよいですか?
この問題を考慮して、私は 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()
これについてスレッドのプロファイリングを行ったところ、結果は次のようになりました。
「Go」ボタンが押されると、SwingWorker-pool-1-thread-1
スレッドは緑色になります。THEN、if 条件が満たされると、エラーがスローされ、エラー ダイアログが表示され、スレッドが黄色AWT-EventQueue-0
になり、EDT が呼び出されたことを示す緑色の「ブリップ」がスレッドに表示されます。約 10 秒待って「OK」を押すと、SwingWorker
スレッドが再び緑色になりました。
このようなことをすることの潜在的な落とし穴はありますか? からリアルタイムで計算エラーをユーザーに通知した経験のある人はいSwingWorker
ますか?
正直なところ、このアプローチには不安があります。異例のようですが、これが悪い考えかどうかは断言できません。