6

我正在javax.swing制作一个应用程序,它从 XML Schema(使用 JAXFront 库)生成表单并将用户填充的数据存储到 XML 文档中。

我在需要时放置了 try-catch-finally 块,但是当主线程结束时(AWT 线程仍在运行)捕获异常时我遇到了一点问题。

我有两个做主要工作的班级和其他对这个问题不重要的班级:

  • 主类:它具有以下结构。初始化应用程序并运行主框架

    public class Main { 
        public static void main(String[] args) {
            readArgs(); // An INI file with the app config
            Model model = initializeElements(args); // My model class
            try {
                MyFrame mfr = new MyFrame(title,model);
                mfr.visualize(); // Assembling view and setting visible
            } catch( Excepion e ) {
                doCleanUp();
                System.exit(-1);
            }
        }
    }
  • Frame Class : 生成视图和监听事件

    public class MyFrame extends JFrame implements ActionListener,MenuListener { 
        // Some attributes
        // Other mthods without importance
        /**
         * Compose the elements, add listeners and set visible the frame
         */
        public void visualize() {
            generateFormPanel();
            setListeners();
            validate();
            setVisible(true);
        }
    
        public MyFrame(String title, Modele model) {
            super(title);
            createElementsUsing(model);
        }
    
        public void actionPerformed(ActionEvent e) {
            // Code to manage events
        }
    }

那么问题来了:当从main方法中执行visualize函数时,会生成并显示视图。那一刻是我失去对异常捕获的控制的时候。那么我的问题是,是否有某种方法可以捕获在此之后抛出的可能的 RuntimeExceptions

我希望你能理解我的英语并能回答这个问题。

提前致谢。

4

3 回答 3

24

最简单的版本是设置默认的未捕获异常处理程序:

Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
    public void uncaughtException(Thread t, Throwable e) {
        // do something
    }
});

但这也会捕获程序其他部分中抛出的未捕获异常。

但是,您可以使用代理仅捕获从 swing 事件调度线程抛出的运行时异常(有关更多信息,请参阅页面,从那里复制代码):

class EventQueueProxy extends EventQueue {

    protected void dispatchEvent(AWTEvent newEvent) {
        try {
            super.dispatchEvent(newEvent);
        } catch (Throwable t) {
            // do something more useful than: t.printStackTrace();
        }
    }
}

现在像这样安装它:

Toolkit.getDefaultToolkit().getSystemEventQueue().push(new EventQueueProxy());
于 2011-07-26T09:10:34.650 回答
1

在您调用之后visualize(),唯一运行的线程是 Swing/AWT 事件调度线程。如果您想捕获任何异常,则需要在此线程上调用的任何侦听器方法中执行此操作,例如

public void actionPerformed(ActionEvent e) {
  try {
    // Some code here
  } catch(RuntimeException e) {
    // Handling code here
  }
}

为了防止样板文件,您可以将此代码放在超类中。

请注意,如果您想捕获 Swing/AWT 线程尚未处理的任何内容,您还可以设置默认的未捕获异常处理程序。

另请注意,一般来说,如果可以避免,最好不要捕获 RuntimeException 的子类。

于 2011-07-26T09:11:07.677 回答
0

尝试添加:

setDefaultCloseOperation(EXIT_ON_CLOSE);

到 MyFrame 构造函数。虽然不确定,但值得一试。

于 2011-07-26T09:13:03.683 回答