1.9 Writing Event Listeners

«« Previous
Next »»

1. Introduction to Event Listeners


If you have read any of the component how-to pages, you probably already know the basics of event listeners.

Let us look at one of the simplest event handling examples possible. It is called Beeper, and it features a button that beeps when you click it.

Click the Launch button to run Beeper using Java™ Web Start (download JDK 7 or later). Alternatively, to compile and run the example yourself, consult the example index.

Oracle Java Certifications, Oracle Java Guides, Oracle Java Tutorials and Materials

You can find the entire program in Beeper.java. Here is the code that implements the event handling for the button:

public class Beeper ... implements ActionListener {
    ...
    //where initialization occurs:
        button.addActionListener(this);
    ...
    public void actionPerformed(ActionEvent e) {
        ...//Make a beep sound...
    }
}

The Beeper class implements the ActionListener interface, which contains one method: actionPerformed. Since Beeper implements ActionListener, a Beeper object can register as a listener for the action events that buttons fire. Once the Beeper has been registered using the Button addActionListener method, the Beeper's actionPerformed method is called every time the button is clicked.

A More Complex Example

The event model, which you saw at its simplest in the preceding example, is quite powerful and flexible. Any number of event listener objects can listen for all kinds of events from any number of event source objects. For example, a program might create one listener per event source. Or a program might have a single listener for all events from all sources. A program can even have more than one listener for a single kind of event from a single event source.

Oracle Java Certifications, Oracle Java Guides, Oracle Java Tutorials and Materials

Multiple listeners can register to be notified of events of a particular type from a particular source. Also, the same listener can listen to notifications from different objects.

Each event is represented by an object that gives information about the event and identifies the event source. Event sources are often components or models, but other kinds of objects can also be event sources.

Whenever you want to detect events from a particular component, first check the how-to section for that component. A list of the component how-to sections is here. The how-to sections give examples of handling the events that you are most likely to care about. In How to Use Color Choosers, for instance, you will find an example of writing a change listener to track when the color changes in the color chooser.

The following example demonstrates that event listeners can be registered on multiple objects and that the same event can be sent to multiple listeners. The example contains two event sources (JButton instances) and two event listeners. One of the event listeners (an instance of a class called MultiListener) listens for events from both buttons. When it receives an event, it adds the event's "action command" (which is set to the text on the button's label) to the top text area. The second event listener (an instance of a class called Eavesdropper) listens for events on only one of the buttons. When it receives an event, it adds the action command to the bottom text area.

Oracle Java Certifications, Oracle Java Guides, Oracle Java Tutorials and Materials

You can find the entire program in MultiListener.java. Here is the code that implements the event handling for the button:

public class MultiListener ... implements ActionListener {
    ...
    //where initialization occurs:
        button1.addActionListener(this);
        button2.addActionListener(this);

        button2.addActionListener(new Eavesdropper(bottomTextArea));
    }

    public void actionPerformed(ActionEvent e) {
        topTextArea.append(e.getActionCommand() + newline);
    }
}

class Eavesdropper implements ActionListener {
    ...
    public void actionPerformed(ActionEvent e) {
        myTextArea.append(e.getActionCommand() + newline);
    }
}

In the above code, both MultiListener and Eavesdropper implement the ActionListener interface and register as action listeners using the JButton addActionListener method. Both classes' implementations of the actionPerformed method are similar: they simply add the event's action command to a text area.

2. General Information about Writing Event Listeners


This section discusses several design considerations to keep in mind when implementing event handlers in your application. We then introduce you to event objects small objects that describe each event. In particular, we talk about EventObject, the superclass for all AWT and Swing events. Next, we introduce the concepts of low-level events and semantic events, recommending that you prefer semantic events when possible. The remainder of this section discusses implementation techniques you might use in some event listeners or see in event listeners created by other people or by GUI builders.

◉ Design Considerations

The most important rule to keep in mind about event listeners is that they should execute very quickly. Because all drawing and event-listening methods are executed in the same thread, a slow event-listener method can make the program seem unresponsive and slow to repaint itself. If you need to perform some lengthy operation as the result of an event, do it by starting up another thread (or somehow sending a request to another thread) to perform the operation.

You have many choices on how to implement an event listener. We can not recommend a specific approach because one solution would not suit all situations. However, we can give you some hints and show you some techniques that you might see, even if you do not use the same solution in your program.

For example, you might choose to implement separate classes for different kinds of event listeners. This can be an easy architecture to maintain, but many classes can also mean reduced performance.

When designing your program, you might want to implement your event listeners in a class that is not public, but somewhere more hidden. A private implementation is a more secure implementation.

If you have a very specific kind of simple event listener, you might be able to avoid creating a class at all by using the EventHandler class.

◉ Getting Event Information: Event Objects

Every event-listener method has a single argument an object that inherits from the EventObject class. Although the argument always descends from EventObject, its type is generally specified more precisely. For example, the argument for methods that handle mouse events is an instance of MouseEvent, where MouseEvent is an indirect subclass of EventObject.

The EventObject class defines one very useful method:

Object getSource()
Returns the object that fired the event.

Note that the getSource method returns an Object. Event classes sometimes define methods similar to getSource, but that have more restricted return types. For example, the ComponentEvent class defines a getComponent method that just like getSource returns the object that fired the event. The difference is that getComponent always returns a Component. Each how-to page for event listeners mentions whether you should use getSource or another method to get the event source.

Often, an event class defines methods that return information about the event. For example, you can query a MouseEvent object for information about where the event occurred, how many clicks the user made, which modifier keys were pressed, and so on.

◉ Concepts: Low-Level Events and Semantic Events

Events can be divided into two groups: low-level events and semantic events. Low-level events represent window-system occurrences or low-level input. Everything else is a semantic event.

Examples of low-level events include mouse and key events both of which result directly from user input. Examples of semantic events include action and item events. A semantic event might be triggered by user input; for example, a button customarily fires an action event when the user clicks it, and a text field fires an action event when the user presses Enter. However, some semantic events are not triggered by low-level events, at all. For example, a table-model event might be fired when a table model receives new data from a database.

Whenever possible, you should listen for semantic events rather than low-level events. That way, you can make your code as robust and portable as possible. For example, listening for action events on buttons, rather than mouse events, means that the button will react appropriately when the user tries to activate the button using a keyboard alternative or a look-and-feel-specific gesture. When dealing with a compound component such as a combo box, it is imperative that you stick to semantic events, since you have no reliable way of registering listeners on all the look-and-feel-specific components that might be used to form the compound component.

◉ Event Adapters

Some listener interfaces 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 do not care about can have empty bodies. Here is an example:

//An example that implements a listener interface directly.
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 listener implementation goes here...
    }
}

The resulting collection of empty method bodies can make code harder to read and maintain. To help you avoid implementing empty method bodies, the API generally includes an adapter class for each listener interface with more than one method. (The Listener API Table 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 and override only the methods of interest, rather than directly implementing all methods of the listener interface. Here is an example of modifying the preceding code to extend MouseAdapter. By extending MouseAdapter, it 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 listener implementation goes here...
    }
}

◉ Inner Classes and Anonymous Inner Classes

What if you want to use an adapter class, but do not want your public 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 does not permit multiple inheritance, your class cannot extend both the Applet and MouseAdapter classes. A solution is to define an inner class a class inside of your Applet subclass that extends the MouseAdapter class.

Inner classes can also be useful for event listeners that implement one or more interfaces directly.

//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 listener implementation goes here...
        }
    }
}

Performance note:  When considering whether to use an inner class, keep in mind that application startup time and memory footprint are typically directly proportional to the number of classes you load. The more classes you create, the longer your program takes to start up and the more memory it will take. As an application developer you have to balance this with other design constraints you may have. We are not suggesting you turn your application into a single monolithic class in hopes of cutting down startup time and memory footprint this would lead to unnecessary headaches and maintenance burdens.

You can create an inner class without specifying a name this is known as an anonymous inner class. While it might look strange at first glance, anonymous inner classes can make your code easier to read because the class is defined where it is referenced. However, you need to weigh the convenience against possible performance implications of increasing the number of classes.

Here is an example of using an anonymous 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 listener implementation goes here...
            }
        });
    ...
    }
}

Inner classes work even if your event listener needs access to private instance variables from the enclosing class. As long as you do not 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.

To refer to the enclosing instance, you can use EnclosingClass.this.

◉ The EventHandler Class

An EventHandler class supports dynamic generation of simple, one-statement event listeners. Although EventHandler is only useful for a certain type of extremely simple event listeners, it is worth mentioning for two reasons. It is useful for:

◉ Making an event listener that persistence can see and yet does not clog up your own classes with event listener interfaces and methods.
◉ Not adding to the number of classes defined in an application this can help performance.

Creating an EventHandler by hand is difficult. An EventHandler must be carefully constructed. If you make a mistake, you would not be notified at compile time it will throw an obscure exception at runtime. For this reason, EventHandlers are best created by a GUI builder. EventHandlers should be carefully documented. Otherwise you run the risk of producing hard-to-read code.

The EventHandler class is intended to be used by interactive tools, such as application builders, that allow developers to make connections between beans. Typically connections are made from a user interface bean (the event source) to an application logic bean (the target). The most effective connections of this kind isolate the application logic from the user interface. For example, the EventHandler for a connection from a JCheckBox to a method that accepts a boolean value can deal with extracting the state of the check box and passing it directly to the method so that the method is isolated from the user interface layer.

Inner classes are another, more general way to handle events from user interfaces. The EventHandler class handles only a subset of what is possible using inner classes. However, EventHandler works better with the long-term persistence scheme than inner classes. Also, using EventHandler in large applications in which the same interface is implemented many times can reduce the disk and memory footprint of the application.

Examples of Using EventHandler The simplest use of EventHandler is to install a listener that calls a method on the target object with no arguments. In the following example we create an ActionListener that invokes the toFront method on an instance of javax.swing.JFrame.

    myButton.addActionListener(
        (ActionListener)EventHandler.create(ActionListener.class, frame, "toFront"));

When myButton is pressed, the statement frame.toFront() will be executed. One could get the same effect, with some additional compile-time type safety, by defining a new implementation of the ActionListener interface and adding an instance of it to the button:

    //Equivalent code using an inner class instead of EventHandler.
    myButton.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            frame.toFront();
        }
    });

The next simplest use of EventHandler is to extract a property value from the first argument of the method in the listener interface (typically an event object) and use it to set the value of a property in the target object. In the following example we create an ActionListener that sets the nextFocusableComponent property of the target (myButton) object to the value of the "source" property of the event.

    EventHandler.create(ActionListener.class, myButton, "nextFocusableComponent", "source")

This would correspond to the following inner class implementation:

    //Equivalent code using an inner class instead of EventHandler.
    new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            myButton.setNextFocusableComponent((Component)e.getSource()); 
        }
    }

It is also possible to create an EventHandler that just passes the incoming event object to the target's action. If the fourth EventHandler.create argument is an empty string, then the event is just passed along:

    EventHandler.create(ActionListener.class, target, "doActionEvent", "")

This would correspond to the following inner class implementation:

    //Equivalent code using an inner class instead of EventHandler.
    new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            target.doActionEvent(e);
        }
    }

Probably the most common use of EventHandler is to extract a property value from the source of the event object and set this value as the value of a property of the target object. In the following example we create an ActionListener that sets the "label" property of the target object to the value of the "text" property of the source (the value of the "source" property) of the event.

    EventHandler.create(ActionListener.class, myButton, "label", "source.text")

This would correspond to the following inner class implementation:

    //Equivalent code using an inner class instead of EventHandler.
    new ActionListener {
        public void actionPerformed(ActionEvent e) {
            myButton.setLabel(((JTextField)e.getSource()).getText()); 
        }
    }

3. Listeners Supported by Swing Components


You can tell what kinds of events a component can fire by looking at the kinds of event listeners you can register on it. For example, the JComboBox class defines these listener registration methods:

◈ addActionListener
◈ addItemListener
◈ addPopupMenuListener

Thus, a combo box supports action, item, and popup menu listeners in addition to the listener methods it inherits from JComponent.

Listeners supported by Swing components fall into two categories:

1. Listeners that All Swing Components Support

Because all Swing components descend from the AWT Component class, you can register the following listeners on any Swing component:
  • component listener
    • Listens for changes in the component's size, position, or visibility.
  • focus listener
    • Listens for whether the component gained or lost the keyboard focus.
  • key listener
    • Listens for key presses; key events are fired only by the component that has the current keyboard focus.
  • mouse listener
    • Listens for mouse clicks, mouse presses, mouse releases and mouse movement into or out of the component's drawing area.
  • mouse-motion listener
    • Listens for changes in the mouse cursor's position over the component.
  • mouse-wheel listener
    • Listens for mouse wheel movement over the component.
  • Hierarchy Listener
    • Listens for changes to a component's containment hierarchy of changed events.
  • Hierarchy Bounds Listener
    • Listens for changes to a component's containment hierarchy of moved and resized events.
All Swing components descend from the AWT Container class, but many of them are not used as containers. So, technically speaking, any Swing component can fire container events, which notify listeners that a component has been added to or removed from the container. Realistically speaking, however, only containers (such as panels and frames) and compound components (such as combo boxes) typically fire container events.

JComponent provides support for three more listener types. You can register an ancestor listener to be notified when a component's containment ancestors are added to or removed from a container, hidden, made visible, or moved. This listener type is an implementation detail which predated hierarchy listeners.

The other two listener types are part of the Swing components' conformance to the JavaBeans specification. Among other things, this means that Swing components support bound and constrained properties and notify listeners of changes to the properties. Property change listeners listen for changes to bound properties and are used by several Swing components, such as formatted text fields, to track changes on a component's bound properties. Also, property change listeners, as well as vetoable change listeners are used by builder tools to listen for changes on constrained properties. For more information refer to the Properties lesson in the JavaBeans trail.

4. Implementing Listeners for Commonly Handled Events


The following sections give details about implementing specific kinds of event listeners. We do not have a how-to section for every single kind of event listener that you can write. Rather, we cover the listeners we think you are most likely to need. If you are interested in other listeners, you can find some information in the Listener API Table.

4.1 How to Write an Action Listener


Action listeners are probably the easiest — and most common — event handlers to implement. You implement an action listener to define what should be done when an user performs certain operation.

An action event occurs, whenever an action is performed by the user. Examples: When the user clicks a button, chooses a menu item, presses Enter in a text field. The result is that an actionPerformed message is sent to all action listeners that are registered on the relevant component.

To write an Action Listener, follow the steps given below:

1. Declare an event handler class and specify that the class either implements an ActionListener interface or extends a class that implements an ActionListener interface. For example:

public class MyClass implements ActionListener { 

2. Register an instance of the event handler class as a listener on one or more components. For example:

someComponent.addActionListener(instanceOfMyClass);

3. Include code that implements the methods in listener interface. For example:

public void actionPerformed(ActionEvent e) { 
    ...//code that reacts to the action... 
}

In general, to detect when the user clicks an onscreen button (or does the keyboard equivalent), a program must have an object that implements the ActionListener interface. The program must register this object as an action listener on the button (the event source), using the addActionListener method. When the user clicks the onscreen button, the button fires an action event. This results in the invocation of the action listener's actionPerformed method (the only method in the ActionListener interface). The single argument to the method is an ActionEvent object that gives information about the event and its source.

Let us write a simple program which displays how many number of times a button is clicked by the user. First, here is the code that sets up the TextField , button and numClicks variable:

public class AL extends Frame implements WindowListener,ActionListener {
TextField text = new TextField(20);
Button b;
private int numClicks = 0;

In the above example, the event handler class is AL which implements ActionListener.

We would like to handle the button-click event, so we add an action listener to the button b as below:

b = new Button("Click me");
b.addActionListener(this); 

In the above code, Button b is a component upon which an instance of event handler class AL is registered.

Now, we want to display the text as to how many number of times a user clicked button. We can do this by writing the code as below:

public void actionPerformed(ActionEvent e) {
         numClicks++;
         text.setText("Button Clicked " + numClicks + " times");

Now, when the user clicks the Button b, the button fires an action event which invokes the action listener's actionPerformed method. Each time the user presses the button, numClicks variable is appended and the message is displayed in the text field.

Here is the complete program(AL.java):

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

public class AL extends Frame implements WindowListener,ActionListener {
        TextField text = new TextField(20);
        Button b;
        private int numClicks = 0;

        public static void main(String[] args) {
                AL myWindow = new AL("My first window");
                myWindow.setSize(350,100);
                myWindow.setVisible(true);
        }

        public AL(String title) {

                super(title);
                setLayout(new FlowLayout());
                addWindowListener(this);
                b = new Button("Click me");
                add(b);
                add(text);
                b.addActionListener(this);
        }

        public void actionPerformed(ActionEvent e) {
                numClicks++;
                text.setText("Button Clicked " + numClicks + " times");
        }

        public void windowClosing(WindowEvent e) {
                dispose();
                System.exit(0);
        }

        public void windowOpened(WindowEvent e) {}
        public void windowActivated(WindowEvent e) {}
        public void windowIconified(WindowEvent e) {}
        public void windowDeiconified(WindowEvent e) {}
        public void windowDeactivated(WindowEvent e) {}
        public void windowClosed(WindowEvent e) {}

}

The Action Listener API

The ActionListener Interface

Because ActionListener has only one method, it has no corresponding adapter class.

Method Purpose
actionPerformed(actionEvent) Called just after the user performs an action.

The ActionEvent Class

Method Purpose
String getActionCommand() Returns the string associated with this action. Most objects that can fire action events support a method called setActionCommand that lets you set this string.
int getModifiers() Returns an integer representing the modifier keys the user was pressing when the action event occurred. You can use the ActionEvent-defined constants SHIFT_MASK, CTRL_MASK, META_MASK, and ALT_MASK to determine which keys were pressed. For example, if the user Shift-selects a menu item, then the following expression is nonzero:
actionEvent.getModifiers() & ActionEvent.SHIFT_MASK
Object getSource()
(in java.util.EventObject)
Returns the object that fired the event.

Examples that Use Action Listeners

The following table lists some of the many examples that use action listeners.

Example Where Described Notes
Beeper This section and Introduction to Event Listeners Contains one button with one action listener that beeps when you click the button.
MultiListener Introduction to Event Listeners Registers two different action listeners on one button. Also registers the same action listener on two different buttons.
RadioButtonDemo How to Use Radio Buttons Registers the same action listener on five radio buttons. The listener uses the getActionCommand method to determine which radio button fired the event.
MenuDemo How to Use Menus Shows how to listen for action events on menu items.
TextDemo  How to Use Text Fields An applet that registers an action listener on a text field.
IconDemo  How to Use Icons  Loads an image in an action listener. Because loading an image can take a while, this program uses a SwingWorker to load the image in a background thread.
TableDialogEditDemo How to Use Tables Registers an action listener through a factory method on the OK button of a color chooser dialog.
SliderDemo How to Use Sliders Registers an action listener on a timer that controls an animation loop.

4.2 How to Write a Caret Listener


Caret events occur when the caret — the cursor indicating the insertion point — in a text component moves or when the selection in a text component changes. The text component's document can initiate caret events when it inserts or removes text, for example. You can attach a caret listener to an instance of any JTextComponent subclass with the addCaretListener method.

Note: An alternate way of detecting caret changes is to attach a listener directly to the caret object itself rather than to the text component that manages the caret. A caret fires change events (not caret events), so you would need to write a change listener rather than a caret listener.
Here is the caret event handling code from an application called TextComponentDemo:

...
//where initialization occurs
CaretListenerLabel caretListenerLabel =
    new CaretListenerLabel("Caret Status");
...
textPane.addCaretListener(caretListenerLabel);
...
protected class CaretListenerLabel extends JLabel
                                   implements CaretListener
{
    ...
    //Might not be invoked from the event dispatching thread.
    public void caretUpdate(CaretEvent e) {
        displaySelectionInfo(e.getDot(), e.getMark());
    }

    //This method can be invoked from any thread.  It 
    //invokes the setText and modelToView methods, which 
    //must run in the event dispatching thread. We use
    //invokeLater to schedule the code for execution
    //in the event dispatching thread.
    protected void displaySelectionInfo(final int dot,
                                        final int mark) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                if (dot == mark) {  // no selection
                    ...
                }
            });
        }
    }
}

Note: The caretUpdate method is not guaranteed to be called in the event-dispatching thread. To use any methods inside of caretUpdate that update the GUI special handling is required to ensure they are executed on the event-dispatching thread. You can do this by wrapping the code inside a Runnable and calling SwingUtilities.invokeLater on that Runnable.

You can find a link to the source file for TextComponentDemo in the example index for using Swing Components. 

The Caret Listener API

The CaretListener Interface

Because CaretListener has only one method, it has no corresponding adapter class.

Method Purpose
caretUpdate(CaretEvent) Called when the caret in the listened-to component moves or when the selection in the listened-to component changes.

The CaretEvent Class

Method Purpose
int getDot() Returns the current location of the caret. If text is selected, the caret marks one end of the selection.
int getMark() Returns the other end of the selection. If nothing is selected, the value returned by this method is equal to the value returned by getDot. Note that the dot is not guaranteed to be less than the mark.
Object getSource()
(in java.util.EventObject)
Returns the object that fired the event.

Examples that Use Caret Listeners

The following table lists the examples that use caret listeners.

Example: TextComponentDemo
Where Described: Listening for Caret and Selection Changes
Notes: Listening for Caret and Selection Changes

4.3 How to Write a Change Listener


A change listener is similar to a property change listener. A change listener is registered on an object — typically a component, but it could be another object, like a model — and the listener is notified when the object has changed. The big difference from a property change listener is that a change listener is not notified of what has changed, but simply that the source object has changed. Therefore, a change listener is most useful when it is only necessary to know when an object has changed in any way.

Several Swing components (including JTabbedPane, JViewPort) rely on change events for basic functionality — sliders, color choosers and spinners. To learn when the value in a slider changes, you need to register a change listener. Similarly, you need to register a change listener on a color chooser to be informed when the user chooses a new color. You register a change listener on a spinner, to be notified when the spinner's value changes.

Here is an example of change event handling code for a slider:

//...where initialization occurs:
framesPerSecond.addChangeListener(new SliderListener());
...
class SliderListener implements ChangeListener {
    public void stateChanged(ChangeEvent e) {
        JSlider source = (JSlider)e.getSource();
        if (!source.getValueIsAdjusting()) {
            int fps = (int)source.getValue();
            ...
        }    
    }
}

You can find the source file for SliderDemo in the example index for Using Swing Components.

The Change Listener API

The ChangeListener Interface

Because ChangeListener has only one method, it has no corresponding adapter class.

Method Purpose
stateChanged(ChangeEvent) Called when the listened-to component changes state.

The ChangeEvent Class

Method Purpose
Object getSource()
(in java.util.EventObject
Returns the object that fired the event.

Examples that Use Change Listeners

The following table lists the examples that use change listeners.

Example Where Described Notes 
SliderDemo and
SliderDemo2
How to Use Sliders Registers a change listener on a slider that controls animation speed. The change listener ignores the change events until the user releases the slider.
ColorChooserDemo and
ColorChooserDemo2
How to Use Color Choosers Uses a change listener on the selection model of a color chooser to learn when the user changes the current color.
SpinnerDemo3 Detecting Spinner Value Changes in How to Use Spinners. Uses a change listener on a date-field spinner to change the color of the text as the spinner's date changes.
SpinnerDemo4 Detecting Spinner Value Changes in How to Use Spinners. Uses a change listener on a spinner to cycle through the gray scale as the spinner's value changes.
ConverterRangeModel
and its subclass,
FollowerRangeModel
How to Use Models Implement custom models for the sliders used in the Converter demo. Both models explicitly fire change events when necessary.

4.4 How to Write a Component Listener


The Component listener is a listener interface for receiving component events. A component is an object having a graphical representation that can be displayed on the screen and that can interact with the user. Some of the examples of components are the buttons, checkboxes, and scrollbars of a typical graphical user interface.

The class that is interested in processing a component event either implements this interface and all the methods it contains, or extends the abstract ComponentAdapter class overriding only the methods of interest. The listener object created from that class is then registered with a component using the component's addComponentListener method. When the component's size, location, or visibility changes, the relevant method in the listener object is invoked, and the ComponentEvent is passed to it.

One or more component events are fired by a Component object just after the component is hidden, made visible, moved, or resized.

The component-hidden and component-shown events occur only as the result of calls to a Component 's setVisible method. For example, a window might be miniaturized into an icon (iconified) without a component-hidden event being fired.

To write a simple Component listener program, follow the steps mentioned below:

◉ Declare a class which implements Component listener. For example:

public class ComponentEventDemo ... implements ComponentListener

◉ Identify the components that you would like to catch the events for. For example: pane, label, checkbox, etc.
◉ Add the Component Listener to the identified components. For example:
....
label.addComponentListener(this);
.....
checkbox.addComponentListener(this);
....
panel.addComponentListener(this);
...
frame.addComponentListener(this);

◉ Finally, catch the different events of these components by using four methods of Component 

Listener as shown below:
public void componentHidden(ComponentEvent e) {
        displayMessage(e.getComponent().getClass().getName() + " --- Hidden");
    }

    public void componentMoved(ComponentEvent e) {
        displayMessage(e.getComponent().getClass().getName() + " --- Moved");
    }

    public void componentResized(ComponentEvent e) {
        displayMessage(e.getComponent().getClass().getName() + " --- Resized ");            
    }

    public void componentShown(ComponentEvent e) {
        displayMessage(e.getComponent().getClass().getName() + " --- Shown");

    }

The following example demonstrates component events. The window contains a panel that has a label and a check box. The check box controls whether the label is visible. A text area displays a message every time the window, panel, label, or check box fires a component event.

Oracle Java Certifications, Oracle Java Guides, Oracle Java Tutorials and Materials

Try this: 

1. Click the Launch button to run ComponentEventDemo using Java™ Web Start (download JDK 7 or later).

2. When the window appears, one or more component-shown events have been fired.

3. Click the check box to hide the label. 

The label fires a component-hidden event. The panel fires component-moved and component-resized events. The check box fires a component-moved event.

4. Click the check box again to show the label. 

The label fires a component-shown event. The panel fires component-moved and component-resized events. The check box fires a component-moved event.

5. Iconify and then deiconify the window. 

You do not get component-hidden or -shown events. If you want to be notified of iconification events, you should use a window listener or a window state listener.

6. Resize the window. 

You will see component-resized (and possibly component-moved) events from all four components — label, check box, panel, and frame. If the frame and panel's layout manager did not make every component as wide as possible, the panel, label, and check box would not have been resized.

You can find the demo's code in ComponentEventDemo.java. Here is just the code related to handling component events:

public class ComponentEventDemo ... implements ComponentListener {
    static JFrame frame;
    JLabel label;
    ...
    public ComponentEventDemo() {
        ...
        JPanel panel = new JPanel(new BorderLayout());
        label = new JLabel("This is a label", JLabel.CENTER);
        label.addComponentListener(this);
        panel.add(label, BorderLayout.CENTER);

        JCheckBox checkbox = new JCheckBox("Label visible", true);
        checkbox.addComponentListener(this);
        panel.add(checkbox, BorderLayout.PAGE_END);
        panel.addComponentListener(this);
        ...
        frame.addComponentListener(this);
    }
    ...
     public void componentHidden(ComponentEvent e) {
        displayMessage(e.getComponent().getClass().getName() + " --- Hidden");
    }

    public void componentMoved(ComponentEvent e) {
        displayMessage(e.getComponent().getClass().getName() + " --- Moved");
    }

    public void componentResized(ComponentEvent e) {
        displayMessage(e.getComponent().getClass().getName() + " --- Resized ");            
    }

    public void componentShown(ComponentEvent e) {
        displayMessage(e.getComponent().getClass().getName() + " --- Shown");

    }

    public static void main(String[] args) {
        ...
        //Create and set up the window.
        frame = new JFrame("ComponentEventDemo");
        ...
        JComponent newContentPane = new ComponentEventDemo();
        frame.setContentPane(newContentPane);
        ...
    }
}

The Component Listener API

The ComponentListener Interface

All of these methods are also in the adapter class, ComponentAdapter.

Method Purpose
componentHidden(ComponentEvent) Called after the listened-to component is hidden as the result of the setVisible method being called.
componentMoved(ComponentEvent)  Called after the listened-to component moves, relative to its container. For example, if a window is moved, the window fires a component-moved event, but the components it contains do not.
componentResized(ComponentEvent) Called after the listened-to component's size (rectangular bounds) changes. 
componentShown(ComponentEvent) Called after the listened-to component becomes visible as the result of the setVisible method being called. 

The ComponentEvent Class

Method: Component getComponent()
Purpose: Returns the component that fired the event. You can use this instead of the getSource method.

Examples that Use Component Listeners

The following table lists the examples that use component listeners.

Example: ComponentEventDemo

Described: Reports all component events that occur on several components to demonstrate the circumstances under which component events are fired.

4.5 How to Write a Container Listener


Container events are fired by a Container just after a component is added to or removed from the container. These events are for notification only — no container listener need be present for components to be successfully added or removed.

The following example demonstrates container events. By clicking Add a button or Remove a button, you can add buttons to or remove them from a panel at the bottom of the window. Each time a button is added to or removed from the panel, the panel fires a container event, and the panel's container listener is notified. The listener displays descriptive messages in the text area at the top of the window.

Oracle Java Certifications, Oracle Java Guides, Oracle Java Tutorials and Materials

Try this: 

1. Click the Launch button to run ContainerEventDemo using Java™ Web Start (download JDK 7 or later). Alternatively, to compile and run the example yourself, consult the example index.Launches the ContainerEventDemo example

2. Click the button labeled Add a button.
You will see a button appear near the bottom of the window. The container listener reacts to the resulting component-added event by displaying "JButton #1 was added to javax.swing.JPanel" at the top of the window.

3. Click the button labeled Remove a button.
This removes the most recently added button from the panel, causing the container listener to receive a component-removed event.

You can find the demo's code in ContainerEventDemo.java. Here is the demo's container event handling code:

public class ContainerEventDemo ... implements ContainerListener ... {
    ...//where initialization occurs:
        buttonPanel = new JPanel(new GridLayout(1,1));
        buttonPanel.addContainerListener(this);
    ...
    public void componentAdded(ContainerEvent e) {
        displayMessage(" added to ", e);
    }

    public void componentRemoved(ContainerEvent e) {
        displayMessage(" removed from ", e);
    }

    void displayMessage(String action, ContainerEvent e) {
        display.append(((JButton)e.getChild()).getText()
                       + " was"
                       + action
                       + e.getContainer().getClass().getName()
                       + newline);
    }
    ...
}

The Container Listener API

The ContainerListener Interface

The corresponding adapter class is ContainerAdapter.

Method Purpose
componentAdded(ContainerEvent) Called just after a component is added to the listened-to container.
componentRemoved(ContainerEvent) Called just after a component is removed from the listened-to container.

The ContainerEvent Class

Method Purpose
Component getChild() Returns the component whose addition or removal triggered this event.
Container getContainer() getContainer() Returns the container that fired this event. You can use this instead of the getSource method.

Examples that Use Container Listeners

The following table lists the examples that use container listeners.

Example: ContainerEventDemo

Described: Reports all container events that occur on a single panel to demonstrate the circumstances under which container events are fired.

4.6 How to Write a Document Listener


A Swing text component uses a Document to represent its content. Document events occur when the content of a document changes in any way. You attach a document listener to a text component's document, rather than to the text component itself.

The following example demonstrates document events on two plain text components.

Oracle Java Certifications, Oracle Java Guides, Oracle Java Tutorials and Materials

Try this: 

1. Click the Launch button to run DocumentEventDemo using Java™ Web Start (download JDK 7 or later). Alternatively, to compile and run the example yourself, consult the example index.Launches the DocumentEventDemo example

2. Type in the text field at the upper left of the window or the text area beneath the text field.

One document event is fired for each character typed.

3. Delete text with the backspace key.

One document event is fired for each backspace key typed.

4. Select text and then delete it by typing backspace or by using a keyboard command such as CTRL-X (cut).

One document event is fired for the entire deletion.

5. Copy text from one text component into the other using keyboard commands such as CTRL-C (copy) and CTRL-V (paste).

One document event is fired for the entire paste operation regardless of the length of the text pasted. If text is selected in the target text component before the paste command is issued, an additional document event is fired because the selected text is deleted first.

You can find the demo's code in DocumentEventDemo.java. Here is the demo's document event handling code:

public class DocumentEventDemo ... {
    ...//where initialization occurs:
    textField = new JTextField(20);
    textField.addActionListener(new MyTextActionListener());
    textField.getDocument().addDocumentListener(new MyDocumentListener());
    textField.getDocument().putProperty("name", "Text Field");

    textArea = new JTextArea();
    textArea.getDocument().addDocumentListener(new MyDocumentListener());
    textArea.getDocument().putProperty("name", "Text Area");
    ...

class MyDocumentListener implements DocumentListener {
    String newline = "\n";

    public void insertUpdate(DocumentEvent e) {
        updateLog(e, "inserted into");
    }
    public void removeUpdate(DocumentEvent e) {
        updateLog(e, "removed from");
    }
    public void changedUpdate(DocumentEvent e) {
        //Plain text components do not fire these events
    }

    public void updateLog(DocumentEvent e, String action) {
        Document doc = (Document)e.getDocument();
        int changeLength = e.getLength();
        displayArea.append(
            changeLength + " character" +
            ((changeLength == 1) ? " " : "s ") +
            action + doc.getProperty("name") + "." + newline +
            "  Text length = " + doc.getLength() + newline);
    }
}

Document listeners should not modify the contents of the document; The change is already complete by the time the listener is notified of the change. Instead, write a custom document that overrides the insertString or remove methods, or both.

The Document Listener API


The DocumentListener Interface

DocumentListener has no adapter class.

Method Purpose
changedUpdate(DocumentEvent) Called when the style of some of the text in the listened-to document changes. This sort of event is fired only from a StyledDocument — a PlainDocument does not fire these events.
insertUpdate(DocumentEvent) Called when text is inserted into the listened-to document. 
removeUpdate(DocumentEvent) Called when text is removed from the listened-to document. 

The DocumentEvent Interface

Each document event method is passed an object that implements the DocumentEvent interface. Typically, this is an instance of DefaultDocumentEvent, defined in AbstractDocument.

Method Purpose 
Document getDocument() Returns the document that fired the event. Note that the DocumentEvent interface does not inherit from EventObject. Therefore, it does not inherit the getSource method.
int getLength() Returns the length of the change.
int getOffset() Returns the location within the document of the first character changed.
ElementChange getChange(Element) Returns details about what elements in the document have changed and how. ElementChange is an interface defined within the DocumentEvent interface.
EventType getType() Returns the type of change that occurred. EventType is a class defined within the DocumentEvent interface that enumerates the possible changes that can occur on a document: insert text, remove text, and change text style.

Examples that Use Document Listeners

The following table lists the examples that use document listeners.
Example Notes
DocumentEventDemo Reports all document events that occur on the documents for both a text field and a text area. One listener listens to both text components and uses a client property on the document to determine which component fired the event. 
TextComponentDemo Updates a change log every time text in the listened-to document changes. The document in this example supports styled text, so changedUpdate gets called in this example. 

4.7 How to Write a Focus Listener


Focus events are fired whenever a component gains or loses the keyboard focus. This is true whether the change in focus occurs through the mouse, the keyboard, or programmatically. To get familiar with basic focus concepts or to obtain detailed information about focus.

This section explains how to get focus events for a particular component by registering a FocusListener instance on it. To get focus for a window only, implement a WindowFocusListener instance instead. To obtain the focus status of many components, consider implementing a PropertyChangeListener instance on the KeyboardFocusManager class, as described in Tracking Focus Changes to Multiple Components in How to Use the Focus Subsystem.

The following example demonstrates focus events. The window displays a variety of components. A focus listener, registered on each component, reports every focus-gained and focus-lost event. For each event, the other component involved in the focus change, the opposite component, is reported. For example, when the focus goes from a button to a text field, a focus-lost event is fired by the button (with the text field as the opposite component) and then a focus-gained event is fired by the text field (with the button as the opposite component). Focus-lost as well as focus-gained events can be temporary. For example, a temporary focus-lost event occurs when the window loses the focus. A temporary focus-gained event occurs on popup menus.

Oracle Java Certifications, Oracle Java Guides, Oracle Java Tutorials and Materials

Running the Example
  1. Click the Launch button to run FocusEventDemo using Java™ Web Start (download JDK 7 or later). Alternatively, to compile and run the example yourself, consult the example index.Launches the FocusEventDemo application
  2. You will see a "Focus gained: JTextField" message in the text area — its "opposite component" is null, since it is the first component to have the focus.
  3. Click the label. Nothing happens because the label, by default, cannot get the focus.
  4. Click the combo box. A focus-lost event is fired by the text field and a focus-gained event by the combo box. The combo box now shows that it has the focus, perhaps with a dotted line around the text — exactly how this is represented is look and feel dependent. Notice that when the focus changes from one component to another, the first component fires a focus-lost event before the second component fires a focus-gained event.
  5. Select a choice from the combo box's menu. Click the combo box again. Notice that no focus event is reported. As long as the user manipulates the same component, the focus stays on that component.
  6. Click the text area where the focus events are printed. Nothing happens because the text area has been rendered unclickable with setRequestFocusEnabled(false).
  7. Click the text field to return the focus to the initial component.
  8. Press Tab on the keyboard. The focus moves to the combo box and skips over the label.
  9. Press Tab again. The focus moves to the button.
  10. Click another window so that the FocusEventDemo window loses the focus. A temporary focus-lost event is generated for the button.
  11. Click the top of the FocusEventDemo window. A focus-gained event is fired by the button.
  12. Press Tab on the keyboard. The focus moves to the list.
  13. Press Tab again. The focus moves to the text area.
Notice that even though you are not allowed to click on the text area, you can tab to it. This is so users who use assistive technologies can determine that a component is there and what it contains. The demo disables click-to-focus for the text area, while retaining its tab-to-focus capability, by invoking setRequestFocusEnabled(false) on the text area. The demo could use setFocusable(false) to truly remove the text area from the focus cycle, but that would have the unfortunate effect of making the component unavailable to those who use assistive technologies.

14. Press Tab again. The focus moves from the list back to the text field. You have just completed a focus cycle.

The complete code for this demo is in the FocusEventDemo.java file. The following code snippet represents the focus-event handling mechanism:

public class FocusEventDemo ... implements FocusListener ... {
    public FocusEventDemo() {
        ...
        JTextField textField = new JTextField("A TextField");
        textField.addFocusListener(this);
        ...
        JLabel label = new JLabel("A Label");
        label.addFocusListener(this);
        ...
        JComboBox comboBox = new JComboBox(vector);
        comboBox.addFocusListener(this);
        ...
        JButton button = new JButton("A Button");
        button.addFocusListener(this);
        ...
        JList list = new JList(listVector);
        list.setSelectedIndex(1); //It's easier to see the focus change
                                  //if an item is selected.
        list.addFocusListener(this);
        JScrollPane listScrollPane = new JScrollPane(list);
        
        ...

        //Set up the area that reports focus-gained and focus-lost events.
        display = new JTextArea();
        display.setEditable(false);
        //The method setRequestFocusEnabled prevents a
        //component from being clickable, but it can still
        //get the focus through the keyboard - this ensures
        //user accessibility.
        display.setRequestFocusEnabled(false);
        display.addFocusListener(this);
        JScrollPane displayScrollPane = new JScrollPane(display);

        ...
    }
    ...
    public void focusGained(FocusEvent e) {
        displayMessage("Focus gained", e);
    }

    public void focusLost(FocusEvent e) {
        displayMessage("Focus lost", e);
    }

    void displayMessage(String prefix, FocusEvent e) {
        display.append(prefix
                       + (e.isTemporary() ? " (temporary):" : ":")
                       +  e.getComponent().getClass().getName()
                       + "; Opposite component: " 
                       + (e.getOppositeComponent() != null ?
                          e.getOppositeComponent().getClass().getName() : "null")
                       + newline); 
    }
    ...
}

The Focus Listener API

The FocusListener Interface

The corresponding adapter class is FocusAdapter.

Example Notes
focusGained(FocusEvent) Called just after the listened-to component gets the focus.
focusLost(FocusEvent) Called just after the listened-to component loses the focus.

The FocusEvent API

Method Purpose 
boolean isTemporary() Returns the true value if a focus-lost or focus-gained event is temporary.
Component getComponent()
(in java.awt.event.ComponentEvent)
Returns the component that fired the focus event. 
Component getOppositeComponent() Returns the other component involved in the focus change. For a FOCUS_GAINED event, this is the component that lost the focus. For a FOCUS_LOST event, this is the component that gained the focus. If the focus change involves a native application, a Java application in a different VM or context, or no other component, then null is returned. 

Examples that Use Focus Listeners

The following table lists the examples that use focus listeners.

Example Notes
FocusEventDemo Returns the true value if a focus-lost or focus-gained event is temporary.
TrackFocusDemo Reports all focus events that occur on several components to demonstrate the circumstances under which focus events are fired.

4.8 How to Write an Internal Frame Listener


An InternalFrameListener is similar to a WindowListener. Like the window listener, the internal frame listener listens for events that occur when the "window" has been shown for the first time, disposed of, iconified, deiconified, activated, or deactivated. Before using an internal frame listener, please familiarize yourself with the WindowListener interface in How to Write Window Listeners.

The application shown in the following figure demonstrates internal frame events. The application listens for internal frame events from the Event Generator frame, displaying a message that describes each event.

Oracle Java Tutorials and Materials, Oracle Java Guides, Oracle Java Certifications

Here is the internal frame event handling code:

public class InternalFrameEventDemo ...
                     implements InternalFrameListener ... {
    ...

    public void internalFrameClosing(InternalFrameEvent e) {
        displayMessage("Internal frame closing", e);
    }

    public void internalFrameClosed(InternalFrameEvent e) {
        displayMessage("Internal frame closed", e);
        listenedToWindow = null;
    }

    public void internalFrameOpened(InternalFrameEvent e) {
        displayMessage("Internal frame opened", e);
    }

    public void internalFrameIconified(InternalFrameEvent e) {
        displayMessage("Internal frame iconified", e);
    }

    public void internalFrameDeiconified(InternalFrameEvent e) {
        displayMessage("Internal frame deiconified", e);
    }

    public void internalFrameActivated(InternalFrameEvent e) {
        displayMessage("Internal frame activated", e);
    }

    public void internalFrameDeactivated(InternalFrameEvent e) {
        displayMessage("Internal frame deactivated", e);
    }

    void displayMessage(String prefix, InternalFrameEvent e) {
        String s = prefix + ": " + e.getSource(); 
        display.append(s + newline);
    }

    public void actionPerformed(ActionEvent e) {
        if (SHOW.equals(e.getActionCommand())) {
            ...
            if (listenedToWindow == null) {
                listenedToWindow = new JInternalFrame("Event Generator",
                                                      true,  //resizable
                                                      true,  //closable
                                                      true,  //maximizable
                                                      true); //iconifiable
                //We want to reuse the internal frame, so we need to
                //make it hide (instead of being disposed of, which is
                //the default) when the user closes it.
                listenedToWindow.setDefaultCloseOperation(
                                        WindowConstants.HIDE_ON_CLOSE);

                listenedToWindow.addInternalFrameListener(this);
                ...
            }
        } 
        ...
    }
}

The Internal Frame Listener API
The InternalFrameListener Interface

The corresponding adapter class is InternalFrameAdapter.

Method Purpose
internalFrameOpened(InternalFrameEvent) Called just after the listened-to internal frame has been shown for the first time.
internalFrameClosing(InternalFrameEvent) Called in response to a user request that the listened-to internal frame be closed. By default, JInternalFrame hides the window when the user closes it. You can use the JInternalFrame setDefaultCloseOperation method to specify another option, which must be either DISPOSE_ON_CLOSE or DO_NOTHING_ON_CLOSE (both defined in WindowConstants, an interface that JInternalFrame implements). Or by implementing an internalFrameClosing method in the internal frame's listener, you can add custom behavior (such as bringing up dialogs or saving data) to internal frame closing.
internalFrameClosed(InternalFrameEvent) Called just after the listened-to internal frame has been disposed of.
internalFrameIconified(InternalFrameEvent)
internalFrameDeiconified(InternalFrameEvent)
Called just after the listened-to internal frame is iconified or deiconified, respectively.
internalFrameActivated(InternalFrameEvent)
internalFrameDeactivated(InternalFrameEvent)
Called just after the listened-to internal frame is activated or deactivated, respectively.

Each internal frame event method has a single parameter: an InternalFrameEvent object. The InternalFrameEvent class defines no generally useful methods. To get the internal frame that fired the event, use the getSource method, which InternalFrameEvent inherits from java.util.EventObject.

Examples that Use Internal Frame Listeners

No other source files currently contain internal frame listeners. However, internal frame listeners are very similar to WindowListeners and several Swing programs have window listeners:

Method Notes
InternalFrameEventDemo Reports all internal frame events that occur on one internal frame to demonstrate the circumstances under which internal frame events are fired.
DialogDemo Text Component Features
internalFrameClosed(InternalFrameEvent) CustomDialog.java uses setDefaultCloseOperation instead of a window listener to determine what action to take when the user closes the window
SliderDemo Listens for window iconify and deiconify events, so that it can stop the animation when the window is not visible.

4.9 How to Write an Item Listener


Item events are fired by components that implement the ItemSelectable interface. Generally, ItemSelectable components maintain on/off state for one or more items. The Swing components that fire item events include buttons like check boxes, check menu items, toggle buttons etc...and combo boxes.

Here is some item-event handling code taken from ComponentEventDemo.java:

//where initialization occurs
checkbox.addItemListener(this);
...
public void itemStateChanged(ItemEvent e) {
    if (e.getStateChange() == ItemEvent.SELECTED) {
        label.setVisible(true);
        ...
    } else {
        label.setVisible(false);
    }
}

The Item Listener API

The ItemListener Interface

Because ItemListener has only one method, it has no corresponding adapter class.

Method Purpose
itemStateChanged(ItemEvent) Called just after a state change in the listened-to component.

The ItemEvent Class

Method Purpose
Object getItem() Returns the component-specific object associated with the item whose state changed. Often this is a String containing the text on the selected item.
ItemSelectable getItemSelectable() Returns the component that fired the item event. You can use this instead of the getSource method. 
int getStateChange() Returns the new state of the item. The ItemEvent class defines two states: SELECTED and DESELECTED. 

Examples that Use Item Listeners

The following table lists some examples that use item listeners.

Example Notes
ComponentEventDemo Listens for item events on a check box, which determines whether a lable is visible. 
CheckBoxDemo Four check boxes share one item listener, which uses getItemSelected to determine which check box fired the event. 
MenuDemo  Listens for item events on a check box menu item.
MenuDemo Listens for item events on a toggle button. 

4.10 How to Write a Key Listener

Key events indicate when the user is typing at the keyboard. Specifically, key events are fired by the component with the keyboard focus when the user presses or releases keyboard keys.

Note: To define special reactions to particular keys, use key bindings instead of a key listener. For further information, see How to Use Key Bindings.

Notifications are sent about two basic kinds of key events:

◉ The typing of a Unicode character
◉ The pressing or releasing of a key on the keyboard

The first kind of event is called a key-typed event. The second kind is either a key-pressed or key-released event.

In general, you react to only key-typed events unless you need to know when the user presses keys that do not correspond to characters. For example, to know when the user types a Unicode character — whether by pressing one key such as 'a' or by pressing several keys in sequence — you handle key-typed events. On the other hand, to know when the user presses the F1 key, or whether the user pressed the '3' key on the number pad, you handle key-pressed events.

Note: To fire keyboard events, a component must have the keyboard focus.

To make a component get the keyboard focus, follow these steps:

1. Make sure the component's isFocusable method returns true. This state allows the component to receive the focus. For example, you can enable keyboard focus for a JLabel component by calling the setFocusable(true) method on the label.
2. Make sure the component requests the focus when appropriate. For custom components, implement a mouse listener that calls the requestFocusInWindow method when the component is clicked.

Version note: 
The focus subsystem consumes focus traversal keys, such as Tab and Shift Tab. If you need to prevent the focus traversal keys from being consumed, you can call

component.setFocusTraversalKeysEnabled(false)

on the component that is firing the key events. Your program must then handle focus traversal on its own. Alternatively, you can use the KeyEventDispatcher class to pre-listen to all key events. The focus page has detailed information on the focus subsystem.

You can obtain detailed information about a particular key-pressed event. For example, you can query a key-pressed event to determine if it was fired from an action key. Examples of action keys include Copy, Paste, Page Up, Undo, and the arrow and function keys. You can also query a key-pressed or key-released event to determine the location of the key that fired the event. Most key events are fired from the standard keyboard, but the events for some keys, such as Shift, have information on whether the user pressed the Shift key on the left or the right side of the keyboard. Likewise, the number '2' can be typed from either the standard keyboard or from the number pad.

For key-typed events you can obtain the key character value as well as any modifiers used.

Note: You should not rely on the key character value returned from getKeyChar unless it is involved in a key-typed event.

The following example demonstrates key events. It consists of a text field that you can type into, followed by a text area that displays a message every time the text field fires a key event. A button at the bottom of the window lets you clear both the text field and text area.

Oracle Java Tutorials and Material, Oracle Java Certifications, Oracle Java Web

Try this: 

1. Click the Launch button to run KeyEventDemo using Java™ Web Start (download JDK 7 or later). Alternatively, to compile and run the example yourself, consult the example index.Launches the KeyEventDemo application

2. Type a lowercase 'a' by pressing and releasing the A key on the keyboard.
The text field fires three events: a key-pressed event, a key-typed event, and a key-released event. Note that the key-typed event doesn't have key code information, and key-pressed and key-released events don't have key character information. None of the events so far are from modifier or action keys and the key location, reported on the key-pressed and key-released events, is most likely standard.

3. Press the Clear button.
You might want to do this after each of the following steps.

4. Press and release the Shift key.
The text field fires two events: a key-pressed and a key-released. The text field doesn't fire a key-typed event because Shift, by itself, doesn't correspond to any character.

5. Type an uppercase 'A' by pressing the Shift and A keys.
You'll see the following events, although perhaps not in this order: key-pressed (Shift), key-pressed (A), key typed ('A'), key-released (A), key-released (Shift). Note that Shift is listed as the modifier key for the key-typed and key-pressed events.

6. Type an uppercase 'A' by pressing and releasing the Caps Lock key, and then pressing the A key.
You should see the following events: key-pressed (Caps Lock), key-pressed (A), key typed ('A'), key-released (A). Note that Caps Lock is not listed as a modifier key.

7. Press the Tab key. No Tab key-pressed or key-released events are received by the key event listener. This is because the focus subsystem consumes focus traversal keys, such as Tab and Shift Tab. Press Tab twice more to return the focus to the text area.

8. Press a function key, such as F3. You'll see that the function key is an action key.

9. Press the left Shift key, followed by the right Shift key. The key-pressed and key-released events indicate which Shift key was typed.

10. Press the Num Lock key if your keyboard has a number pad.
As for Caps Lock, there is a key-pressed event, but no key-released event.

11. Press the '2' key on the number pad. You see the key-pressed, key-typed, and key-released events for the number '2'.

12. Press the '2' key on the standard keyboard. Again, you see the three event messages. The key-typed events for both number 2 keys are identical. But the key-pressed and key-released events indicate different key codes and different key locations.
13. Press the Num Lock key again. A key-released event is fired.

You can find the example's code in KeyEventDemo.java. Here is the demo's key event handling code:

public class KeyEventDemo ...  implements KeyListener ... {
    ...//where initialization occurs:
        typingArea = new JTextField(20);
        typingArea.addKeyListener(this);

        //Uncomment this if you wish to turn off focus
        //traversal.  The focus subsystem consumes
        //focus traversal keys, such as Tab and Shift Tab.
        //If you uncomment the following line of code, this
        //disables focus traversal and the Tab events 
        //become available to the key event listener.
        //typingArea.setFocusTraversalKeysEnabled(false);
    ...
    /** Handle the key typed event from the text field. */
    public void keyTyped(KeyEvent e) {
        displayInfo(e, "KEY TYPED: ");
    }

    /** Handle the key-pressed event from the text field. */
    public void keyPressed(KeyEvent e) {
        displayInfo(e, "KEY PRESSED: ");
    }

    /** Handle the key-released event from the text field. */
    public void keyReleased(KeyEvent e) {
        displayInfo(e, "KEY RELEASED: ");
    }
    ...
    private void displayInfo(KeyEvent e, String keyStatus){
        
        //You should only rely on the key char if the event
        //is a key typed event.
        int id = e.getID();
        String keyString;
        if (id == KeyEvent.KEY_TYPED) {
            char c = e.getKeyChar();
            keyString = "key character = '" + c + "'";
        } else {
            int keyCode = e.getKeyCode();
            keyString = "key code = " + keyCode
                    + " ("
                    + KeyEvent.getKeyText(keyCode)
                    + ")";
        }
        
        int modifiersEx = e.getModifiersEx();
        String modString = "extended modifiers = " + modifiersEx;
        String tmpString = KeyEvent.getModifiersExText(modifiersEx);
        if (tmpString.length() > 0) {
            modString += " (" + tmpString + ")";
        } else {
            modString += " (no extended modifiers)";
        }
        
        String actionString = "action key? ";
        if (e.isActionKey()) {
            actionString += "YES";
        } else {
            actionString += "NO";
        }
        
        String locationString = "key location: ";
        int location = e.getKeyLocation();
        if (location == KeyEvent.KEY_LOCATION_STANDARD) {
            locationString += "standard";
        } else if (location == KeyEvent.KEY_LOCATION_LEFT) {
            locationString += "left";
        } else if (location == KeyEvent.KEY_LOCATION_RIGHT) {
            locationString += "right";
        } else if (location == KeyEvent.KEY_LOCATION_NUMPAD) {
            locationString += "numpad";
        } else { // (location == KeyEvent.KEY_LOCATION_UNKNOWN)
            locationString += "unknown";
        }
        
        ...//Display information about the KeyEvent...
    }
}

The Key Listener API

The KeyListener Interface

The corresponding adapter class is KeyAdapter.

Method Purpose
keyTyped(KeyEvent) Called just after the user types a Unicode character into the listened-to component. 
keyPressed(KeyEvent)  Called just after the user presses a key while the listened-to component has the focus. 
keyReleased(KeyEvent) Called just after the user releases a key while the listened-to component has the focus.

The KeyEvent Class

The KeyEvent class inherits many useful methods from the InputEvent class, such as getModifiersEx, and a couple of useful methods from the ComponentEvent and AWTEvent classes. See the InputEvent Class table in the mouse listener page for a complete list.

Method Purpose 
int getKeyChar() Obtains the Unicode character associated with this event. Only rely on this value for key-typed events.
int getKeyCode()  Obtains the key code associated with this event. The key code identifies the particular key on the keyboard that the user pressed or released. The KeyEvent class defines many key code constants for commonly seen keys. For example, VK_A specifies the key labeled A, and VK_ESCAPE specifies the Escape key.
String getKeyText(int)
String getKeyModifiersText(int)
Return text descriptions of the event's key code and modifier keys, respectively. 
int getModifiersEx()
String getModifiersExText(int modifiers) 
Return the extended modifiers mask for this event. There are methods inherited from the InputEvent class. Extended modifiers represent the state of all modal keys. The getModifiersExText method returns a string describing the extended modifier keys and mouse buttons. Since the getModifiersEx and getModifiersExText methods provide more information about key events, they are preferred over the getKeyText or getKeyModifiersText methods. 
boolean isActionKey() Returns true if the key firing the event is an action key. Examples of action keys include Cut, Copy, Paste, Page Up, Caps Lock, the arrow and function keys. This information is valid only for key-pressed and key-released events. 
int getKeyLocation()   Returns the location of the key that fired this event. This provides a way to distinguish keys that occur more than once on a keyboard, such as the two shift keys, for example. The possible values are KEY_LOCATION_STANDARD, KEY_LOCATION_LEFT, KEY_LOCATION_RIGHT, KEY_LOCATION_NUMPAD, or KEY_LOCATION_UNKNOWN. This method always returns KEY_LOCATION_UNKNOWN for key-typed events. 

Examples that Use Key Listeners

The following table lists the examples that use key listeners.

Example: KeyEventDemo
Note: Reports all key events that occur on a text field to demonstrate the circumstances under which key events are fired.

4.11 How to Write a List Data Listener


List data events occur when the contents of a mutable list change. Since the model — not the component — fires these events, you have to register a list data listener with the list model. If you have not explicitly created a list with a mutable list model, then your list is immutable, and its model will not fire these events.

Note: Combo box models also fire list data events. However, you normally do not need to know about them unless you are creating a custom combo box model.

The following example demonstrates list data events on a mutable list:

Oracle Java Guides, Oracle Java Tutorials and Materials

Try this: 

1. Click the Launch button to run ListDataEventDemo using Java™ Web Start (download JDK 7 or later). Alternatively, to compile and run the example yourself, consult the example index.Launches the ListDataEventDemo example
2. Type in the name of your favorite ski resort and click the Add button. An intervalAdded event was fired.
3. Select a few continguous items in the list and click the Delete button. An intervalRemoved event was fired.
4. Select one item and move it up or down in the list with the arrow buttons. Two contentsChanged events are fired — one for the item that moved and one for the item that was displaced.

You can find the demo's code in ListDataEventDemo.java. Here is the code that registers a list data listener on the list model and implements the listener:

//...where member variables are declared...
private DefaultListModel listModel;
...
//Create and populate the list model
listModel = new DefaultListModel();
...
listModel.addListDataListener(new MyListDataListener());

class MyListDataListener implements ListDataListener {
    public void contentsChanged(ListDataEvent e) {
        log.append("contentsChanged: " + e.getIndex0() +
                   ", " + e.getIndex1() + newline);
    }
    public void intervalAdded(ListDataEvent e) {
        log.append("intervalAdded: " + e.getIndex0() +
                   ", " + e.getIndex1() + newline);
    }
    public void intervalRemoved(ListDataEvent e) {
        log.append("intervalRemoved: " + e.getIndex0() +
                   ", " + e.getIndex1() + newline);
    }

The List Data Listener API

The ListDataListener Interface

ListDataListener has no corresponding adapter class.

Method Purpose
intervalAdded(ListDataEvent) Called when one or more items have been added to the list.
intervalRemoved(ListDataEvent) Called when one or more items have been removed from the list. 
contentsChanged(ListDataEvent) Called when the contents of one or more items in the list have changed. 

The ListDataEvent API

Method Purpose 
Object getSource()
(in java.util.EventObject)
Return the object that fired the event.
int getIndex0() Return the index of the first item whose value has changed. 
int getIndex1() Return the index of the last item whose value has changed.
int getType() Return the event type. The possible values are: CONTENTS_CHANGED, INTERVAL_ADDED, or INTERVAL_REMOVED. 

Examples that Use List Data Listeners

The following table lists the examples that use list data listeners.

Example: ListDataEventDemo
Notes: Reports all list data events that occur on a list.

4.12 How to Write a List Selection Listener


List selection events occur when the selection in a list or table is either changing or has just changed. List selection events are fired from an object that implements the ListSelectionModel interface. To get a table's list selection model object, you can use either getSelectionModel method or getColumnModel().getSelectionModel().

To detect list selection events, you register a listener on the appropriate list selection model object. The JList class also gives you the option of registering a listener on the list itself, rather than directly on the list selection model.

This section looks at two examples that show how to listen to list selection events on a selection model. Examples that Use List Selection Listeners lists examples that listen on the list directly.

In these two examples, you can dynamically change the selection mode to any of the three supported modes:

◉ single selection mode
◉ single interval selection mode
◉ multiple interval selection mode

Here is a picture of ListSelectionDemo example running in a List :

Oracle Java Tutorials and Materials, Oracle Java Guides, Oracle Java Certifications

Try this: 

1. Click the Launch button to run ListSelectionDemo using Java™ Web Start (download JDK 7 or later). 

2. Select and deselect items in the list. The mouse and keyboard commands required to select items depends on the look and feel. For the Java look and feel, click the left mouse button to begin a selection, use the shift key to extend a selection contiguously, and use the control key to extend a selection discontiguously. Note that there are two types of selections: Lead and Anchor. Lead is the focused item and Anchor is the highlighted item. When you press ctrl key and move up and down, the lead selection causes the events being fired even though the actual selection has not changed. Dragging the mouse moves or extends the selection, depending on the list selection mode.

Here is a picture of TableListSelectionDemo example running in a Table:

Oracle Java Tutorials and Materials, Oracle Java Guides, Oracle Java Certifications

Try this: 

1. Click the Launch button to run TableListSelectionDemo using Java™ Web Start (download JDK 7 or later). 

2. Select and deselect items in the table. The mouse and keyboard commands required to select items depends on the look and feel. For the Java look and feel, click the left mouse button to begin a selection, use the shift key to extend a selection contiguously, and use the control key to extend a selection discontiguously. Note that there are two types of selections: Lead and Anchor. Lead is the focused item and Anchor is the highlighted item. When you press ctrl key and move up or down, the lead selection causes the events being fired even though the actual selection has not changed. Dragging the mouse moves or extends the selection, depending on the list selection mode.

You can find the entire program of ListSelectionDemo in ListSelectionDemo.java and the entire program of TableListSelectionDemo in TableListSelectionDemo.java.

Here is the code from ListSelectionDemo that sets up the selection model and adds a listener to it:

...//where the member variables are defined
JList list;
    ...//in the init method:
    listSelectionModel = list.getSelectionModel();
    listSelectionModel.addListSelectionListener(
                            new SharedListSelectionHandler());
    ...
And here is the code for the listener, which works for all the possible selection modes:

class SharedListSelectionHandler implements ListSelectionListener {
    public void valueChanged(ListSelectionEvent e) {
        ListSelectionModel lsm = (ListSelectionModel)e.getSource();

        int firstIndex = e.getFirstIndex();
        int lastIndex = e.getLastIndex();
        boolean isAdjusting = e.getValueIsAdjusting();
        output.append("Event for indexes "
                      + firstIndex + " - " + lastIndex
                      + "; isAdjusting is " + isAdjusting
                      + "; selected indexes:");

        if (lsm.isSelectionEmpty()) {
            output.append(" <none>");
        } else {
            // Find out which indexes are selected.
            int minIndex = lsm.getMinSelectionIndex();
            int maxIndex = lsm.getMaxSelectionIndex();
            for (int i = minIndex; i <= maxIndex; i++) {
                if (lsm.isSelectedIndex(i)) {
                    output.append(" " + i);
                }
            }
        }
        output.append(newline);
    }
}

This valueChanged method displays the first and last indices reported by the event, the value of the event's isAdjusting flag, and the indices currently selected.

Note that the first and last indices reported by the event indicate the inclusive range of items for which the selection has changed. If the selection mode is multiple interval selection some items within the range might not have changed. The isAdjusting flag is true if the user is still manipulating the selection, and false if the user has finished changing the selection.

The ListSelectionEvent object passed into valueChanged indicates only that the selection has changed. The event contains no information about the current selection. So, this method queries the selection model to figure out the current selection.

The List Selection Listener API

The ListSelectionListener Interface

Because ListSelectionListener has only one method, it has no corresponding adapter class.

Method Purpose
valueChanged(ListSelectionEvent) Called in response to selection changes.

The ListSelectionEvent API

Method Purpose
Object getSource()
(in java.util.EventObject)
Return the object that fired the event. If you register a list selection listener on a list directly, then the source for each event is the list. Otherwise, the source is the selection model.
int getFirstIndex() Return the index of the first item whose selection value has changed. Note that for multiple interval selection, the first and last items are guaranteed to have changed but items between them might not have. However, when you press ctrl key and move up or down, the lead selection causes the events being fired even though the actual selection has not changed. 
int getLastIndex() Return the index of the last item whose selection value has changed. Note that for multiple interval selection, the first and last items are guaranteed to have changed but items between them might not have. However, when you press ctrl key and move up and down, the lead selection causes the events being fired even though the actual selection has not changed. 
boolean getValueIsAdjusting() Return true if the selection is still changing. Many list selection listeners are interested only in the final state of the selection and can ignore list selection events when this method returns true.

Examples that Use List Selection Listeners

The following table lists the examples that use list selection listeners.

Example Notes
ListSelectionDemo Reports all list selection events that occur on a list. Lets the user dynamically change the selection mode.
TableListSelectionDemo Reports all list selection events that occur on a table. Lets the user dynamically change the selection mode.
ListDemo Listens to events on a single-selection list (not on its selection model). Enables and disables a button depending on whether any items are selected in the list.
SplitPaneDemo Listens to events on a single-selection list (not on its selection model).
SimpleTableSelectionDemo Uses two different list selection listeners on one table. One listener listens to list selection events on table columns, the other listens to list selection events on table rows.

4.13 How to Write a Mouse Listener


Mouse events notify when the user uses the mouse (or similar input device) to interact with a component. Mouse events occur when the cursor enters or exits a component's onscreen area and when the user presses or releases one of the mouse buttons.

Tracking the cursor's motion involves significantly more system overhead than tracking other mouse events. That is why mouse-motion events are separated into Mouse Motion listener type.

To track mouse wheel events, you can register a mouse-wheel listener.

If an application requires the detection of both mouse events and mouse-motion events, use the MouseInputAdapter class. This class implements the MouseInputListener, a convenient interface that implements the MouseListener and MouseMotionListener interfaces. However, the MouseInputListener interface does not implement the MouseWheelListener interface.

Alternatively, use the corresponding AWT MouseAdapter class, which implements the MouseListener, MouseMotionListener, and MouseWheelListener interfaces.

The following example shows a mouse listener. At the top of the window is a blank area (implemented by a class named BlankArea). The mouse listener listens for events both on the BlankArea and on its container, an instance of MouseEventDemo. Each time a mouse event occurs, a descriptive message is displayed under the blank area. By moving the cursor on top of the blank area and occasionally pressing mouse buttons, you can fire mouse events.

Oracle Java Tutorials and Materials, Oracle Java Guides, Oracle Java Certifications

Try this: 

1. Click the Launch button to run MouseEventDemo using Java™ Web Start (download JDK 7 or later). 
2. Move the cursor into the yellow rectangle at the top of the window.
You will see one or more mouse-entered events.
3. Press and hold the left mouse button without moving the mouse.
You will see a mouse-pressed event. You might see some extra mouse events, such as mouse-exited and then mouse-entered.
4. Release the mouse button.
You will see a mouse-released event. If you did not move the mouse, a mouse-clicked event will follow.
5. Press and hold the mouse button again, and then drag the mouse so that the cursor ends up outside the window. Release the mouse button.

You will see a mouse-pressed event, followed by a mouse-exited event, followed by a mouse-released event. You are not notified of the cursor's motion. To get mouse-motion events, you need to implement a mouse-motion listener.
You can find the demo's code in MouseEventDemo.java and BlankArea.java. Here is the demo's mouse event handling code:

public class MouseEventDemo ... implements MouseListener {
        //where initialization occurs:
        //Register for mouse events on blankArea and the panel.
        blankArea.addMouseListener(this);
        addMouseListener(this);
    ...

    public void mousePressed(MouseEvent e) {
       saySomething("Mouse pressed; # of clicks: "
                    + e.getClickCount(), e);
    }

    public void mouseReleased(MouseEvent e) {
       saySomething("Mouse released; # of clicks: "
                    + e.getClickCount(), e);
    }

    public void mouseEntered(MouseEvent e) {
       saySomething("Mouse entered", e);
    }

    public void mouseExited(MouseEvent e) {
       saySomething("Mouse exited", e);
    }

    public void mouseClicked(MouseEvent e) {
       saySomething("Mouse clicked (# of clicks: "
                    + e.getClickCount() + ")", e);
    }

    void saySomething(String eventDescription, MouseEvent e) {
        textArea.append(eventDescription + " detected on "
                        + e.getComponent().getClass().getName()
                        + "." + newline);
    }
}

The Mouse Listener API

The MouseListener Interface

Method Purpose 
mouseClicked(MouseEvent) Called just after the user clicks the listened-to component. 
mouseEntered(MouseEvent)  Called just after the cursor enters the bounds of the listened-to component. 
mouseExited(MouseEvent)  Called just after the cursor exits the bounds of the listened-to component. 
mousePressed(MouseEvent)  Called just after the user presses a mouse button while the cursor is over the listened-to component. 
mouseReleased(MouseEvent)  Called just after the user releases a mouse button after a mouse press over the listened-to component.

The MouseAdapter class (the AWT adapter class) is abstract. All its methods have an empty body. So a developer can define methods for events specific to the application. You can also use the MouseInputAdapter class, which has all the methods available from MouseListener and MouseMotionListener.

The MouseEvent Class

Return the (x,y) position at which the event occurred, relative to the component that fired the event.

Method Purpose 
int getClickCount() Returns the number of quick, consecutive clicks the user has made (including this event). For example, returns 2 for a double click.
int getX()
int getY()
Point getPoint()
Return the (x,y) position at which the event occurred, relative to the component that fired the event.
int getXOnScreen()
int getYOnScreen()
int getLocationOnScreen()
Return the absolute (x,y) position of the event. These coordinates are relative to the virtual coordinate system for the multi-screen environment. Otherwise, these coordinates are relative to the coordinate system associated with the Component's Graphics Configuration.
int getButton() Returns which mouse button, if any, has a changed state. One of the following constants is returned: NOBUTTON, BUTTON1, BUTTON2, or BUTTON3.
boolean isPopupTrigger() Returns true if the mouse event should cause a popup menu to appear. Because popup triggers are platform dependent, if your program uses popup menus, you should call isPopupTrigger for all mouse-pressed and mouse-released events fired by components over which the popup can appear. See Bringing Up a Popup Menu for more information about popup menus.
String getMouseModifiersText(int) Returns a String describing the modifier keys and mouse buttons that were active during the event, such as "Shift", or "Ctrl+Shift". These strings can be localized using the awt.properties file.

The InputEvent Class

The MouseEvent class inherits many useful methods from InputEvent and a couple handy methods from the ComponentEvent and AWTEvent classes.

Method Purpose 
int getID()
(in java.awt.AWTEvent)
Returns the event type, which defines the particular action. For example, the MouseEvent id reflects the state of the mouse buttons for every mouse event. The following states could be specified by the MouseEvent id: MouseEvent.MOUSE_PRESSED, MouseEvent.MOUSE_RELEASED, and MouseEvent.MOUSE_CLICKED.
Component getComponent()
(in ComponentEvent)
Returns the component that fired the event. You can use this method instead of the getSource method.
int getWhen() Returns the timestamp of when this event occurred. The higher the timestamp, the more recently the event occurred.
boolean isAltDown()
boolean isControlDown()
boolean isMetaDown()
boolean isShiftDown()
Return the state of individual modifier keys at the time the event was fired.
int getModifiers() Returns the state of all the modifier keys and mouse buttons when the event was fired. You can use this method to determine which mouse button was pressed (or released) when a mouse event was fired. The InputEvent class defines these constants for use with the getModifiers method: ALT_MASK, BUTTON1_MASK, BUTTON2_MASK, BUTTON3_MASK, CTRL_MASK, META_MASK, and SHIFT_MASK. For example, the following expression is true if the right button was pressed:
(mouseEvent.getModifiers() & InputEvent.BUTTON3_MASK)
== InputEvent.BUTTON3_MASK
int getModifiersEx() Returns the extended modifier mask for this event. Extended modifiers represent the state of the mouse button and all modal keys, such as ALT, CTRL, META, just after the event occurred. You can check the status of the modifiers using one of the following predefined bitmasks: SHIFT_DOWN_MASK, CTRL_DOWN_MASK, META_DOWN_MASK, ALT_DOWN_MASK, BUTTON1_DOWN_MASK, BUTTON2_DOWN_MASK, BUTTON3_DOWN_MASK, or ALT_GRAPH_DOWN_MASK. For example, to check that button 1 is down, but that buttons 2 and 3 are up, you would use the following code snippet:
if (event.getModifiersEx() & (BUTTON1_DOWN_MASK |
BUTTON2_DOWN_MASK |
BUTTON3_DOWN_MASK)
== BUTTON1_DOWN_MASK) {
...
}
int getModifiersExText(int) Returns a string describing the extended modifier keys and mouse buttons, such as "Shift", "Button1", or "Ctrl+Shift". These strings can be localized by changing the awt.properties file.

The MouseInfo Class

The MouseInfo class provides methods to obtain information about the mouse pointer location at any time while an application runs.

Method Purpose
getPointerInfo() Returns a PointerInfo instance that represents the current location of the mouse pointer.
getNumberOfButtons()   Returns the number of buttons on the mouse or -1 , if a system does not support a mouse.

Examples That Use Mouse Listeners

The following table lists the examples that use mouse listeners.

Example Notes
MouseEventDemo Reports all mouse events that occur within a blank panel to demonstrate the circumstances under which mouse events are fired.
GlassPaneDemo Uses a subclass of MouseInputAdapter to listen to mouse events and mouse-motion events on the root pane's glass pane. Re-dispatches the events to underlying components.
TableSortDemo Listens to mouse events on a table header. Sorts data in the selected column.
PopupMenuDemo Displays a popup menu in response to mouse clicks.
TrackFocusDemo The custom component, Picture, implements a mouse listener that requests the focus when a user clicks on the component.

4.14 How to Write a Mouse-Motion Listener


ouse-motion events notify when the user uses the mouse (or a similar input device) to move the onscreen cursor. For information on listening for other kinds of mouse events, such as clicks, see How to Write a Mouse Listener. For information on listening for mouse-wheel events.

If an application requires the detection of both mouse events and mouse-motion events, use the MouseInputAdapter class, which implements the MouseInputListener a convenient interface that implements both the MouseListener and MouseMotionListener interfaces.

Alternatively, use the corresponding MouseAdapter AWT class, which implements the MouseMotionListener interface, to create a MouseMotionEvent and override the methods for the specific events.

The following demo code contains a mouse-motion listener. This demo is exactly the same as the demo described in the How to Write a Mouse Listener section, except for substituting the MouseMotionListener interface for the MouseListener interface. Additionally, MouseMotionEventDemo implements the mouseDragged and mouseMoved methods instead of the mouse listener methods, and displays coordinates instead of numbers of clicks.

Oracle JAva Guides, Oracle Java Tutorials and Materials

Try this: 

1. Click the Launch button to run MouseMotionEventDemo using Java™ Web Start (download JDK 7 or later). 
2. Move the cursor into the yellow rectangle at the top of the window.
You will see one or more mouse-moved events.
3. Press and hold the mouse button, and then move the mouse so that the cursor is outside the yellow rectangle.
You will see mouse-dragged events.

You can find the demo's code in MouseMotionEventDemo.java and BlankArea.java. The following code snippet from MouseMotionEventDemo implements the mouse-motion event handling:

public class MouseMotionEventDemo extends JPanel 
                                  implements MouseMotionListener {
    //...in initialization code:
        //Register for mouse events on blankArea and panel.
        blankArea.addMouseMotionListener(this);
        addMouseMotionListener(this);
        ...
    }

    public void mouseMoved(MouseEvent e) {
       saySomething("Mouse moved", e);
    }

    public void mouseDragged(MouseEvent e) {
       saySomething("Mouse dragged", e);
    }

    void saySomething(String eventDescription, MouseEvent e) {
        textArea.append(eventDescription 
                        + " (" + e.getX() + "," + e.getY() + ")"
                        + " detected on "
                        + e.getComponent().getClass().getName()
                        + newline);
    }
}

The SelectionDemo example, draws a rectangle illustrating the user's current dragging. To draw the rectangle, the application must implement an event handler for three kinds of mouse events: mouse presses, mouse drags, and mouse releases. To be informed of all these events, the handler must implement both the MouseListener and MouseMotionListener interfaces, and be registered as both a mouse listener and a mouse-motion listener. To avoid having to define empty methods, the handler doesn't implement either listener interface directly. Instead, it extends MouseInputAdapter, as the following code snippet shows.

...//where initialization occurs:
    MyListener myListener = new MyListener();
    addMouseListener(myListener);
    addMouseMotionListener(myListener);
...
private class MyListener extends MouseInputAdapter {
    public void mousePressed(MouseEvent e) {
        int x = e.getX();
        int y = e.getY();
        currentRect = new Rectangle(x, y, 0, 0);
        updateDrawableRect(getWidth(), getHeight());
        repaint();
    }

    public void mouseDragged(MouseEvent e) {
        updateSize(e);
    }

    public void mouseReleased(MouseEvent e) {
        updateSize(e);
    }

    void updateSize(MouseEvent e) {
        int x = e.getX();
        int y = e.getY();
        currentRect.setSize(x - currentRect.x,
                            y - currentRect.y);
        updateDrawableRect(getWidth(), getHeight());
        Rectangle totalRepaint = rectToDraw.union(previouseRectDrawn); 
        repaint(totalRepaint.x, totalRepaint.y,
                totalRepaint.width, totalRepaint.height);
    }
}

The Mouse-Motion Listener API

The MouseMotionListener Interface

The corresponding adapter classes are MouseMotionAdapter and MouseAdapter.

Method Purpose 
mouseDragged(MouseEvent) Called in response to the user moving the mouse while holding a mouse button down. This event is fired by the component that fired the most recent mouse-pressed event, even if the cursor is no longer over that component.
mouseMoved(MouseEvent) Called in response to the user moving the mouse with no mouse buttons pressed. This event is fired by the component that's currently under the cursor. 

Each mouse-motion event method has a single parameter — and it's not called MouseMotionEvent! Instead, each mouse-motion event method uses a MouseEvent argument. See The MouseEvent API for information about using MouseEvent objects.

Examples That Use Mouse-Motion Listeners

The following table lists the examples that use mouse-motion listeners.

Example Notes
MouseMotionEventDemo Reports all mouse motion events that occur within a blank panel to demonstrate the circumstances under which mouse motion events are fired.
LayeredPaneDemo and
LayeredPaneDemo2
Moves an image of Duke around within a layered pane in response to mouse motion events.
SelectionDemo Lets the user drag a rectangle to select a portion of an image. Uses a subclass of MouseInputAdapter to listen to both mouse events and mouse-motion events.
GlassPaneDemo Uses a subclass of MouseInputAdapter to listen to mouse events and mouse-motion events on the root pane's glass pane. Redispatches the events to underlying components.
ScrollDemo The label subclass, ScrollablePicture, uses a mouse-motion listener to allow the user to scroll the picture even when the user drags the cursor outside the window.

4.15 How to Write a Mouse-Wheel Listener


Mouse-wheel events notify when the wheel on the mouse rotates.There is no way to programmatically detect whether the mouse is equipped with a mouse wheel.

Alternatively, use the corresponding MouseAdapter AWT class, which implements the MouseWheelListener interface, to create a MouseWheelEvent and override the methods for the specific events.

Usually it is not necessary to implement a mouse-wheel listener because the mouse wheel is used primarily for scrolling. Scroll panes automatically register mouse-wheel listeners that react to the mouse wheel appropriately.

However, to create a custom component to be used inside a scroll pane you may need to customize its scrolling behavior — specifically you might need to set the unit and block increments. For a text area, for example, scrolling one unit means scrolling by one line of text. A block increment typically scrolls an entire "page", or the size of the viewport.

To generate mouse-wheel events, the cursor must be over the component registered to listen for mouse-wheel events. The type of scrolling that occurs, either WHEEL_UNIT_SCROLL or WHEEL_BLOCK_SCROLL, is platform dependent. The amount that the mouse wheel scrolls is also platform dependent. Both the type and amount of scrolling can be set via the mouse control panel for the platform.

The following example demonstrates mouse-wheel events.

Writing Event Listeners, Oracle Java Certifications, Oracle Java Guides

Try this: 
1. Click the Launch button to run MouseWheelEventDemo using Java™ Web Start (download JDK 7 or later). 
2. Move the cursor over the text area.
3. Rotate the mouse wheel away from you. You will see one or more mouse-wheel events in the up direction.
4. Rotate the mouse wheel in the opposite direction. You will see mouse-wheel events in the down direction.
5. Try changing your mouse wheel's scrolling behavior your system's mouse control panel to see how the output changes. You should not need to restart the demo to see the changes take effect.

The output from MouseWheelEventDemo for a system that uses unit increments for its mouse wheel might look as follows:

javax.swing.JTextArea: Mouse wheel moved UP 1 notch(es)
    Scroll type: WHEEL_UNIT_SCROLL
    Scroll amount: 3 unit increments per notch
    Units to scroll: -3 unit increments
    Vertical unit increment: 16 pixels

The scroll amount, returned by the getScrollAmount method, indicates how many units will be scrolled and always presents a positive number. The units to scroll, returned by the getUnitsToScroll method, are positive when scrolling down and negative when scrolling up. The number of pixels for the vertical unit is obtained from the vertical scroll bar using the getUnitIncrement method. In the preceding example, rolling the mouse wheel one notch upward should result in the text area scrolling upward 48 pixels (3x16).

For a system that uses block increments for mouse-wheel scrolling, for the same movement of the mouse wheel the output might look as follows:

javax.swing.JTextArea: Mouse wheel moved UP 1 notch(es)
    Scroll type: WHEEL_BLOCK_SCROLL
    Vertical block increment: 307 pixels

The vertical block increment is obtained from the vertical scroll bar using the getBlockIncrement method. In this case, rolling the mouse wheel upward one notch means that the text area should scroll upward 307 pixels.

Find the demo's code in the MouseWheelEventDemo.java file. The following code snippet is related to the mouse-wheel event handling:

public class MouseWheelEventDemo ... implements MouseWheelListener ... {
    public MouseWheelEventDemo() {
        //where initialization occurs:
        //Register for mouse-wheel events on the text area.
        textArea.addMouseWheelListener(this);
        ...
    }

    public void mouseWheelMoved(MouseWheelEvent e) {
       String message;
       int notches = e.getWheelRotation();
       if (notches < 0) {
           message = "Mouse wheel moved UP "
                        + -notches + " notch(es)" + newline;
       } else {
           message = "Mouse wheel moved DOWN "
                        + notches + " notch(es)" + newline;
       }
       if (e.getScrollType() == MouseWheelEvent.WHEEL_UNIT_SCROLL) {
           message += "    Scroll type: WHEEL_UNIT_SCROLL" + newline;
           message += "    Scroll amount: " + e.getScrollAmount()
                   + " unit increments per notch" + newline;
           message += "    Units to scroll: " + e.getUnitsToScroll()
                   + " unit increments" + newline;
           message += "    Vertical unit increment: "
               + scrollPane.getVerticalScrollBar().getUnitIncrement(1)
               + " pixels" + newline;
       } else { //scroll type == MouseWheelEvent.WHEEL_BLOCK_SCROLL
           message += "    Scroll type: WHEEL_BLOCK_SCROLL" + newline;
           message += "    Vertical block increment: "
               + scrollPane.getVerticalScrollBar().getBlockIncrement(1)
               + " pixels" + newline;
       }
       saySomething(message, e);
    }
    ...
}

The Mouse Wheel Listener API

The MouseWheelListener Interface

Although MouseWheelListener has only one method, it has the corresponding adapter class — MouseAdapter. This capability enables an application to have only one adapter class instance for the component to manage all types of events from the mouse pointer.

Method Purpose 
mouseWheelMoved(MouseWheelEvent) Called when the mouse wheel is rotated.

The MouseWheelEvent Class

Method Purpose
int getScrollType() Returns the type of scrolling to be used. Possible values are WHEEL_BLOCK_SCROLL and WHEEL_UNIT_SCROLL, and are determined by the native platform.
int getWheelRotation() Returns the number of notches the mouse wheel was rotated. If the mouse wheel rotated towards the user (down) the value is positive. If the mouse wheel rotated away from the user (up) the value is negative. 
int getScrollAmount() Returns the number of units that should be scrolled per notch. This is always a positive number and is only valid if the scroll type is MouseWheelEvent.WHEEL_UNIT_SCROLL. 
int getUnitsToScroll() Returns the positive or negative units to scroll for the current event. This is only valid when the scroll type is MouseWheelEvent.WHEEL_UNIT_SCROLL. 

Examples That Use Mouse Wheel Listeners

The following table lists the examples that use mouse-wheel listeners.

Example: MouseWheelEventDemo
Notes: Reports all mouse wheel events that occur within a text area to demonstrate the circumstances under which mouse wheel events are fired.

4.16 How to Write a Property Change Listener


Property-change events occur whenever the value of a bound property changes for a bean — a component that conforms to the JavaBeans™ specification. You can find out more about beans from the JavaBeans trail of the Java Tutorial. All Swing components are also beans.

A JavaBeans property is accessed through its get and set methods. For example, JComponent has the property font which is accessible through the getFont and setFont methods.

Besides the get and set methods, a bound property fires a property-change event when its value changes. For more information, see the Bound Properties page in the JavaBeans trail.

Some scenarios that commonly require property-change listeners include:

◉ You have implemented a formatted text field and need a way to detect when the user has entered a new value. You can register a property-change listener on the formatted text field to listen to changes on the value property.
◉ You have implemented a dialog and need to know when a user has clicked one of the dialog's buttons or changed a selection in the dialog. DialogDemo in How to Make Dialogs for an example of registering a property-change listener on an option pane to listen to changes to the value property. You can also check out FileChooserDemo2 in How to Use File Choosers for an example of how to register a property-change listener to listen to changes to the directoryChanged and selectedFileChanged properties.
◉ You need to be notified when the component that has the focus changes. You can register a property-change listener on the keyboard focus manager to listen to changes to the focusOwner property. See TrackFocusDemo and DragPictureDemo in How to Use the Focus Subsystem for examples of this.
Although these are some of the more common uses for property-change listeners, you can register a property-change listener on the bound property of any component that conforms to the JavaBeans specification.

You can register a property change listener in two ways. The first uses the method addPropertyChangeListener(PropertyChangeListener). When you register a listener this way, you are notified of every change to every bound property for that object. In the propertyChange method, you can get the name of the property that has changed using the PropertyChangeEvent getPropertyName method, as in the following code snippet:

KeyboardFocusManager focusManager =
   KeyboardFocusManager.getCurrentKeyboardFocusManager();
focusManager.addPropertyChangeListener(new FocusManagerListener());
...
public FocusManagerListener implements PropertyChangeListener {
    public void propertyChange(PropertyChangeEvent e) {
        String propertyName = e.getPropertyName();
        if ("focusOwner".equals(propertyName) {
            ...
        } else if ("focusedWindow".equals(propertyName) {
            ...
        }
    }
    ...
}

The second way to register a property change listener uses the method addPropertyChangeListener(String, PropertyChangeListener). The String argument is the name of a property. Using this method means that you only receive notification when a change occurs to that particular property. So, for example, if you registered a property change listener like this:

aComponent.addPropertyChangeListener("font",
                                     new FontListener());
FontListener only receives notification when the value of the component's font property changes. It does not receive notification when the value changes for transferHandler, opaque, border, or any other property.

The following example shows how to register a property change listener on the value property of a formatted text field using the two-argument version of addPropertyChangeListener:

//...where initialization occurs:
double amount;
JFormattedTextField amountField;
...
amountField.addPropertyChangeListener("value",
                                      new FormattedTextFieldListener());
...
class FormattedTextFieldListener implements PropertyChangeListener {
    public void propertyChanged(PropertyChangeEvent e) {
        Object source = e.getSource();
        if (source == amountField) {
            amount = ((Number)amountField.getValue()).doubleValue();
            ...
        }
        ...//re-compute payment and update field...
    }
}

The Property Change Listener API

Registering a PropertyChangeListener

Method Purpose 
addPropertyChangeListener(PropertyChangeListener) Add a property-change listener to the listener list. 
addPropertyChangeListener(String, PropertyChangeListener) Add a property-change listener for a specific property. The listener is called only when there is a change to the specified property. 

The PropertyChangeListener Interface

Because PropertyChangeListener has only one method, it has no corresponding adapter class.

Method Purpose 
propertyChange(PropertyChangeEvent) Called when the listened-to bean changes a bound property.

The PropertyChangeEvent Class

Method Purpose
Object getNewValue()
Object getOldValue()
Return the new, or old, value of the property, respectively. 
String getPropertyName()  Return the name of the property that was changed. 
void setPropagationId()  Get or set the propagation ID value. Reserved for future use. 

Examples that Use Property Change Listeners

The following table lists the examples that use property-change listeners.

Example Notes
FormattedTextFieldDemo A property-change listener is registered on several formatted text fields to track changes to the value property.
DialogDemo The CustomDialog class registers a property-change listener on an option pane to listen to the value and inputValue properties.
FileChooserDemo2 The ImagePreview class registers a property-change listener on the file chooser to listen to the directoryChanged and selectedFileChanged properties
TrackFocusDemo A property-change listener is registered on the keyboard focus manager to track changes to the focusOwner property.

4.17 How to Write a Table Model Listener


Upon instantiation, each JTable object is passed a table model object that manages the data it displays. By default, a JTable object inherits a DefaultTable object if no custom TableModel object is specified, but by default, this model only manages strings. To handle objects, perform calculations, or to retrieve data from databases or other programs, you must design your own custom TableModel object, which implements the TableModel interface.

To detect changes to the data managed by a table model object, the JTable class needs to implement the TableModelListener interface, call addTableModelListener() to catch events, and then override tableChanged() to respond to listener events.

The Table Model Listener API

The TableModelListener Interface

Because TableModelListener has only one method, it has no corresponding adapter class.

Method Purpose 
tableChanged(TableModelEvent) Called when the structure of or data in the table has changed. 

The TableModelEvent API

Method Purpose
Object getSource()
(in java.util.EventObject)
Return the object that fired the event. 
int getFirstRow()  Return the index of the first row that changed. TableModelEvent.HEADER_ROW specifies the table header. 
int getLastRow()  The last row that changed. Again, HEADER_ROW is a possible value. 
int getColumn() Return the index of the column that changed. The constant TableModelEvent. ALL_COLUMNS specifies that all the columns might have changed. 
int getType() What happened to the changed cells. The returned value is one of the following: TableModelEvent.INSERT, TableModelEvent.DELETE, or TableModelEvent.UPDATE. 

4.18 How to Write a Tree Expansion Listener


Sometimes when using a tree, you might need to react when a branch becomes expanded or collapsed. For example, you might need to load or save data.

Two kinds of listeners report expansion and collapse occurrences: tree expansion listeners and tree-will-expand listeners. This page discusses tree expansion listeners.

A tree expansion listener detects when an expansion or collapse has already occured. In general, you should implement a tree expansion listener unless you need to prevent an expansion or collapse from ocurring .

This example demonstrates a simple tree expansion listener. The text area at the bottom of the window displays a message every time a tree expansion event occurs. It's a straightforward, simple demo.

Oracle Java Tutorials and Materials, Oracle Java Guides, Oracle Java Learning

Try this: 

1. Click the Launch button to run TreeExpandEventDemo using Java™ Web Start (download JDK 7 or later). Alternatively, to compile and run the example yourself, consult the example index.Launches the TreeExpandEventDemo example

2. Expand a node. A tree-expanded event is fired.
3. Collapse the node. A tree-collapsed event is fired.

The following code shows how the program handles expansion events. You can find the source code for this example in TreeExpandEventDemo.java.

public class TreeExpandEventDemo ... {
    ...
    void saySomething(String eventDescription, TreeExpansionEvent e) {
        textArea.append(eventDescription + "; "
                        + "path = " + e.getPath()
                        + newline);
    }

    class DemoArea ... implements TreeExpansionListener {
        ...
        public DemoArea() {
            ...
            tree.addTreeExpansionListener(this);
            ...
        }
        ...
        // Required by TreeExpansionListener interface.
        public void treeExpanded(TreeExpansionEvent e) {
            saySomething("Tree-expanded event detected", e);
        }

        // Required by TreeExpansionListener interface.
        public void treeCollapsed(TreeExpansionEvent e) {
            saySomething("Tree-collapsed event detected", e);
        }
    }
}

The Tree Expansion Listener API

The TreeExpansionListener Interface

TreeExpansionListener has no adapter class.

Method Purpose
treeCollapsed(TreeExpansionEvent) Called just after a tree node collapses. 
treeExpanded(TreeExpansionEvent)   Called just after a tree node expands. 

The TreeExpansionEvent API

Method Purpose
Object getSource() Return the object that fired the event.
TreePath getPath() Returns a TreePath object that identifies each node from the root of the tree to the collapsed/expanded node, inclusive.

Examples that Use Tree Expansion Listeners

The following table lists the examples that use tree expansion listeners.

Example Notes
TreeExpandEventDemo Displays a message whenever a tree expansion event occurs.
TreeExpandEventDemo2 Adds a tree-will-expand listener to TreeExpandEventDemo.

4.19 How to Write a Tree Model Listener

By implementing a tree model listener, you can detect when the data displayed by a tree changes. You can use a tree model listener to detect when the user edits tree nodes. All notifications describe changes relative to a node in the tree.

The Tree Model Listener API

The TreeModelListener Interface

TreeModelListener has no adapter class.

Method Purpose 
treeNodesChanged(TreeModelEvent) Called when one or more sibling nodes have changed in some way. 
treeNodesInserted(TreeModelEvent)  Called after nodes have been inserted into the tree. 
treeNodesRemoved(TreeModelEvent)  Called after nodes have been removed from the tree. 
treeStructureChanged(TreeModelEvent) Called after the tree's structure has drastically changed from the current node on down. This event applies to all nodes connected to this node. 

The TreeModelEvent API

Method Purpose 
Object getSource()
(in java.util.EventObject)
Return the object that fired the event.
int[] getChildIndices() For treeNodesChanged, treeNodesInserted, and treeNodesRemoved, returns the indices of the changed, inserted, or deleted nodes, respectively. Returns nothing useful for treeStructureChanged.
Object[] getChildren() Returns the objects corresponding to the child indices.
Object[] getPath() Returns the path to the parent of the changed, inserted, or deleted nodes. For treeStructureChanged, returns the path to the node beneath which the structure has changed.
TreePath getTreePath() Returns the same thing as getPath, but as a TreePath object.

Examples that Use Tree Model Listeners

The following table lists the examples that use tree expansion listeners.

Example: DynamicTreeDemo

Notes: The DynamicTree class implements a tree model listener to detect when the user has edited a node's data.

4.20 How to Write a Tree Selection Listener


To detect when the user selects a node in a tree, you need to register a tree selection listener. Here is an example, taken from the TreeDemo example discussed in Responding to Node Selection, of detecting node selection in a tree that can have at most one node selected at a time:

tree.addTreeSelectionListener(new TreeSelectionListener() {
    public void valueChanged(TreeSelectionEvent e) {
        DefaultMutableTreeNode node = (DefaultMutableTreeNode)
                           tree.getLastSelectedPathComponent();

    /* if nothing is selected */ 
        if (node == null) return;

    /* retrieve the node that was selected */ 
        Object nodeInfo = node.getUserObject();
        ...
    /* React to the node selection. */
        ...
    }
});

To specify that the tree should support single selection, the program uses this code:

tree.getSelectionModel().setSelectionMode
        (TreeSelectionModel.SINGLE_TREE_SELECTION);
The TreeSelectionModel interface defines three values for the selection mode:

DISCONTIGUOUS_TREE_SELECTION
This is the default mode for the default tree selection model. With this mode, any combination of nodes can be selected.
SINGLE_TREE_SELECTION
This is the mode used by the preceding example. At most one node can be selected at a time.
CONTIGUOUS_TREE_SELECTION
With this mode, only nodes in adjoining rows can be selected.

The Tree Selection Listener API

The TreeSelectionListener Interface

Because TreeSelectionListener has only one method, it has no corresponding adapter class.

Method Purpose 
valueChanged(TreeSelectionEvent) Called whenever the selection changes.

The TreeSelectionEvent API

Method Purpose 
Object getSource()
(in java.util.EventObject) 
Return the object that fired the event.
TreePath getNewLeadSelectionPath()  Return the current lead path. 
TreePath getOldLeadSelectionPath()  Return the path that was previously the lead path. 
TreePath getPath()  Return the first path element. 
TreePath[] getPaths()  Return the paths that have been added or removed from the selection. 
boolean isAddedPath()  Return true if the first path element has been added to the selection. Returns false if the first path has been removed from the selection. 
boolean isAddedPath(int)  Return true if the path specified by the index was added to the selection. 
boolean isAddedPath(TreePath)  Return true if the specified path was added to the selection. 
Object getLastSelectedPathComponent()   Return the last path component in the first node of the current selection. 
TreePath getLeadSelectionPath()
(in JTree) 
Return the current lead path. 

Examples that Use Tree Selection Listeners

The following table lists the examples that use tree selection listeners.

Example: TreeDemo

Notes: The tree listener responds to node clicks by showing the appropriate HTML document.

4.21 How to Write a Tree-Will-Expand Listener


The tree-will-expand listener prevents a tree node from expanding or collapsing. To be notified just after an expansion or collapse occurs, you should use a tree expansion listener instead.

This demo adds a tree-will-expand listener to the TreeExpandEventDemo example discussed in How to Write a Tree Expansion Listener. The code added here demonstrates that tree-will-expand listeners prevent node expansions and collapses: The listener will prompt you for confirmation each time you try to expand a node.

Writing Event Listeners, Oracle Java Tutorials and Materials

Try this: 

1. Click the Launch button to run TreeExpandEventDemo2 using Java™ Web Start (download JDK 7 or later). Alternatively, to compile and run the example yourself, consult the example index.Launches the TreeExpandEventDemo2 example
2. Click the graphic to the left of the Potrero Hill node. This tells the tree that you want to expand the node.
A dialog appears asking you whether you really want to expand the node.
3. Click "Expand" or dismiss the dialog.
Messages in the text area tell you that both a tree-will-expand event and a tree-expanded event have occurred. At the end of each message is the path to the expanded node.
4. Try to expand another node, but this time press the "Cancel Expansion" button in the dialog.
The node does not expand. Messages in the text area tell you that a tree-will-expand event occurred, and that you cancelled a tree expansion.
5. Collapse the Potrero Hill node.
The node collapses without a dialog appearing, because the event handler's treeWillCollapse method lets the collapse occur, uncontested.

The following snippet shows the code that this program adds to TreeExpandEventDemo. The bold line prevents the tree expansion from happening. You can find all the demo's source code in TreeExpandEventDemo2.java.

public class TreeExpandEventDemo2 ... {
    ...
    class DemoArea ... implements ... TreeWillExpandListener {
        ...
        public DemoArea() {
            ...
            tree.addTreeWillExpandListener(this);
            ...
        }
        ...
        //Required by TreeWillExpandListener interface.
        public void treeWillExpand(TreeExpansionEvent e) 
                    throws ExpandVetoException {
            saySomething("Tree-will-expand event detected", e);
            //...show a dialog...
            if (/* user said to cancel the expansion */) {
                //Cancel expansion.
                saySomething("Tree expansion cancelled", e);
                throw new ExpandVetoException(e);
            }
        }

        //Required by TreeWillExpandListener interface.
        public void treeWillCollapse(TreeExpansionEvent e) {
            saySomething("Tree-will-collapse event detected", e);
        }
        ...
    }
}

The Tree-Will-Expand Listener API

The TreeWillExpandListener Interface

TreeWillExpandListener has no adapter class.

Method Purpose 
treeWillCollapse(TreeExpansionEvent) Called just before a tree node collapses. To prevent the collapse from occurring, your implementation of this method should throw a ExpandVetoException event. 
treeWillExpand(TreeExpansionEvent) Called just before a tree node expands. To prevent the expansion from occurring, your implementation of this method should throw a ExpandVetoException event. 

Examples that Use Tree-Will-Expand Listeners

TreeExpandEventDemo2, featured in this section, is our only example that uses a tree-will-expand listener.

4.22 How to Write an Undoable Edit Listener


Undoable edit events occur when an operation that can be undone occurs on a component. Currently, only text components fire undoable edit events, and then only indirectly. The text component's document fires the events. For text components, undoable operations include inserting characters, deleting characters, and modifying the style of text. Programs typically listen to undoable edit events to assist in the implementation of undo and redo commands.

Here is the undoable edit event handling code from an application called TextComponentDemo.
...
//where initialization occurs
document.addUndoableEditListener(new MyUndoableEditListener());
...
protected class MyUndoableEditListener implements UndoableEditListener {
    public void undoableEditHappened(UndoableEditEvent e) {
        //Remember the edit and update the menus
        undo.addEdit(e.getEdit());
        undoAction.updateUndoState();
        redoAction.updateRedoState();
    }
}  

You can find a link to the source file for TextComponentDemo in the example index for Using Swing Components.

The Undoable Edit Listener API
The UndoableEditListener Interface

Because UndoableEditListener has only one method, it has no corresponding adapter class.

Method Purpose 
undoableEditHappened(UndoableEditEvent) Called when an undoable event occurs on the listened-to component. 

The UndoableEditEvent Class

Method Purpose 
Object getSource()
(in java.util.EventObject)
Return the object that fired the event. 
UndoableEdit getEdit() Returns an UndoableEdit object that represents the edit that occurred and contains information about and commands for undoing or redoing the edit. 

Examples that Use Undoable Edit Listeners

The following table lists the examples that use undoable edit listeners.

Example: TextComponentDemo

Note: Implements undo and redo on a text pane with help from an undoable edit listener.

4.23 How to Write Window Listeners

This section explains how to implement three kinds of window-related event handlers: WindowListener, WindowFocusListener, and WindowStateListener. All three listeners handle WindowEvent objects. The methods in all three event handlers are implemented by the abstract WindowAdapter class.

When the appropriate listener has been registered on a window, window events are fired just after the window activity or state has occurred. A window is considered as a "focus owner", if this window receives keyboard input.

The following window activities or states can precede a window event:

◈ Opening a window — Showing a window for the first time.
◈ Closing a window — Removing the window from the screen.
◈ Iconifying a window — Reducing the window to an icon on the desktop.
◈ Deiconifying a window — Restoring the window to its original size.
◈ Focused window — The window which contains the "focus owner".
◈ Activated window (frame or dialog) — This window is either the focused window, or owns the focused window.
◈ Deactivated window — This window has lost the focus. For more information about focus, see the AWT Focus Subsystem specification.
◈ Maximizing the window — Increasing a window's size to the maximum allowable size, either in the vertical direction, the horizontal direction, or both directions.

The WindowListener interface defines methods that handle most window events, such as the events for opening and closing the window, activation and deactivation of the window, and iconification and deiconification of the window.

The other two window listener interfaces are WindowFocusListener and WindowStateListener. WindowFocusListener contains methods to detect when the window becomes the focus owner or it loses the focus owner status. WindowStateListener has a single method to detect a change to the state of the window, such as when the window is iconified, deiconified, maximized, or restored to normal.

While you can use the WindowListener methods to detect some window states, such as iconification, there are two reasons why a WindowStateListener might be preferable: it has only one method for you to implement, and it provides support for maximization.

Note: Not all window managers/native platforms support all window states. The java.awt.Toolkit method isFrameStateSupported(int) can be used to determine whether a particular window state is supported by a particular window manager. The WindowEventDemo example, described later in this section, shows how this method can be used.
Window listeners are commonly used to implement custom window-closing behavior. For example, a window listener is used to save data before closing the window, or to exit the program when the last window closes.

A user does not necessarily need to implement a window listener to specify what a window should do when the user closes it. By default, when the user closes a window the window becomes invisible. To specify different behavior, use the setDefaultCloseOperation method of the JFrame or JDialog classes. To implement a window-closing handler, use the setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE) method to enable the window listener to provide all window-closing duties. See Responding to Window-Closing Events for details on how to use setDefaultCloseOperation.

When the last displayable window within the Java virtual machine (VM) is disposed of, the VM may terminate. Note, however, that there can be a delay before the program exits automatically, and that under some circumstances the program might keep running. It is quicker and safer to explicitly exit the program using System.exit(int). See AWT Threading Issues for more information.
Window listeners are also commonly used to stop threads and release resources when a window is iconified, and to start up again when the window is deiconified. This avoids unnecessarily using the processor or other resources. For example, when a window that contains animation is iconified, it should stop its animation thread and free any large buffers. When the window is deiconified, it can start the thread again and recreate the buffers.

The following example demonstrates window events. A non-editable text area reports all window events that are fired by its window. This demo implements all methods in the WindowListener, WindowFocusListener, and WindowStateListener interfaces. You can find the demo's code in WindowEventDemo.java.


Try this: 

1. Click the Launch button to run WindowEventDemo using Java™ Web Start (download JDK 7 or later). 
2. When the window appears, several messages are already displayed. One line reports whether your window manager supports MAXIMIZED_BOTH. If the window manager does not support other window states, this condition is also reported. Next, several lines are displayed, reporting that the window's window listener has received window-opened, activated, and gained-focus events. All the messages displayed in the window are also sent to standard output.
3. Click another window. The "window lost focus" and "window deactivated" messages will be displayed. If this window is not a frame or a dialog, it will receive the activated or deactivated events.
4. Click the WindowEventDemo window. You'll see "window activated" and "window gained focus" messages.
5. Iconify the window, using the window controls. Two iconification messages are displayed, one from the window listener and the other from the window state listener. Unless you are looking at standard output, the messages will not display until the window is deiconified. Window-deactivation and window-lost-focus events are also reported.
6. De-iconify the window. Two deiconification messages are displayed, one from the window listener and the other from the window state listener. The windowStateChanged method in WindowStateListener class gives the same information that you get using the windowIconified and windowDeiconified methods in WindowListener class. Window-activation and window-gained-focus events are also reported.
7. Maximize the window, if your look and feel provides a way to do so. Note that some look and feels running on some window managers, such as the Java look and feel on dtwm, provide a way to maximize the window, but no events are reported. This is because dtwm mimics maximization by resizing the window, but it is not a true maximization event. Some look and feels provide a way to maximize the window in the vertical or horizontal direction only. Experiment with your window controls to see what options are available.
8. Close the window, using the window controls. A window closing message is displayed. Once the window has closed, a window closed message is sent to standard output.
Here is the demo's window event handling code:

public class WindowEventDemo extends JFrame implements WindowListener,
                                            WindowFocusListener,
                                            WindowStateListener {
    ...
    static WindowEventDemo frame = new WindowEventDemo("WindowEventDemo");
    JTextArea display;
    ...

    private void addComponentsToPane() {
        display = new JTextArea();
        display.setEditable(false);
        JScrollPane scrollPane = new JScrollPane(display);
        scrollPane.setPreferredSize(new Dimension(500, 450));
        getContentPane().add(scrollPane, BorderLayout.CENTER);
        
        addWindowListener(this);
        addWindowFocusListener(this);
        addWindowStateListener(this);
        
        checkWM();
    }
    
    public WindowEventDemo(String name) {
        super(name);
    }

    //Some window managers don't support all window states.
  
    public void checkWM() {
        Toolkit tk = frame.getToolkit();
        if (!(tk.isFrameStateSupported(Frame.ICONIFIED))) {
            displayMessage(
                    "Your window manager doesn't support ICONIFIED.");
        }  else displayMessage(
                "Your window manager supports ICONIFIED.");
        if (!(tk.isFrameStateSupported(Frame.MAXIMIZED_VERT))) {
            displayMessage(
                    "Your window manager doesn't support MAXIMIZED_VERT.");
        }  else displayMessage(
                "Your window manager supports MAXIMIZED_VERT.");
        if (!(tk.isFrameStateSupported(Frame.MAXIMIZED_HORIZ))) {
            displayMessage(
                    "Your window manager doesn't support MAXIMIZED_HORIZ.");
        } else displayMessage(
                "Your window manager supports MAXIMIZED_HORIZ.");
        if (!(tk.isFrameStateSupported(Frame.MAXIMIZED_BOTH))) {
            displayMessage(
                    "Your window manager doesn't support MAXIMIZED_BOTH.");
        } else {
            displayMessage(
                    "Your window manager supports MAXIMIZED_BOTH.");
        }
    }

    public void windowClosing(WindowEvent e) {
        displayMessage("WindowListener method called: windowClosing.");
        //A pause so user can see the message before
        //the window actually closes.
        ActionListener task = new ActionListener() {
            boolean alreadyDisposed = false;
            public void actionPerformed(ActionEvent e) {
                if (frame.isDisplayable()) {
                    alreadyDisposed = true;
                    frame.dispose();
                }
            }
        };
        Timer timer = new Timer(500, task); //fire every half second
        timer.setInitialDelay(2000);        //first delay 2 seconds
        timer.setRepeats(false);
        timer.start();
    }

    public void windowClosed(WindowEvent e) {
        //This will only be seen on standard output.
        displayMessage("WindowListener method called: windowClosed.");
    }

    public void windowOpened(WindowEvent e) {
        displayMessage("WindowListener method called: windowOpened.");
    }

    public void windowIconified(WindowEvent e) {
        displayMessage("WindowListener method called: windowIconified.");
    }

    public void windowDeiconified(WindowEvent e) {
        displayMessage("WindowListener method called: windowDeiconified.");
    }

    public void windowActivated(WindowEvent e) {
        displayMessage("WindowListener method called: windowActivated.");
    }

    public void windowDeactivated(WindowEvent e) {
        displayMessage("WindowListener method called: windowDeactivated.");
    }

    public void windowGainedFocus(WindowEvent e) {
        displayMessage("WindowFocusListener method called: windowGainedFocus.");
    }

    public void windowLostFocus(WindowEvent e) {
        displayMessage("WindowFocusListener method called: windowLostFocus.");
    }

    public void windowStateChanged(WindowEvent e) {
        displayStateMessage(
          "WindowStateListener method called: windowStateChanged.", e);
    }

    void displayMessage(String msg) {
        display.append(msg + newline);
        System.out.println(msg);
    }

    void displayStateMessage(String prefix, WindowEvent e) {
        int state = e.getNewState();
        int oldState = e.getOldState();
        String msg = prefix
                   + newline + space
                   + "New state: "
                   + convertStateToString(state)
                   + newline + space
                   + "Old state: "
                   + convertStateToString(oldState);
        displayMessage(msg);
    }

    String convertStateToString(int state) {
        if (state == Frame.NORMAL) {
            return "NORMAL";
        }
        String strState = " ";
        if ((state & Frame.ICONIFIED) != 0) {
            strState += "ICONIFIED";
        }
        //MAXIMIZED_BOTH is a concatenation of two bits, so
        //we need to test for an exact match.
        if ((state & Frame.MAXIMIZED_BOTH) == Frame.MAXIMIZED_BOTH) {
            strState += "MAXIMIZED_BOTH";
        } else {
            if ((state & Frame.MAXIMIZED_VERT) != 0) {
                strState += "MAXIMIZED_VERT";
            }
            if ((state & Frame.MAXIMIZED_HORIZ) != 0) {
                strState += "MAXIMIZED_HORIZ";
            }
            if (" ".equals(strState)){
                strState = "UNKNOWN";
            }
        }
        return strState.trim();
    }
}

The Window Listener API

The window listener API consists of three window listener interfaces and the WindowEvent class. Their methods are listed in the following tables:

◈ The WindowListener Interface
◈ The WindowFocusListener Interface
◈ The WindowStateListener Interface
◈ The WindowEvent Class

The methods from all three interfaces are available through the WindowAdapter class.

The WindowListener Interface

Method Purpose 
windowOpened(WindowEvent) Called just after the listened-to window has been shown for the first time. 
windowClosing(WindowEvent)  Called in response to a user request for the listened-to window to be closed. To actually close the window, the listener should invoke the window's dispose or setVisible(false) method. 
windowClosed(WindowEvent)  Called just after the listened-to window has closed. 
windowIconified(WindowEvent)
windowDeiconified(WindowEvent) 
Called just after the listened-to window is iconified or deiconified, respectively. 
windowActivated(WindowEvent)
windowDeactivated(WindowEvent)
Called just after the listened-to window is activated or deactivated, respectively. These methods are not sent to windows that are not frames or dialogs. For this reason, the windowGainedFocus and windowLostFocus methods to determine when a window gains or loses the focus are preferred.

The WindowFocusListener Interface

Method Purpose 
windowGainedFocus(WindowEvent)
windowLostFocus(WindowEvent) 
Called just after the listened-to window gains or loses the focus, respectively.

The WindowStateListener Interface

Method Purpose 
windowStateChanged(WindowEvent) Called just after the listened-to window's state is changed by being iconified, deiconified, maximized, or returned to normal. The state is available through the WindowEvent as a bitwise mask. The possible values, defined in java.awt.Frame, are:
  • NORMAL. Indicates that no state bits are set.
  • ICONIFIED.
  • MAXIMIZED_HORIZ.
  • MAXIMIZED_VERT.
  • MAXIMIZED_BOTH. Concatenates MAXIMIZED_HORIZ and MAXIMIZED_VERT. A window manager may support MAXIMIZED_BOTH, while not supporting MAXIMIZED_HORIZ or MAXIMIZED_VERT. The java.awt.Toolkit method isFrameStateSupported(int) can be used to determine what states are supported by the window manager.

The WindowEvent Class

Method Purpose 
Window getWindow() Returns the window that fired the event. You can use this instead of the getSource method. 
Window getOppositeWindow() Returns the other window involved in this focus or activation change. For a WINDOW_ACTIVATED or WINDOW_GAINED_FOCUS event, this returns the window that lost activation or the focus. For a WINDOW_DEACTIVATED or WINDOW_LOST_FOCUS event, this returns the window that gained activation or the focus. For any other type of WindowEvent with a Java application in a different VM or context, or with no other window, null is returned. 
int getOldState()
int getNewState()
For WINDOW_STATE_CHANGED events, these methods return the previous or new state of the window as a bitwise mask. 

Examples that Use Window Listeners

The following table lists the examples that use window listeners.

Example Notes 
WindowEventDemo Reports all window events that occur on one window to demonstrate the circumstances under which window events are fired
SliderDemo Listens for window iconify and deiconify events, so that it can stop the animation when the window isn't visible. 
InternalFrameEventDemo Reports all internal frame events that occur on one internal frame to demonstrate the circumstances under which internal frame events are fired. Internal frame events are similar to window events. 
DialogDemo CustomDialog.java uses setDefaultCloseOperatin instead of a window listener to determine what action to take when the user closes the window. 
Framework A demo that allows multiple windows to be created and destroyed.

«« Previous
Next »»