Previous | Next | Trail Map | Creating a User Interface (with Swing) | Using Components, the GUI Building Blocks

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.
public class 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.
 */
public class 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.
public class MyClass extends Applet {
    ...
	someObject.addMouseListener(new MyAdapter());
    ...
    class MyAdapter extends MouseAdapter {
        public void mouseClicked(MouseEvent e) {
	    ...//Event handler implementation goes here...
        }
    }
}
Here's another example of using an inner class:
//An example of using an anonymous inner class.
public class MyClass extends Applet {
    ...
	someObject.addMouseListener(new 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. To make a local variable available to an inner class, just save a copy of the variable as a final local variable.

Note: Some 1.1 compilers don't let an inner class use private instance variables of the enclosing class. A workaround is to remove the private specifier from the instance variable's declaration.

For more information about inner classes, see Implementing Nested Classes(in the Learning the Java Language trail).


Previous | Next | Trail Map | Creating a User Interface (with Swing) | Using Components, the GUI Building Blocks