我正在开发一个Swing应用程序,其中包含一个执行自定义绘制的组件。当我在绘制代码中犯了一些错误并抛出异常时,情况很难调试。弹出窗口显示异常信息,而不是被调试器捕获。此外,the thread seems to be restarted,并且作为编码错误的结果的例外,它会一次又一次地显示。
当我很幸运地切换到调试器时(这很困难,因为越来越多的弹出窗口随着应用程序获取绘制请求而不断出现),调试控制台向我显示了一个异常信息,如:
严重:线程中抛出未捕获的异常[AWT-EventQueue-0,6,main]
.... stack跟随
我的应用程序是用Scala编写的,我使用的是IntelliJ IDEA 14.我的未被捕获的主线程异常由调试器处理得很好(我Uncaught exception
启用了Any exception
在Java Exception Breakpoints
中启用了断点但是,AWT线程中的异常不是。
我已尝试安装this How can I detect when an Exception's been thrown globally in Java? answer中描述的处理程序,但我的处理程序似乎没有被触发。
我想实现以下(按重要性顺序):
(注意:虽然这是Scala应用程序,但我认为Java的行为是相同的,因此是Java标记)。
答案 0 :(得分:9)
根据此link,您必须同时处理常规Exception
和EDT Exception
而不使用旧的sun.awt.exception.handler
黑客(自Java 7以来不再有效)< / p>
这是您的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());
}
});
答案 1 :(得分:0)
在Java中
你的问题是异常被抛出在另一个线程中,即事件调度线程。几个解决方案:
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()。
在Scala中
你的问题是异常被抛出在另一个线程中,即事件调度线程。几个解决方案:
Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
def uncaughtException(t: Thread, e: Throwable) {
logger.error("Uncaught exception in thread: " + t.getName, e)
}
})
在任何情况下,您原则上都应该使用
中的UI启动代码EventQueue.invokeLater()
答案 2 :(得分:0)
看起来您唯一的解决方案可能是切换到Eclipse。 :-)其他解决方案需要编码工作,并且在异常处理程序中停止与在抛出异常的确切位置停止不同。
使用以下程序,我在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中调试模式的外观。