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

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

问题描述

我正在使用一个名为 MyExceptionHandler 的类实现 Thread.UncaughtExceptionHandler 来处理我的项目中的正常异常。 / p>

据了解,这个类不能捕获EDT异常,所以我试图在 main()方法来处理EDT异常:

  public static void main(final String [] args){
Thread.setDefaultUncaughtExceptionHandler (new MyExceptionHandler()); //处理正常的异常
System.setProperty(sun.awt.exception.handler,MyExceptionHandler.class.getName()); //处理EDT异常
SwingUtilities.invokeLater(new Runnable(){//在EDT中执行一些代码
public void run(){
JFrame myFrame = new JFrame();
myFrame.setVisible(true);
}
});
}

但直到现在它不工作。例如,在初始化JFrame时,我从构造函数中的bundle文件中加载它的标签,如下所示:

  setTitle(bundle.getString( MyJFrame.title)); 

我删除了密钥 MyJFrame.title 该bundle文件来测试异常处理程序,但它没有工作!



我在这里做错了吗?

解决方案

EDT异常处理程序不使用 Thread.UncaughtExceptionHandler 。相反,它调用一个具有以下签名的方法:

  public void handle(Throwable throwwn); 

将其添加到 MyExceptionHandler ,它应该



文档在 EventDispatchThread 中找到,这是一个包私有类, code> java.awt中。引用来自 handleException()的javadoc:

  / ** 
*处理事件发送线程中抛出的异常。
*
*< p>如果系统属性sun.awt.exception.handler被定义,那么当调用此方法时,
*将尝试执行以下操作:
*
*< ol>
*< li>使用
*当前线程的上下文类加载器
*< li>加载由该属性的值命名的类使用其零参数构造函数
*< li>实例化该类找到结果处理程序对象的< tt> public void handle< / tt>
*方法,它应该采用
*< tt> Throwable< / tt>和
*< li>的单个参数。调用处理程序的< tt>句柄< / tt>方法,传递
*< tt>抛出< / tt>传递给这个方法的参数。
*< / ol>
*
*如果前三个步骤中的任何一个失败,则此方法将返回
*< tt> false< / tt>并且此方法的所有以下调用将返回
*< tt> false< / tt>立即。处理程序对象的
*< tt> handle< / tt>抛出的异常将被捕获​​,并将导致此方法返回
*< tt> false< / tt> ;.如果处理程序的< tt>句柄< / tt>方法成功调用
*,那么这个方法将返回< tt> true< / tt> ;.这个方法将
*不会抛出任何异常。
*
*< p> < I>注意:< I> /;这种方法是一个临时的黑客,可以解决
*缺少真正的API,提供替换
*事件调度线程的能力。魔术sun.awt.exception.handler属性
*< i>将被删除< / i>在将来的版本中。
* /

Sun希望如何找到这个,我不知道。 p>

这是一个完整的例子,它捕获了EDT和EDT之间的异常:

  import javax.swing.SwingUtilities; 

public class Test {
public static class ExceptionHandler
implements Thread.UncaughtExceptionHandler {

public void handle(Throwable throwwn){
/ / for EDT exception
handleException(Thread.currentThread()。getName(),throwwn);
}

public void uncaughtException(Thread thread,Throwable throwwn){
// for other uncaught exceptions
handleException(thread.getName(),throwwn);
}

protected void handleException(String tname,Throwable throwwn){
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());

//在EDT上引发异常
SwingUtilities.invokeLater(new Runnable(){
public void run(){
((Object)null)。 toString();
}
});

//导致EDT
((Object)null)的异常.toString();
}
}

应该这样做。


I am using a class called MyExceptionHandler that implements Thread.UncaughtExceptionHandler to handle normal exceptions in my project.

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 );
        }
    });
}

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" ) );

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.

Am I doing something wrong here?

解决方案

The EDT exception handler doesn't use Thread.UncaughtExceptionHandler. Instead, it calls a method with the following signature:

public void handle(Throwable thrown);

Add that to MyExceptionHandler, and it should work.

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.
 */

How exactly Sun expected you find this, I have no idea.

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();
  }
}

That should do it.

这篇关于如何捕获事件调度线程(EDT)异常?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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