Chapter 7. Lists and Combo Boxes
7.3 Handling Selections
7.3.2.6 Working with the ListSelectionModel
The following example is a modified version of our earlier list example. This one, however, has its own ListSelectionListener that reports each of the list selection events as they occur:
// SimpleList2.java // import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.event.*;
public class SimpleList2 extends JPanel implements ListSelectionListener, ActionListener {
String label[] = { "Zero","One","Two","Three","Four","Five","Six", "Seven","Eight","Nine","Ten","Eleven" };
JList list;
public SimpleList2() {
setLayout(new BorderLayout()); list = new JList(label);
JButton button = new JButton("Print"); JScrollPane pane = new JScrollPane(list);
DefaultListSelectionModel m = new DefaultListSelectionModel(); m.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); m.setLeadAnchorNotificationEnabled(false); list.setSelectionModel(m); list.addListSelectionListener(this); button.addActionListener(this); add(pane, BorderLayout.NORTH); add(button, BorderLayout.SOUTH); }
public static void main(String s[]) {
JFrame frame = new JFrame("List Example");
frame.addWindowListener(new BasicWindowMonitor()); frame.setContentPane(new SimpleList2());
frame.pack();
frame.setVisible(true); }
public void valueChanged(ListSelectionEvent e) {
System.out.println(e.toString()); }
public void actionPerformed(ActionEvent e) { int selected[] = list.getSelectedIndices(); System.out.println("Selected Elements: ");
for (int i=0; i < selected.length; i++) { String element = (String)list.getModel().
getElementAt(selected[i]); System.out.println(" " + element);
} } }
Try running this code and selecting a couple of items in the list. If you drag the mouse from item to item 5, you get the following output:
javax.swing.event.ListSelectionEvent[source=javax.swing.JList[,0,0,86x204] firstIndex= 0 lastIndex= 1 isAdjusting= true ]
javax.swing.event.ListSelectionEvent[source=javax.swing.JList[,0,0,86x204] firstIndex= 1 lastIndex= 2 isAdjusting= true ]
javax.swing.event.ListSelectionEvent[source=javax.swing.JList[,0,0,86x204] firstIndex= 2 lastIndex= 3 isAdjusting= true ]
javax.swing.event.ListSelectionEvent[source=javax.swing.JList[,0,0,86x204] firstIndex= 3 lastIndex= 4 isAdjusting= true ]
javax.swing.event.ListSelectionEvent[source=javax.swing.JList[,0,0,86x204] firstIndex= 4 lastIndex= 5 isAdjusting= true ]
javax.swing.event.ListSelectionEvent[source=javax.swing.JList[,0,0,86x204] firstIndex= 5 lastIndex= 5 isAdjusting= false ]
Each entry describes a change in selection. The first five entries recognize that a change of selection has occurred between one element and the next as the mouse was dragged. In this case, the former was deselected, and the latter was selected. However, note that the isAdjusting property was set to true, indicating that this is potentially one in a series of changes. When the mouse button is
released, the list knows that the drag has stopped, and fires a ListSelectionEvent with the isAdjusting property set to false, repeating the last changed index.
7.3.3 ListSelectionEvent
Much like the ListDataEvent, the ListSelectionEvent specifies a change by highlighting those
elements in the selection list that have altered. Note that a ListSelectionEvent does not indicate
the new selection state of the list element, only that some change has occurred. You should not assume that the new state is the opposite of the previous state; always check with the event source to see what the current selection state really is.
7.3.3.1 Properties
There are four properties in the ListSelectionEvent, each with its own read-only accessor, as
shown in Table 7.8.
Table 7.8, ListSelectionEvent Properties
Property Data Type get is set bound Default Value
firstIndex int
lastIndex int
valueIsAdjusting boolean
7.3.3.2 Constructor
public ListSelectionEvent(Object source, int firstIndex, int lastIndex, boolean isAdjusting) Takes a reference to the object that fires the event, as well as the bounding indices and a boolean indicating whether the event is one in a series. Note that firstIndex should always
be less than or equal to lastIndex.
7.3.3.3 Methods
public String toString()
Provides a comma-separated string output of the properties above.
7.3.4 ListSelectionListener
The ListSelectionListener interface, which is the conduit for receiving the
ListSelectionEvent objects, consists of only one method: valueChanged(). This method must
be implemented by any listener object that wishes to be notified of changes to the list selection model.
public abstract void valueChanged(ListSelectionEvent e)
Notifies the listener that one or more selection elements have changed.
7.3.4.1 Listening for ListSelectionEvents
Here is a brief example that demonstrates using the ListSelectionListener and the
ListSelectionEvent. The example creates a series of radio buttons that listen for selection events
and accurately mirror the current selections in the list. Some results from running this program are shown in Figure 7.6. // SelectionMonitor.java // import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.event.*;
public class SelectionMonitor extends JPanel implements ListSelectionListener {
String label[] = { "Zero","One","Two","Three","Four","Five","Six", "Seven","Eight","Nine","Ten","Eleven","Twelve" }; JRadioButton buttons[];
JList list;
public SelectionMonitor() {
setLayout(new BorderLayout()); list = new JList(label);
JScrollPane pane = new JScrollPane(list); buttons = new JRadioButton[label.length];
// Format the list and the buttons in a vertical box Box rightBox = new Box(BoxLayout.Y_AXIS);
Box leftBox = new Box(BoxLayout.Y_AXIS); // Monitor all list selections
list.addListSelectionListener(this); for(int i=0; i < label.length; i++) {
buttons[i] = new JRadioButton("Selection " + i); rightBox.add(buttons[i]); } leftBox.add(pane); add(rightBox, BorderLayout.EAST); add(leftBox, BorderLayout.WEST); }
public static void main(String s[]) {
JFrame frame = new JFrame("Selection Monitor"); frame.addWindowListener(new BasicWindowMonitor()); frame.setContentPane(new SelectionMonitor()); frame.pack();
frame.setVisible(true); }
public void valueChanged(ListSelectionEvent e) {
// If either of these are true, the event can be ignored.
if ((e.getValueIsAdjusting() == false) || (e.getFirstIndex() == -1)) return;
// Change the radio button to match the current selection state // for each list item that reported a change.
for (int i = e.getFirstIndex(); i <= e.getLastIndex(); i++) {
buttons[i].setSelected(((JList)e.getSource()).isSelectedIndex(i)); }
} }
Remember that a ListSelectionEvent does not inform you of the new selection state of an
element that has changed. You might be tempted to conclude that if you receive a
ListSelectionEvent, the selection state for the target element would simply be the opposite of
what it was before. This is not true. The selection state cannot be determined from the
ListSelectionEvent; it must be determined by querying the event source.