When do I use adapter classes vs. interfaces in "new" expressions for event handling?

Scott Stanchfield

When you register an event handler, you must pass it an instance of some class that implements its listener interface.

Simple Event Handler

Start with a simple example. Suppose we want to print "Hello" when a button is pressed. Button fires an actionPerformed event when pressed, which is the only method in the ActionListener interface. We could write the following code to accomplish this task:

SayHello.java

import java.awt.*;
import java.awt.event.*;

public class SayHello implements ActionListener {
  public void actionPerformed(ActionEvent e) {
    System.out.println("Hello");
  }
}

 

SimpleGUI.java

import java.awt.*;

public class SimpleGUI {
  public static void main(String[] args) {
    Frame f = new Frame();
    Button b = new Button("Press me");
    b.addActionListener(new SayHello());
    f.add(b);
    f.setVisible(true);
    // application exit handler omitted
  }
}

Simple Anonymous Inner Class

It seems like a waste to create an entirely new class just to say "Hello". This uses up a class name in our namespace, and unique names can be difficult to create.

To help this, we create an anonymous inner class by writing the event handler class code in the call to register the event handler. The new test class looks as follows:

SimpleGUI2.java

import java.awt.*;
import java.awt.event.*;

public class SimpleGUI2 {
  public static void main(String[] args) {
    Frame f = new Frame();
    Button b = new Button("Press me");
    b.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        System.out.println("Hello");
      }});
    f.add(b);
    f.setVisible(true);
    // application exit handler omitted
  }
}

ActionListener is an interface! Whenever you see "new" followed by an interface name and a "{" (open curly brace), you're creating an anonymous inner class. You would read

new ActionListener() { ... }

as "Create a new instance of some class (we don't care what its name is) that implements ActionListener, and the details are in the curly braces."

This is a convenient shorthand for creating event handlers.

Event Adapters

Some event listener interfaces require several methods. For example, WindowListener requires seven methods. Normally, you only care about one of these methods, windowClosing. If we were to write an anonymous inner class to close an application, it might look as follows

Frame f = new Frame();
f.addWindowListener(new WindowListener() {
  public void windowClosing(WindowEvent e) {
    System.exit(0);
  }
  public void windowClosed(WindowEvent e) {}
  public void windowOpened(WindowEvent e) {}
  public void windowIconified(WindowEvent e) {}
  public void windowDeiconified(WindowEvent e) {}
  public void windowActivated(WindowEvent e) {}
  public void windowDeactivated(WindowEvent e) {}
});

All of those dummy methods are really a lot of noise. In java.awt.event, Sun defined a class called WindowAdapter that implements WindowListener with seven dummy methods. This means that you can extend WindowAdapter and you only need to override the classes you care about. The above code becomes:

Frame f = new Frame();
f.addWindowListener(new WindowAdapter() {
  public void windowClosing(WindowEvent e) {
    System.exit(0);
}});

You read the anonymous inner class above as "create an instance of some class (we don't care what its name is) that extends WindowAdapter, and the details are in the curly braces."

The full example for the button press and window close follows:

SimpleGUI3.java

import java.awt.*;
import java.awt.event.*;

public class SimpleGUI3 {
  public static void main(String[] args) {
    Frame f = new Frame();
    Button b = new Button("Press me");
    b.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        System.out.println("Hello");
      }});
    f.add(b);
    f.addWindowListener(new WindowAdapter() {
      public void windowClosing(WindowEvent e) {
        System.exit(0);
    }});
    f.setVisible(true);
    // application exit handler omitted
  }
}
Comment and Contribute

 

 

 

 

 


(Maximum characters: 1200). You have 1200 characters left.