在AWT队列线程中调试exception

我正在开发一个Swing应用程序,其中包含执行自定义绘制的组件 当我在绘制代码中犯了一些错误并抛出exception时,情况很难调试。 弹出窗口显示exception信息,而不是被调试器捕获。 此外, 线程似乎重新启动 ,并且由于编码错误的结果exception,它会一次又一次地显示。

当我很幸运地切换到调试器时(这很困难,因为越来越多的弹出窗口随着应用程序获取绘制请求而不断出现),调试控制台会向我显示一个exception信息,例如:

严重:线程中抛出未捕获的exception[AWT-EventQueue-0,6,main]

….堆栈如下

我的应用程序是用Scala编写的,我使用的是IntelliJ IDEA 14.我的未捕获的主线程exception由调试器处理得很好(我在Java Exception Breakpoints启用了Any exception断点的Uncaught exception ),但AWT线程中的exception不是。

我已经尝试过安装一个处理程序,如下所述我如何检测何时在Java中全局抛出exception? 回答 ,但我的处理程序似乎没有被触发。

我想实现以下(按重要性顺序):

  1. 避免AWT线程在exception时重新启动,或者至少阻止弹出窗口显示
  2. 在调试器中处理未捕获的exception,而不是在控制台中打印

(注意:虽然这是Scala应用程序,但我认为Java的行为是相同的,因此Java标记)。

根据此链接 ,您必须处理常规ExceptionEDT Exception而不使用旧的sun.awt.exception.handler hack(自Java 7以来不再起作用)

这是你的ExceptionHandler

 public static class ExceptionHandler implements Thread.UncaughtExceptionHandler { public void uncaughtException(Thread thread, Throwable thrown) { // TODO handle your Exception here } } 

用法:

 // Regular Exception Thread.setDefaultUncaughtExceptionHandler(new ExceptionHandler()); // EDT Exception SwingUtilities.invokeAndWait(new Runnable() { public void run() { // We are in the event dispatching thread Thread.currentThread().setUncaughtExceptionHandler(new ExceptionHandler()); } }); 

在Java中

你的问题是exception被抛出在另一个线程中,即事件调度线程。 几个解决方案:

 Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() { public void uncaughtException(Thread t, Throwable e) { logger.error("Uncaught exception in thread: " + t.getName, e); } }); 

在任何情况下,你原则上应该是你的UI启动代码

 EventQueue.invokeLater(); 

或直接调用它的SwingUtilities.invokeLater() 。

在斯卡拉

你的问题是exception被抛出在另一个线程中,即事件调度线程。 几个解决方案:

 Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() { def uncaughtException(t: Thread, e: Throwable) { logger.error("Uncaught exception in thread: " + t.getName, e) } }) 

在任何情况下,你原则上应该是你的UI启动代码

 EventQueue.invokeLater() 

看起来您唯一的解决方案可能是切换到Eclipse。 :-)其他解决方案需要编码工作,并且在exception处理程序中停止与在抛出exception的确切位置停止不同。

使用以下程序,我在Eclipse中侦听捕获/未捕获的RuntimeException实例时没有任何问题。

 package lambda; import java.awt.Dimension; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.SwingUtilities; public class AWTExceptionTest { public static void main(String[] args) { JFrame frame = new JFrame(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); JButton button = new JButton("Test"); button.addActionListener(e -> { throw new RuntimeException(); }); frame.add(button); frame.setSize(new Dimension(50, 50)); SwingUtilities.invokeLater(() -> frame.setVisible(true)); } } 

以下是它在Eclipse中的调试模式下的外观。

Eclipse处于调试模式