Previous | Next | Trail Map | To 1.1 -- And Beyond! | GUI Changes: The AWT Grows Up


Using Adapters and Inner Classes to Handle AWT Events

This section tells you how to use adapters and inner classes to reduce clutter in your code. If you don't care about this subject, feel free to skip to the next section.

Most AWT listener interfaces, unlike ActionListener, contain more than one method. For example, the MouseListener interface contains five methods: mousePressed, mouseReleased, mouseEntered, mouseExited, and mouseClicked. Even if you care only about mouse clicks, if your class directly implements MouseListener, then you must implement all five MouseListener methods. Methods for those events you don't care about can have empty bodies. Here's an example:

//An example with cluttered but valid code.
MyClass implements MouseListener {
    ...
	someObject.addMouseListener(this);
    ...
    /* Empty method definition. */
    public void mousePressed(MouseEvent e) {
    }

    /* Empty method definition. */
    public void mouseReleased(MouseEvent e) {
    }

    /* Empty method definition. */
    public void mouseEntered(MouseEvent e) {
    }

    /* Empty method definition. */
    public void mouseExited(MouseEvent e) {
    }

    public void mouseClicked(MouseEvent e) {
	...//Event handler implementation goes here...
    }
}
Unfortunately, the resulting collection of empty method bodies can make code harder to read and maintain. To help you avoid cluttering your code with empty method bodies, the AWT provides an adapter class for each listener interface with more than one method. (Handling Standard AWT Events lists all the listeners and their adapters.) For example, the MouseAdapter class implements the MouseListener interface. An adapter class implements empty versions of all its interface's methods.

To use an adapter, you create a subclass of it, instead of directly implementing a listener interface. For example, by extending MouseAdapter, your class inherits empty definitions of all five of the methods that MouseListener contains.

/*
 * An example of extending an adapter class instead of
 * directly implementing a listener interface.
 */
MyClass extends MouseAdapter {
    ... 
	someObject.addMouseListener(this);
    ... 
    public void mouseClicked(MouseEvent e) {
	...//Event handler implementation goes here...
    }
}

What if you don't want your event-handling class to inherit from an adapter class? For example, suppose you write an applet, and you want your Applet subclass to contain some code to handle mouse events. Since the Java language doesn't permit multiple inheritance, your class can't extend both the Applet and MouseAdapter classes. The solution is to define an inner class -- a class inside of your Applet subclass -- that extends the MouseAdapter class,

//An example of using an inner class.
MyClass extends Applet {
    ...
	someObject.addMouseListener(new MyAdapter());
    ...
    class MyAdapter extends MouseAdapter {
        public void mouseClicked(MouseEvent e) {
	    ...//Event handler implementation goes here...
        }
    }
}
Inner classes work well even if your event handler needs access to private instance variables from the enclosing class. As long as you don't declare an inner class to be static, an inner class can refer to instance variables and methods just as if its code is in the containing class. [CHECK on how to phrase that!] [Give more help.]

You'll see inner classes used throughout this lesson. [List examples?] For more information about inner classes, see the Inner Classes Specification.


Previous | Next | Trail Map | To 1.1 -- And Beyond! | GUI Changes: The AWT Grows Up