Previous | Next | Trail Map | Creating a User Interface (with Swing) | Using the JFC/Swing Packages

How to Write a List Selection Listener


Note: This section assumes that you're familiar with the AWT event listener scheme. If you aren't, you can read about it in The 1.1 AWT Event Model(in the Creating a User Interface trail)
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(in the API reference documentation) interface. To get a list or table's list selection model object, use the getSelectionModel method.

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.

List Selection Event Methods

The ListSelectionListener interface has just one method, so it has no corresponding adapter class. Here's the method:
void valueChanged(ListSelectionEvent)
Called when the selection in the listened-to component is changing, as well as just after the selection has changed.

Examples of Handling List Selection Events

The How to Use Lists section provides an example of a listener that listens to events on a single-selection list (not the list's selection model).

This section provides one example that shows how to listen to list selection events on a selection model. The selection model is shared by a list and a table. You can dynamically change the selection mode to any of the three supported modes:

Here's a picture of the example running:


Try this:
  1. Compile and run the application. The main source file is ListSelectionDemo.java. See Getting Started with Swing if you need help.
  2. Select and deselect items in the list and table. The mouse and keyboard commands required to select items depends on the look and feel. For Metal, 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. Dragging the mouse moves or extends the selection, depending on the list selection mode.

Here's the code from ListSelectionDemo.java that sets up the selection model and adds a listener to it:
...//where the member variables are defined
JList list;
JTable table;
    ...//in the init method:
    listSelectionModel = list.getSelectionModel();
    listSelectionModel.addListSelectionListener(
                            new SharedListSelectionHandler());
    ...
    table.setSelectionModel(listSelectionModel);
And here's 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.


Note: The output from this program depends on the version of Swing you are using. Swing 1.0.x contains several bugs and the operation of lists and tables were inconsistent. Later versions of Swing fix these problems.

The ListSelectionEvent Class

Each list selection event method has a single parameter: a ListSelectionEvent(in the API reference documentation) object. The event object tells the listener that the selection changed. One list selection event can indicate a change in selection on multiple, discontiguous items in the list.

To get the source of a ListSelectionEvent, use the getSource method, which ListSelectionEvent inherits from EventObject(in the API reference documentation). 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.

The ListSelectionEvent class defines the following handy methods:

int getFirstIndex()
Returns 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.
int getLastIndex()
Returns 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.
int getValueIsAdjusting()
Returns 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.


Previous | Next | Trail Map | Creating a User Interface (with Swing) | Using the JFC/Swing Packages