Newsletter sign-up
View all newsletters

Enterprise Java Newsletter
Stay up to date on the latest tutorials and Java community news posted on JavaWorld

Replace 1.1 event adapters to build better apps

Sophisticated event adapters can replace JDK 1.1's adapters, improving your applications

  • Digg
  • Reddit
  • SlashDot
  • Stumble
  • del.icio.us
  • Technorati
  • dzone
T he event adapter classes introduced with JDK 1.1 are simple and lightweight, but they do not provide enough capability for medium or large Java applications. Their shortcomings are legion: too many problems go unreported to the user; GUI responsiveness is missing when actions take a long time to complete; and an application's error-handling policy cannot be changed easily. Given all this, what's a developer to do?

This article demonstrates how to address these issues by using sophisticated event adapter classes designed to improve on those provided with JDK 1.1.

The following applet demonstrates this article's sophisticated adapters in action. The top row of the applet uses the sophisticated adapters, with the result that various errors are caught and the user is notified. The Long Asynch Action button shows the asynchronous behavior in action; notice that the GUI is not hung while it sleeps.

The bottom row uses standard adapters; note that the errors detected by the top components go undetected. The Long AWT-Blocking Action button shows the GUI hung.

You need a JDK 1.1-enabled browser to see this applet.

Note: Not all browsers have complete JDK 1.1 support. If the applet does not appear in a pop-up window in the upper left-hand corner of your browser window, you will need to download the applet. To do so, just click on this handy zip file.

Adapter classes in JDK 1.1 -- benefits and limitations

First, let's look at the simple event adapters you get with the JDK 1.1. They aren't very complicated because each method in each JDK 1.1 adapter does absolutely nothing. There is no ActionAdapter class for the simple ActionListener interface, but if an ActionAdapter class existed, it would look like this:

    public class ActionAdapter implements ActionListener
    {
        public void actionPerformed (ActionEvent e)
        {
        }
    }


The other adapter classes provided by the JDK are larger, but no more complicated. These simple adapters do have good features:

  • They are very lightweight.
  • Their "do nothing" methods are as efficient as possible.
  • They do not enforce a specific policy on programs. Since any policy is likely to be wrong for some programs, this safe decision allows different programs to implement different policies. In fact, this article's adapters might have been more difficult to write had the JDK-provided adapters been more complex than they are.
  • They ship with the Java runtime environment, so applets don't need to download them.


Unfortunately, the JDK 1.1-provided adapters also have four major limitations.

Limitation 1: The JDK 1.1 adapters do not catch RuntimeExceptions

Quick, answer this: Can this method throw any exceptions?

    public void niftyMethod ()   // Note: no throws clause!
    {
        // Do stuff.
    }


In fact, it can. The Java language defines an entire class hierarchy of Exception objects that can be thrown even without a throws XXXException clause. These exceptions descend from a base class named java.lang.RuntimeException. Examples include IndexOutOfBoundsException and NullPointerException.

A RuntimeException usually indicates that there is a bug in the program; it may be trying to use a null reference or indexing off the end of an array. Nevertheless, the standard adapters allow programming errors like this to go undetected by the program and unreported to the user of the program. The practical result is that programs can fail silently, preventing the user from discovering the problem until it's too late.

The following sequence illustrates this scenario:

            User: "Please save my work."
    Java Program: Hmmm. There's a null pointer exception so I can't save
                  the work ... but it isn't caught, so I don't need
                  to tell the user.
                  "OK!"
            User: "Exit."
    Java Program: "Bye!"
            User: "Hey, where's my file?!?"


Well-behaved programs should never fail silently. A better exchange would look something like this:

            User: "Please save my work."
    Java Program: Hmm. There's a null pointer exception so I can't save
                  the work. Ah, I'll report it.
                  "I can't save your work because I got a null pointer
                  exception!"
            User: "What the heck is a null pointer?  Well, just to be
                  safe, I think I'll save this to the clipboard and
                  dump it in a text file ..."


The user might still lose some information (formatting, in this example) but this is better than losing everything.

Limitation 2: The JDK 1.1 adapters do not catch Errors

Next question: Can anything be thrown from the following improved function?

    public void niftyMethodTwo ()
    {
        try
        {
            // Do stuff.
        }
        catch (Exception e)    // Note: We are catching all exceptions!
        {
            // Panic.
        }        
    }


Again, the question has an affirmative answer. The Java language defines an entire category of failures, called Errors, that are not exceptions. Errors usually indicate that something has gone wrong with the underlying virtual machine or with the program itself. Examples include OutOfMemoryError and StackOverflowError.

As with runtime exceptions, errors should not happen during program execution. Again, however, if they do happen, the user should receive notification. The following exchange illustrates the problem resulting from not dealing with Errors:

            User: "Please save my work."
    Java Program: Hmm. I'm out of memory so I can't save the work, 
                  but errors aren't caught so I don't need to tell
                  the user.
                  "OK!"
            User: "Exit."
    Java Program: "Bye!"
            User: "Did I lose my file again?!?"


Again, if users receive notification of the problem, they can at least try to recover their work:

            User: "Please save my work."
    Java Program: Hmm. I'm out of memory so I can't save
                  the work. Ah, I'll report it.
                  "I can't because I'm out of memory!"
            User: "Darn. Close these other files."
    Java Program: "OK."
            User: "Now please save my work."
    Java Program: Hmm, everything worked that time.
                  "OK!"
            User: "That worked well. I'm going to start a fan
                  club for the programmers who wrote this program."


To reiterate, well-behaved programs should not fail silently.

Limitation 3: The JDK adapters run on the AWT thread

All the methods in the default adapters run on the AWT thread. Both the AWT and Swing are single-threaded, so the entire GUI freezes while an action executes. Even the application's other frames will not respond to new GUI events while the application handles a prior event. Indeed, if the action runs for very long, the application can appear to be hung.

  • Digg
  • Reddit
  • SlashDot
  • Stumble
  • del.icio.us
  • Technorati
  • dzone
Comment
Login
Forgot your account info?
Add comment
Anonymous comments subject to approval. Register here for member benefits.
Have a JavaWorld account? Log in here. Register now for a free account.
Resources