【问题标题】:Handling exceptions in Swing GUI在 Swing GUI 中处理异常
【发布时间】:2012-09-02 17:14:08
【问题描述】:

我不确定如何在 GUI 中管理异常;我的目标是让用户知道出现问题时显示可理解的消息。

我正在考虑做这样的事情:

// I'm inside an actionPerformed() method
try {
    // do whatever I have to do here
} catch (KnownBusinessException1 e) {
    // inform the user and do something;
    // most times simply inform the user that it wasn't possible to complete the
    // operation and remain in the same window instead of moving forward.
} catch (KnownBusinessException2 e) {
    // just as above
} catch (KnownDataAccessException1 e) {
    // just as above
} catch (KnownDataAccessException2 e) {
    // just as above
} catch (RuntimeException e) { // I want to catch any other unexpected exception,
// maybe NPE or unchecked IllegalArgumentExceptions and so on
    // something went wrong, I don't know where nor how but I will surely inform the user
}

现在:如果在 try 块中有要捕获的已检查异常,是嵌套 try/catch 还是在捕获 RuntimeException 后捕获这些已检查异常更好? (这可能取决于,我什至不知道这是否会发生)

另一件事:Errors 呢?如果我是用户,我不希望遇到意外关机,我更希望应用程序告诉我发生了令人难以置信的错误并且没有人可以对此采取任何措施,“世界末日即将来临,所以我将立即退出”。至少我会知道这不是我的错,哈哈。

顺便说一句,不知道捕获错误是否是一个好习惯...:\

在 Swing 应用程序中有更好的方法吗?

【问题讨论】:

标签: java swing exception exception-handling


【解决方案1】:

我认为最好的办法是显式捕获所有已检查的异常,并为其余的安装未捕获的异常处理程序。看到这个:How can I detect when an Exception's been thrown globally in Java?

这就是我使用 Thread.setDefaultUncaughtExceptionHandler 的方式:

public static void setupGlobalExceptionHandling() {
    Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
        @Override
        public void uncaughtException(Thread t, Throwable e) {
            handleException(e);
        }
    });
}

请注意,许多 SO 帖子中提到的 EDT 线程的“sun.awt.exception.handler”技巧不是必需的,并且在 Java 7 中不起作用。对于 Java 7,只需使用描述的标准 Thread.setDefaultUncaughtExceptionHandler更多。当然,如果你同时使用这两种机制来注册异常处理程序,代码在所有版本中都可以工作。

顺便说一句,如果抛出未捕获的异常,EDT 线程会自动重新启动(但您的应用可能仍处于不一致状态),请参见:EDT and runtime exception

【讨论】:

  • +1 用于提及UncaughtExceptionHandler。在您的代码中确实是一件好事 :)
  • @lbalazscs:谢谢,但我不明白 handleException(e) 应该做什么。这是处理运行时异常(例如日志记录)的常用方法吗?如果我想对 RuntimeException 的不同子类采取不同的操作,具体取决于引发的异常以及导致它的用户的操作,该怎么办?
  • 在我看来,运行时异常不是由用户操作引起的,而是由程序员错误引起的 :) 在 GUI 中,我会显示异常消息,可能带有堆栈跟踪,我会要求用户联系具有此信息的开发人员。 SwingX 中的 JXErrorPane 类执行此操作。但是你可以做任何你想做的事情,包括检查异常的确切类别。
  • 是的,这也是我的观点,我表达得很糟糕:我的意思是用户点击了Button1,这个动作会导致运行时异常(由于编程错误(例如NPE)或任何(例如 DataAccessException))。显然,用户对该异常负责,但我想根据他是否在ViewX 中按Button1 或在ViewY 中按Button2 采取不同的行动:) 这可能在handleException(e) 方法?在我看来不是:(
  • 我在想也许我可以将UncaughtExceptionHandler 仅用于通用RuntimeExceptions,这应该以非常标准的方式处理(我想不出任何自定义方法,并且除了这将是一个矫枉过正)...或任何其他将以相同方式处理的异常,可能只是参数化错误消息(例如DataAccessException,我认为)。
【解决方案2】:

如果在 try 块中有要捕获的已检查异常,是嵌套 try/catch 还是在捕获 RuntimeException 后捕获这些已检查异常更好? (这可能取决于,我什至不知道这是否会发生)

正如您所说,这取决于在捕获异常后执行 try 块中的其余代码是否有意义。如果不是,那么嵌套 try/catch 块就没有意义了。

【讨论】:

    【解决方案3】:

    向用户显示出现问题的一个好方法是使用JOptionPanes。再加上对图标的良好使用(信息/错误),您就可以开始了。以下是一些示例代码供您参考:

    http://docs.oracle.com/javase/tutorial/uiswing/components/dialog.html

    如果您愿意,可以考虑在JOptionPane 上进行一些自定义/抽象类:)

    至于以相同的方式处理多个异常,如果消息在所有 3 个 KnownBusinessExceptions 和 KnownDataAccessExceptions 中都相同,那么您可以确保两个类具有相同的父级并捕获那个班级。如果KnownBusinessExceptions 而不是KnownDataAccessExceptions 需要相同的处理,则让所有KnownBusinessExceptions 具有相同的父级,并且所有KnownDataAccessExceptions 具有相同的父级。希望你能得到我要去的地方.

    【讨论】:

    • 这里没什么新东西,我知道如何使用 JOptionPane,如果我想以相同的方式处理多个异常,我肯定不会复制/粘贴。
    • 对不起,我误解了你的问题。 @Ibalazscs 的回答涉及 UncaughtExceptionHandler 可以满足您的要求。在应用程序级别,您可以处理未捕获的任何事情。假设您想在屏幕级别执行此操作(您可能期望发生运行时异常,您应该为这些异常添加捕获。希望这会有所帮助:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-08-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-24
    相关资源
    最近更新 更多