• No results found

A JList with Changing Contents

In document 107 Java Swing [ PUNISHER ] pdf (Page 145-149)

Chapter 7. Lists and Combo Boxes

7.2 Representing List Data

7.2.3.4 A JList with Changing Contents

Here's a simple program that dynamically adds and removes elements from a JList. To do so, we

work with the DefaultListModel that keeps track of the list's contents. // ListModelExample.java // import java.awt.*; import java.awt.event.*; import javax.swing.*;

public class ListModelExample extends JPanel implements ActionListener { JList list; DefaultListModel model; int counter = 16; public ListModelExample() { super(true); setLayout(new BorderLayout()); model = new DefaultListModel(); list = new JList(model);

JScrollPane pane = new JScrollPane(list);

JButton addButton = new JButton("Add Element");

JButton removeButton = new JButton("Remove Element"); for (int i = 0; i < 15; i++)

model.addElement("Element " + i); addButton.addActionListener(this); removeButton.addActionListener(this); add(pane, BorderLayout.NORTH); add(addButton, BorderLayout.WEST); add(removeButton, BorderLayout.EAST); }

public static void main(String s[]) {

JFrame frame = new JFrame("List Model Example"); frame.addWindowListener(new BasicWindowMonitor()); frame.setContentPane(new ListModelExample()); frame.setSize(250, 220);

frame.setVisible(true); }

public void actionPerformed(ActionEvent e) { if (e.getActionCommand() == "Add Element") { model.addElement("Element " + counter); counter++; } else { if (model.getSize() > 0) model.removeElementAt(0); } } }

The result is shown in Figure 7.5.

This example demonstrates a few important concepts. First, we instantiated our own

DefaultListModel instead of using the default provided with the JList. if we hadn't done this, we

wouldn't have been able to add anything to the list. Working with your own instantiation is generally easier when you need to make runtime changes to any model — again, assigning new models is a wonderful benefit of the MVC architecture in Swing.

We've provided two ways for changing the list's contents: the "Add Element" button and the "Remove Element" button at the bottom. Pressing "Add Element" calls our actionPerformed()

method and appends an element to the end of the list. Pressing "Remove Element" calls the same method and deletes an element from the front of the list. After either button is pressed, the JList is

notified of the change in the model and updates itself automatically. If you watch carefully, you can see the scrollbar thumb grow or shrink as the list size changes.

Try selecting some elements, then press the "Remove Element" button a couple of times. Here's a gotcha: the selections don't decrement with the elements. This introduces an important difference in responsibilities between the data model and the selection model: the selection model simply

remembers the indices of the elements that are selected; it doesn't care what those elements contain, or even if they have shifted over time!

7.2.4 ListDataEvent

ListDataEvent is an extension of java.util.EventObject that holds information about a change

in the list data model. The event describes the nature of the change, as well as the bounding indices of the elements involved. However, it does not send data about the resulting elements. Listeners must query the source of the event to determine the new contents of the affected elements.

There are three types of changes that can occur to the list data: elements can be altered, inserted, or removed from the list. Note that the indices passed in form a closed interval (i.e., both indices are included in the affected range). If a ListDataEvent is received claiming that list elements have

been altered, the bounding indices typically describe the smallest range of data elements that have changed. If elements have been removed, the indices describe the range of elements that have been deleted. If elements have been added, the indices describe the new elements that have been inserted into the list.

7.2.4.1 Properties

The ListDataEvent contains four properties, each with its own read-only accessor, as shown in

Table 7.3. Each of these properties must be set in the ListDataEvent constructor. The source

property indicates the object that is firing the event. The type property represents the type of

change that has occurred; it must be one of the constants listed in Table 7.4. The index0 and index1 properties outline the range of affected elements. index0 does not need to be less than index1 for the ListDataEvent to be valid.

Table 7.3, ListDataEvent Properties

Property Data Type get is set bound Default Value

index0 int

index1 int

source* Object

type int

7.2.4.2 Constants

The static integer event types of the ListDataEvent are listed in Table 7.4.

Table 7.4, Constants for ListDataEvent

Constant Data Type Description

CONTENTS_CHANGEDint The elements between the two indices (inclusive) have been altered.

INTERVAL_ADDED int The elements now between the two indices (inclusive) have just been inserted into the list. INTERVAL_REMOVEDint The elements previously between the two indices (inclusive) have now been removed from the list.

7.2.4.3 Constructor

public ListDataEvent(Object source, int type, int index0, int index1)

The constructor for the event. It takes a reference to the object that fires the event, as well as the event type and bounding indices.

7.2.5 The ListDataListener Interface

The ListDataListener interface, which is the conduit for receiving the ListDataEvent objects,

contains three methods. Each method receives a different ListDataEvent type that can be

generated. This interface must be implemented by any listener object that wishes to be notified of changes to the list model.

7.2.5.1 Methods

public abstract void intervalAdded(ListDataEvent e)

Called when the interval of elements specified in the ListDataEvent has already been

added to the list. The specified interval includes both endpoints. Listeners will typically want to query the source of the event for the contents of the new interval.

public abstract void intervalRemoved(ListDataEvent e)

Called when the interval of elements specified in the ListDataEvent has already been

deleted. The specified interval includes both endpoints.

public abstract void contentsChanged(ListDataEvent e)

Called when the interval of elements specified in the ListDataEvent has been altered. The

specified interval includes both endpoints, although not all elements are guaranteed to have changed. Listeners will typically want to query the source of the event for the contents of those objects.

In document 107 Java Swing [ PUNISHER ] pdf (Page 145-149)