【问题标题】:Catch exceptions in javax.swing application在 javax.swing 应用程序中捕获异常
【发布时间】:2011-10-13 05:56:42
【问题描述】:

我正在与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 方法执行可视化功能时,会生成并显示视图。那一刻是我失去对异常捕获的控制的时候。那么我的问题是是否有某种方法可以捕获在此之后抛出的可能的 RuntimeExceptions

希望你能听懂我的英语并回答问题。

提前致谢。

【问题讨论】:

    标签: java swing exception awt catch-all


    【解决方案1】:

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

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

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

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

    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());
    

    【讨论】:

    • 非常感谢。您的第一个解决方案解决了我的问题。我不能给你投票,但请接受!
    【解决方案2】:

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

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

    为了防止样板,您可以在超类中包含此代码。

    请注意,如果您想捕获 Swing/AWT 线程尚未处理的任何内容,也可以设置 default uncaught exception handler

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

    【讨论】:

      【解决方案3】:

      尝试添加:

      setDefaultCloseOperation(EXIT_ON_CLOSE);
      

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

      【讨论】:

      • 为了控制退出事件,我有 setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);addWindowListener(new WindowAdapter(){...}); 进行清理。
      猜你喜欢
      • 1970-01-01
      • 2011-09-11
      • 2012-04-04
      • 1970-01-01
      • 2011-09-26
      • 1970-01-01
      • 2015-09-25
      • 2018-08-25
      • 2016-05-18
      相关资源
      最近更新 更多