如何捕获事件调度线程 (EDT) 异常? [英] How can I catch Event Dispatch Thread (EDT) exceptions?
问题描述
我正在使用一个名为 MyExceptionHandler
的类,它实现了 Thread.UncaughtExceptionHandler
来处理我项目中的正常异常.
I am using a class called MyExceptionHandler
that implements Thread.UncaughtExceptionHandler
to handle normal exceptions in my project.
据我所知,这个类无法捕获 EDT 异常,所以我尝试在 main()
方法中使用它来处理 EDT 异常:
As I understand this class can't catch the EDT exceptions, so I tried to use this in the main()
method to handle EDT exceptions:
public static void main( final String[] args ) {
Thread.setDefaultUncaughtExceptionHandler( new MyExceptionHandler() ); // Handle normal exceptions
System.setProperty( "sun.awt.exception.handler",MyExceptionHandler.class.getName()); // Handle EDT exceptions
SwingUtilities.invokeLater(new Runnable() { // Execute some code in the EDT.
public void run() {
JFrame myFrame = new JFrame();
myFrame.setVisible( true );
}
});
}
但直到现在它都不起作用.例如,在初始化 JFrame 时,我从构造函数中的包文件加载它的标签,如下所示:
But untill now it's not working. For example while initializing a JFrame I load its labels from a bundle file in the constructor like this:
setTitle( bundle.getString( "MyJFrame.title" ) );
我从包文件中删除了键 MyJFrame.title
以测试异常处理程序,但它不起作用!异常通常打印在日志中.
I deleted the key MyJFrame.title
from the bundle file to test the exception handler, but it didn't work! The exception was normally printed in the log.
我在这里做错了吗?
推荐答案
EDT 异常处理程序不使用 Thread.UncaughtExceptionHandler
.相反,它调用具有以下签名的方法:
The EDT exception handler doesn't use Thread.UncaughtExceptionHandler
. Instead, it calls a method with the following signature:
public void handle(Throwable thrown);
将其添加到 MyExceptionHandler
,它应该可以工作.
Add that to MyExceptionHandler
, and it should work.
相关的文档"可以在 EventDispatchThread
中找到,它是 java.awt
中的一个包私有类.从 handleException()
的 javadoc 中引用:
The "documentation" for this is found in EventDispatchThread
, which is a package-private class in java.awt
. Quoting from the javadoc for handleException()
there:
/**
* Handles an exception thrown in the event-dispatch thread.
*
* <p> If the system property "sun.awt.exception.handler" is defined, then
* when this method is invoked it will attempt to do the following:
*
* <ol>
* <li> Load the class named by the value of that property, using the
* current thread's context class loader,
* <li> Instantiate that class using its zero-argument constructor,
* <li> Find the resulting handler object's <tt>public void handle</tt>
* method, which should take a single argument of type
* <tt>Throwable</tt>, and
* <li> Invoke the handler's <tt>handle</tt> method, passing it the
* <tt>thrown</tt> argument that was passed to this method.
* </ol>
*
* If any of the first three steps fail then this method will return
* <tt>false</tt> and all following invocations of this method will return
* <tt>false</tt> immediately. An exception thrown by the handler object's
* <tt>handle</tt> will be caught, and will cause this method to return
* <tt>false</tt>. If the handler's <tt>handle</tt> method is successfully
* invoked, then this method will return <tt>true</tt>. This method will
* never throw any sort of exception.
*
* <p> <i>Note:</i> This method is a temporary hack to work around the
* absence of a real API that provides the ability to replace the
* event-dispatch thread. The magic "sun.awt.exception.handler" property
* <i>will be removed</i> in a future release.
*/
我不知道 Sun 是如何期望你找到这个的.
How exactly Sun expected you find this, I have no idea.
这是一个完整的示例,它在 EDT 上和下捕获异常:
Here's a complete example which catches exceptions both on and off the EDT:
import javax.swing.SwingUtilities;
public class Test {
public static class ExceptionHandler
implements Thread.UncaughtExceptionHandler {
public void handle(Throwable thrown) {
// for EDT exceptions
handleException(Thread.currentThread().getName(), thrown);
}
public void uncaughtException(Thread thread, Throwable thrown) {
// for other uncaught exceptions
handleException(thread.getName(), thrown);
}
protected void handleException(String tname, Throwable thrown) {
System.err.println("Exception on " + tname);
thrown.printStackTrace();
}
}
public static void main(String[] args) {
Thread.setDefaultUncaughtExceptionHandler(new ExceptionHandler());
System.setProperty("sun.awt.exception.handler",
ExceptionHandler.class.getName());
// cause an exception on the EDT
SwingUtilities.invokeLater(new Runnable() {
public void run() {
((Object) null).toString();
}
});
// cause an exception off the EDT
((Object) null).toString();
}
}
应该可以.
这篇关于如何捕获事件调度线程 (EDT) 异常?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!