Recipe 14.8 Catching and Formatting GUI Exceptions


Problem

Your application code is throwing an exception, and you want to catch it, but the GUI runs in a different Thread (see Chapter 24), so you can't.

Solution

There is an "undocumented feature" for doing this; you can use it for now, but expect the interface to change someday.

Discussion

This is one of the few cases in the book where I venture to document an unsupported feature, and only because Sun's unwillingness to formally document it has generated so much frustration for developers.

You can find out about this by reading the source code for AWT.

To specify an error handler, you must set the System Property (see Recipe 2.2) sun.awt.exception.handler to the full class name of your exception handler before you create any GUI components (the fact that this name begins with sun. rather than java. is your assurance that it is unsupported). The class you name must be on your CLASSPATH at runtime, must have a public, no-argument constructor, and must contain a method exactly matching the signature public void handle(Throwable t). If the named class can be found and loaded, the GUI exception dispatching mechanism calls the handle( ) method whenever an uncaught exception is received.

To display the caught exceptions, show each one in a dialog. My API class com.darwinsys.swingui.ErrorUtil contains both a handle( ) method as described and a more general method public static void showExceptions(Component parent, Throwable t). This method displays the Throwable (and, on 1.4 and later, any nested exceptions) in an error dialog. See the program ErrorUtilTest in the darwinsys/src/regress directory for an example of running this program directly, and see ErrorUtilCatchTest in the same directory for an example of using it with uncaught exceptions from the GUI thread as described. The command ant regress.gui in the darwinsys directory runs both.

In JDK 1.5, an easier method may be to use the new Thread method setDefaultUncaughtExceptionHandler( ) , whose signature is:

public static void setDefaultUncaughtExceptionHandler(Thread. UncaughtExceptionHandlereh);

The code in Example 14-4 shows a tiny demonstration of this technique.

Example 14-4. ThreadBasedCatcher.java
/**  * ThreadBasedCatcher - Demonstrate catching uncaught exceptions   * thrown in an unrelated Thread.  * @version $Id: ch14.xml,v 1.6 2004/05/07 15:20:56 ian Exp $  */ public class ThreadBasedCatcher extends JFrame{     public static void main(String[] args) {         new ThreadBasedCatcher( ).setVisible(true);     }     public ThreadBasedCatcher( ){         Container cp = getContentPane( );         JButton crasher = new JButton("Crash");         cp.add(crasher);         crasher.addActionListener(new ActionListener( ){             public void actionPerformed(ActionEvent e){                 throw new RuntimeException("You asked for it");             }         });         Thread.setDefaultUncaughtExceptionHandler(                 new Thread.UncaughtExceptionHandler( ){                     public void uncaughtException(Thread t, Throwable ex){                         System.out.println(                             "You crashed thread " + t.getName( ));                         System.out.println(                             "Exception was: " + ex.toString( ));                     }                 });         pack( );     } }

Figure 14-7 shows the program running; pushing the button produced this output.

Figure 14-7. ThreadBasedCatcher running
figs/jcb2_1407.gif


You crashed thread AWT-EventQueue-0 Exception was: java..lang.RuntimeException: You asked for it.



Java Cookbook
Java Cookbook, Second Edition
ISBN: 0596007019
EAN: 2147483647
Year: 2003
Pages: 409
Authors: Ian F Darwin

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net