如何捕获事件调度线程 (EDT) 异常? [英] How can I catch Event Dispatch Thread (EDT) exceptions?

查看:28
本文介绍了如何捕获事件调度线程 (EDT) 异常?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用一个名为 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆