Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/324.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java SwingWorker中的错误处理_Java_Swing_Swingworker_Event Dispatch Thread_Invokeandwait - Fatal编程技术网

Java SwingWorker中的错误处理

Java SwingWorker中的错误处理,java,swing,swingworker,event-dispatch-thread,invokeandwait,Java,Swing,Swingworker,Event Dispatch Thread,Invokeandwait,我的问题是一个基于理论的问题,但它确实满足了我的特殊需要 如果SwingWorker抛出了一个异常,您a)可以预期,b)需要从中恢复并继续,但您想通知用户该错误已经发生,您该怎么办?如何获取预期的异常并通知用户,而不违反“没有来自doInBackground()的Swing代码”规则 考虑到这个问题,我开发了一个SSCCE,我想提出以下问题 SSCCE: import java.awt.event.ActionEvent; import java.awt.event.ActionListener

我的问题是一个基于理论的问题,但它确实满足了我的特殊需要

如果SwingWorker抛出了一个异常,您a)可以预期,b)需要从中恢复并继续,但您想通知用户该错误已经发生,您该怎么办?如何获取预期的异常并通知用户,而不违反“没有来自
doInBackground()的Swing代码”规则

考虑到这个问题,我开发了一个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();
        }

    }
}
导入java.awt.event.ActionEvent;
导入java.awt.event.ActionListener;
导入java.util.concurrent.ExecutionException;
导入javax.swing.JButton;
导入javax.swing.JDialog;
导入javax.swing.JFrame;
导入javax.swing.JOptionPane;
导入javax.swing.JProgressBar;
导入javax.swing.SwingUtilities;
导入javax.swing.SwingWorker;
公开课考试{
公共静态void main(字符串参数[]){
最终JFrame=新JFrame();
JButton go=新JButton(“go”);
go.addActionListener(新ActionListener(){
@凌驾
已执行的公共无效操作(操作事件e){
新任务(框架);
}
});
frame.add(go);
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationByPlatform(真);
frame.setVisible(true);
}
静态类任务扩展SwingWorker{
JFrame父代;
JDialog对话框;
公共任务(JFrame父级){
this.parent=parent;
dialog=newjdialog(父级);
JProgressBar jpb=新的JProgressBar();
jpb.setUndeterminate(真);
添加对话框(jpb);
对话框.setLocationRelativeTo(空);
对话框.setVisible(true);
执行();
}
@凌驾
受保护的Void doInBackground()引发异常{
对于(int i=0;i<100000;i++){
系统输出打印LN(i);
试一试{
如果(i==68456)抛出新的非法状态异常(“Yikes!i=68456”);
}捕获(最终非法状态){
SwingUtilities.invokeAndWait(新的Runnable(){
@凌驾
公开募捐{
showMessageDialog(父级,“错误:+e.getMessage(),“错误”,JOptionPane.Error\u消息);
}
});
}
}
返回null;
}
@凌驾
受保护的void done(){
如果(!isCancelled()){
试一试{
get();
}捕获(ExecutionException | InterruptedException e){
e、 printStackTrace();
}
}
系统输出打印项次(“完成”);
dialog.dispose();
}
}
}
doInBackground()
方法中调用
SwingUtilities.invokeAndWait()
是否有效?
我对此进行了一些线程分析,结果如下:

按下“Go”按钮后,
SwingWorker-pool-1-thread-1
线程变为绿色。然后,当满足if条件时,抛出错误,并显示错误对话框,线程变为黄色,并且
AWT-EventQueue-0
线程上确实有一个绿色的“blip”,指示调用了EDT。我等了大约10秒钟,按下“ok”,SwingWorker线程再次变绿

这样做有没有潜在的陷阱?有没有人有过从SwingWorker
实时通知用户计算错误的经验


老实说,这种方法让我怀疑。似乎不太正统,但我不能肯定这是否是个坏主意。

我认为在用户实际需要批准时使用
invokeAndWait()
没有问题。如果没有,如图所示,
SwingWorker
只需调用
publish()
,数据和错误消息交错。在
done()
中附加适当的消息将允许用户在必要时查看累计输出。

如果它是已处理的异常,您可以在
doInBackground
中返回
Void
,而不是返回带有
errorCode
说明的bean。。或者当异常发生时,调用
publish
以获取调用的
process
并处理异常,或者您可以使用
firePropertyChange
确认发生了错误,确保我可以返回除
Void
以外的内容,但返回
Void
的是我的SSCCE。我的实际应用程序可能需要返回临时结果。SwingWorker没有正确使用doInBackground(workers线程,不是invokeAndWait的位置,只有在初始踩踏后不是EDT,如果EDT处于活动状态则导致异常),使用publish(在EDT上完成)作为JOptionPane,您真正想做什么或知道什么about@mKorbel根据,,这是
invokeAndWait
的有效用法,因为1)它不是从EDT调用的,2)我需要更新GUI,3)我需要线程等待用户点击“ok”后才能继续。这在
publish()
process()
中是不可能的。