Module java.desktop
Package javax.swing

Class JList<E>

java.lang.Object
Type Parameters:
E - the type of the elements of this list
All Implemented Interfaces:
ImageObserver, MenuContainer, Serializable, Accessible, Scrollable

@JavaBean(defaultProperty="UI", description="A component which allows for the selection of one or more objects from a list.") public class JList<E> extends JComponent implements Scrollable, Accessible
A component that displays a list of objects and allows the user to select one or more items. A separate model, ListModel, maintains the contents of the list.

It's easy to display an array or Vector of objects, using the JList constructor that automatically builds a read-only ListModel instance for you:

 
 // Create a JList that displays strings from an array

 String[] data = {"one", "two", "three", "four"};
 JList<String> myList = new JList<String>(data);

 // Create a JList that displays the superclasses of JList.class, by
 // creating it with a Vector populated with this data

 Vector<Class<?>> superClasses = new Vector<Class<?>>();
 Class<JList> rootClass = javax.swing.JList.class;
 for(Class<?> cls = rootClass; cls != null; cls = cls.getSuperclass()) {
     superClasses.addElement(cls);
 }
 JList<Class<?>> myList = new JList<Class<?>>(superClasses);

 // The automatically created model is stored in JList's "model"
 // property, which you can retrieve

 ListModel<Class<?>> model = myList.getModel();
 for(int i = 0; i < model.getSize(); i++) {
     System.out.println(model.getElementAt(i));
 }
 
 

A ListModel can be supplied directly to a JList by way of a constructor or the setModel method. The contents need not be static - the number of items, and the values of items can change over time. A correct ListModel implementation notifies the set of javax.swing.event.ListDataListeners that have been added to it, each time a change occurs. These changes are characterized by a javax.swing.event.ListDataEvent, which identifies the range of list indices that have been modified, added, or removed. JList's ListUI is responsible for keeping the visual representation up to date with changes, by listening to the model.

Simple, dynamic-content, JList applications can use the DefaultListModel class to maintain list elements. This class implements the ListModel interface and also provides a java.util.Vector-like API. Applications that need a more custom ListModel implementation may instead wish to subclass AbstractListModel, which provides basic support for managing and notifying listeners. For example, a read-only implementation of AbstractListModel:

 
 // This list model has about 2^16 elements.  Enjoy scrolling.

 ListModel<String> bigData = new AbstractListModel<String>() {
     public int getSize() { return Short.MAX_VALUE; }
     public String getElementAt(int index) { return "Index " + index; }
 };
 
 

The selection state of a JList is managed by another separate model, an instance of ListSelectionModel. JList is initialized with a selection model on construction, and also contains methods to query or set this selection model. Additionally, JList provides convenient methods for easily managing the selection. These methods, such as setSelectedIndex and getSelectedValue, are cover methods that take care of the details of interacting with the selection model. By default, JList's selection model is configured to allow any combination of items to be selected at a time; selection mode MULTIPLE_INTERVAL_SELECTION. The selection mode can be changed on the selection model directly, or via JList's cover method. Responsibility for updating the selection model in response to user gestures lies with the list's ListUI.

A correct ListSelectionModel implementation notifies the set of javax.swing.event.ListSelectionListeners that have been added to it each time a change to the selection occurs. These changes are characterized by a javax.swing.event.ListSelectionEvent, which identifies the range of the selection change.

The preferred way to listen for changes in list selection is to add ListSelectionListeners directly to the JList. JList then takes care of listening to the selection model and notifying your listeners of change.

Responsibility for listening to selection changes in order to keep the list's visual representation up to date lies with the list's ListUI.

Painting of cells in a JList is handled by a delegate called a cell renderer, installed on the list as the cellRenderer property. The renderer provides a java.awt.Component that is used like a "rubber stamp" to paint the cells. Each time a cell needs to be painted, the list's ListUI asks the cell renderer for the component, moves it into place, and has it paint the contents of the cell by way of its paint method. A default cell renderer, which uses a JLabel component to render, is installed by the lists's ListUI. You can substitute your own renderer using code like this:

 
  // Display an icon and a string for each object in the list.

 class MyCellRenderer extends JLabel implements ListCellRenderer<Object> {
     static final ImageIcon longIcon = new ImageIcon("long.gif");
     static final ImageIcon shortIcon = new ImageIcon("short.gif");

     // This is the only method defined by ListCellRenderer.
     // We just reconfigure the JLabel each time we're called.

     public Component getListCellRendererComponent(
       JList<?> list,           // the list
       Object value,            // value to display
       int index,               // cell index
       boolean isSelected,      // is the cell selected
       boolean cellHasFocus)    // does the cell have focus
     {
         String s = value.toString();
         setText(s);
         setIcon((s.length() > 10) ? longIcon : shortIcon);
         if (isSelected) {
             setBackground(list.getSelectionBackground());
             setForeground(list.getSelectionForeground());
         } else {
             setBackground(list.getBackground());
             setForeground(list.getForeground());
         }
         setEnabled(list.isEnabled());
         setFont(list.getFont());
         setOpaque(true);
         return this;
     }
 }

 myList.setCellRenderer(new MyCellRenderer());
 
 

Another job for the cell renderer is in helping to determine sizing information for the list. By default, the list's ListUI determines the size of cells by asking the cell renderer for its preferred size for each list item. This can be expensive for large lists of items. To avoid these calculations, you can set a fixedCellWidth and fixedCellHeight on the list, or have these values calculated automatically based on a single prototype value:

 
 JList<String> bigDataList = new JList<String>(bigData);

 // We don't want the JList implementation to compute the width
 // or height of all of the list cells, so we give it a string
 // that's as big as we'll need for any cell.  It uses this to
 // compute values for the fixedCellWidth and fixedCellHeight
 // properties.

 bigDataList.setPrototypeCellValue("Index 1234567890");
 
 

JList doesn't implement scrolling directly. To create a list that scrolls, make it the viewport view of a JScrollPane. For example:

 JScrollPane scrollPane = new JScrollPane(myList);

 // Or in two steps:
 JScrollPane scrollPane = new JScrollPane();
 scrollPane.getViewport().setView(myList);
 

JList doesn't provide any special handling of double or triple (or N) mouse clicks, but it's easy to add a MouseListener if you wish to take action on these events. Use the locationToIndex method to determine what cell was clicked. For example:

 MouseListener mouseListener = new MouseAdapter() {
     public void mouseClicked(MouseEvent e) {
         if (e.getClickCount() == 2) {
             int index = list.locationToIndex(e.getPoint());
             System.out.println("Double clicked on Item " + index);
          }
     }
 };
 list.addMouseListener(mouseListener);
 

Warning: Swing is not thread safe. For more information see Swing's Threading Policy.

Warning: Serialized objects of this class will not be compatible with future Swing releases. The current serialization support is appropriate for short term storage or RMI between applications running the same version of Swing. As of 1.4, support for long term storage of all JavaBeans has been added to the java.beans package. Please see XMLEncoder.

See How to Use Lists in The Java Tutorial for further documentation.

Since:
1.2
See Also: