在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? 回答 ,但我的处理程序似乎没有被触发。
我想实现以下(按重要性顺序):
- 避免AWT线程在exception时重新启动,或者至少阻止弹出窗口显示
- 在调试器中处理未捕获的exception,而不是在控制台中打印
(注意:虽然这是Scala应用程序,但我认为Java的行为是相同的,因此Java标记)。
根据此链接 ,您必须处理常规Exception
和EDT 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中的调试模式下的外观。