h1

Catching all Runtime Exceptions in Swing

March 30, 2009

[note: see my post about writing a java thick client applications using extjs]

So you got some framework that you are using in your swing application and it throws a runtime exception. The Exception is thrown all the way out and ends up on the system.out – very nasty, not good looking and doesn’t help us determining that there is a problem in our application. We might just go on and do the same task again even though the exception was telling us that something went fatally wrong and that it probably would be a good idea to change the state of the application, go into recovery or terminate gracefully.

What can we do to prevent this? We can use try/catch clauses all over the place whenever we call some third party code but that is neither fun nor good code. And still there can be some exceptions slipping by – or are you really sure your code never throws a null pointer exception? Really?

There is an easier way to deal with this problem: All swing activity originates from the event queue and therefore all events are thrown to the event queue as well.  So in order to catch all runtime exceptions such as a null pointer exception we can just use the event queue.

We just need to extend EventQueue and overwrite the dispatchEvent method.

class EventQueueProxy extends EventQueue {

	protected void dispatchEvent(AWTEvent newEvent) {
		try {
			super.dispatchEvent(newEvent);
		} catch (Throwable t) {
			t.printStackTrace();
			String message = t.getMessage();

			if (message == null || message.length() == 0) {
				message = "Fatal: " + t.getClass();
			}

			JOptionPane.showMessageDialog(null, "General Error", message, JOptionPane.ERROR_MESSAGE);
		}
	}
}

The proxy class still calls it’s parents dispatchEvent method and catches anything throwable. When it does, it pops up a simple dialog.

Only thing remaining, we need to install our new event dispatcher on the event queue.

EventQueue queue = Toolkit.getDefaultToolkit().getSystemEventQueue();
queue.push(new EventQueueProxy());

Using this method one can also use exceptions to handle errors throughout a swing application – dealing with errors and exceptions ends up at one place in the application this way and can be used to transform the exceptions into human readable error messages.

For some other helpful links for building swing applications have a look at helpful-java-swing-articles

About these ads

12 comments

  1. Since Java 5, java.lang.Thread provides build in support for a global error handler: setDefaultUncaughtExceptionHandler


    • Thanks for the tip – although that extends to all thread, my approach only handles the swing event thread.


  2. Personally, I don’t see much of a point to limit error reporting to Swing events, but if one should need to support such a use case, I would rather refrain from messing with the event queue and filter the relevant events instead. Easy enough for the EDT.


  3. The setDefaultUncaughtExceptionHandler will only work if the thread die (thread abruptly terminates due to an uncaught exception). But EventQueue thread will never die unless the application ends. Therefore without special handling all uncaught exception will be swallow by EventQueue and go into system out silently.


  4. [...] has a post outlining how he believes you should catch Swing runtime exceptions . Basically he suggests to provide a wrapper around the event queue such that every event is [...]


  5. See this post from Hans Muller. He discusses the pros and cons of three different ways to catch exceptions on EDT: https://appframework.dev.java.net/servlets/ReadMsg?list=users&msgNo=1113


  6. That’s the only solution which worked for me. Thank you very much!


  7. Great article. Thanks !


  8. I just came across your post. Great solution, though I wonder if I still need to call setDefaultUncaughtExceptionHandler. Seems no, as long as your technique is instantiated right away. Thanks again!

    Fortunately, java swing is highly extendable. Unfortunately, just about everything has to be extended to be useful.


  9. Thanks for the article. That’s exactly what I was looking for…


  10. Thanks for the post. This is a great intro to EventQueue mechanism for Swing beginners. But just to be picky I think you got the message and tittle the other way around on JOptionPane.showMessageDialog :)


  11. If you use SwingUtilities.invokeXXX your task gets wrapped in a subclass to AWTEvent and this subclass will catch any exception and then it will be returned in an InvocationTargetException. If you want to have a common place to handle Swing exceptions you would have to extend the code to something like
    super.dispatchEvent(newEvent);
    if (newEvent instanceof InvocationEvent) {
    InvocationEvent event = (InvocationEvent) newEvent;
    Throwable t = event.getThrowable();
    if (t != null) {
    throw new InvocationTargetException(t);
    }
    }



Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 39 other followers

%d bloggers like this: