/* * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package javax.swing; import java.awt.*;import java.awt.event.*; import java.util.Vector;import java.util.Locale;import java.util.ArrayList;import java.util.Collections;import java.util.List; import java.beans.PropertyChangeEvent;import java.beans.PropertyChangeListener;import java.beans.Transient; import javax.swing.event.*;import javax.accessibility.*;import javax.swing.plaf.*;import javax.swing.text.Position; import java.io.ObjectOutputStream;import java.io.ObjectInputStream;import java.io.IOException;import java.io.Serializable; import sun.swing.SwingUtilities2;import sun.swing.SwingUtilities2.Section;import static sun.swing.SwingUtilities2.Section.*; /** * A component that displays a list of objects and allows the user to select * one or more items. A separate model, {@code ListModel}, maintains the * contents of the list. * <p> * It's easy to display an array or Vector of objects, using the {@code JList} * constructor that automatically builds a read-only {@code ListModel} instance * for you: * <pre> * {@code * // 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)); * } * } * </pre> * <p> * A {@code ListModel} can be supplied directly to a {@code JList} by way of a * constructor or the {@code setModel} method. The contents need not be static - * the number of items, and the values of items can change over time. A correct * {@code ListModel} implementation notifies the set of * {@code javax.swing.event.ListDataListener}s that have been added to it, each * time a change occurs. These changes are characterized by a * {@code javax.swing.event.ListDataEvent}, which identifies the range of list * indices that have been modified, added, or removed. {@code JList}'s * {@code ListUI} is responsible for keeping the visual representation up to * date with changes, by listening to the model. * <p> * Simple, dynamic-content, {@code JList} applications can use the * {@code DefaultListModel} class to maintain list elements. This class * implements the {@code ListModel} interface and also provides a * <code>java.util.Vector</code>-like API. Applications that need a more * custom <code>ListModel</code> implementation may instead wish to subclass * {@code AbstractListModel}, which provides basic support for managing and * notifying listeners. For example, a read-only implementation of * {@code AbstractListModel}: * <pre> * {@code * // 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; } * }; * } * </pre> * <p> * The selection state of a {@code JList} is managed by another separate * model, an instance of {@code ListSelectionModel}. {@code JList} is * initialized with a selection model on construction, and also contains * methods to query or set this selection model. Additionally, {@code JList} * provides convenient methods for easily managing the selection. These methods, * such as {@code setSelectedIndex} and {@code getSelectedValue}, are cover * methods that take care of the details of interacting with the selection * model. By default, {@code JList}'s selection model is configured to allow any * combination of items to be selected at a time; selection mode * {@code MULTIPLE_INTERVAL_SELECTION}. The selection mode can be changed * on the selection model directly, or via {@code JList}'s cover method. * Responsibility for updating the selection model in response to user gestures * lies with the list's {@code ListUI}. * <p> * A correct {@code ListSelectionModel} implementation notifies the set of * {@code javax.swing.event.ListSelectionListener}s that have been added to it * each time a change to the selection occurs. These changes are characterized * by a {@code javax.swing.event.ListSelectionEvent}, which identifies the range * of the selection change. * <p> * The preferred way to listen for changes in list selection is to add * {@code ListSelectionListener}s directly to the {@code JList}. {@code JList} * then takes care of listening to the the selection model and notifying your * listeners of change. * <p> * Responsibility for listening to selection changes in order to keep the list's * visual representation up to date lies with the list's {@code ListUI}. * <p> * <a name="renderer"> * Painting of cells in a {@code JList} is handled by a delegate called a * cell renderer, installed on the list as the {@code cellRenderer} property. * The renderer provides a {@code 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 {@code 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 * {@code paint} method. A default cell renderer, which uses a {@code JLabel} * component to render, is installed by the lists's {@code ListUI}. You can * substitute your own renderer using code like this: * <pre> * {@code * // Display an icon and a string for each object in the list. * * class MyCellRenderer extends JLabel implements ListCellRenderer<Object> { * final static ImageIcon longIcon = new ImageIcon("long.gif"); * final static 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()); * } * </pre> * <p> * Another job for the cell renderer is in helping to determine sizing * information for the list. By default, the list's {@code 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 {@code fixedCellWidth} and * {@code fixedCellHeight} on the list, or have these values calculated * automatically based on a single prototype value: * <a name="prototype_example"> * <pre> * {@code * 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"); * } * </pre> * <p> * {@code JList} doesn't implement scrolling directly. To create a list that * scrolls, make it the viewport view of a {@code JScrollPane}. For example: * <pre> * JScrollPane scrollPane = new JScrollPane(myList); * * // Or in two steps: * JScrollPane scrollPane = new JScrollPane(); * scrollPane.getViewport().setView(myList); * </pre> * <p> * {@code JList} doesn't provide any special handling of double or triple * (or N) mouse clicks, but it's easy to add a {@code MouseListener} if you * wish to take action on these events. Use the {@code locationToIndex} * method to determine what cell was clicked. For example: * <pre> * 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); * </pre> * <p> * <strong>Warning:</strong> Swing is not thread safe. For more * information see <a * href="package-summary.html#threading">Swing's Threading * Policy</a>. * <p> * <strong>Warning:</strong> * 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<sup><font size="-2">TM</font></sup> * has been added to the <code>java.beans</code> package. * Please see {@link java.beans.XMLEncoder}. * <p> * See <a href="http://java.sun.com/docs/books/tutorial/uiswing/components/list.html">How to Use Lists</a> * in <a href="http://java.sun.com/Series/Tutorial/index.html"><em>The Java Tutorial</em></a> * for further documentation. * Also see the article <a href="http://java.sun.com/products/jfc/tsc/tech_topics/jlist_1/jlist.html">Advanced JList Programming</a> * in <a href="http://java.sun.com/products/jfc/tsc"><em>The Swing Connection</em></a>. * <p> * @see ListModel * @see AbstractListModel * @see DefaultListModel * @see ListSelectionModel * @see DefaultListSelectionModel * @see ListCellRenderer * @see DefaultListCellRenderer * * @param <E> the type of the elements of this list * * @beaninfo * attribute: isContainer false * description: A component which allows for the selection of one or more objects from a list. * * @author Hans Muller */public class JList<E> extends JComponent implements Scrollable, Accessible{ /** * @see #getUIClassID * @see #readObject */ private static final String uiClassID = "ListUI"; /** * Indicates a vertical layout of cells, in a single column; * the default layout. * @see #setLayoutOrientation * @since 1.4 */ public static final int VERTICAL = 0; /** * Indicates a "newspaper style" layout with cells flowing vertically * then horizontally. * @see #setLayoutOrientation * @since 1.4 */ public static final int VERTICAL_WRAP = 1; /** * Indicates a "newspaper style" layout with cells flowing horizontally * then vertically. * @see #setLayoutOrientation * @since 1.4 */ public static final int HORIZONTAL_WRAP = 2; private int fixedCellWidth = -1; private int fixedCellHeight = -1; private int horizontalScrollIncrement = -1; private E prototypeCellValue; private int visibleRowCount = 8; private Color selectionForeground; private Color selectionBackground; private boolean dragEnabled; private ListSelectionModel selectionModel; private ListModel<E> dataModel; private ListCellRenderer<? super E> cellRenderer; private ListSelectionListener selectionListener; /** * How to lay out the cells; defaults to <code>VERTICAL</code>. */ private int layoutOrientation; /** * The drop mode for this component. */ private DropMode dropMode = DropMode.USE_SELECTION; /** * The drop location. */ private transient DropLocation dropLocation; /** * A subclass of <code>TransferHandler.DropLocation</code> representing * a drop location for a <code>JList</code>. * * @see #getDropLocation * @since 1.6 */ public static final class DropLocation extends TransferHandler.DropLocation { private final int index; private final boolean isInsert; private DropLocation(Point p, int index, boolean isInsert) { super(p); this.index = index; this.isInsert = isInsert; } /** * Returns the index where dropped data should be placed in the * list. Interpretation of the value depends on the drop mode set on * the associated component. If the drop mode is either * <code>DropMode.USE_SELECTION</code> or <code>DropMode.ON</code>, * the return value is an index of a row in the list. If the drop mode is * <code>DropMode.INSERT</code>, the return value refers to the index * where the data should be inserted. If the drop mode is * <code>DropMode.ON_OR_INSERT</code>, the value of * <code>isInsert()</code> indicates whether the index is an index * of a row, or an insert index. * <p> * <code>-1</code> indicates that the drop occurred over empty space, * and no index could be calculated. * * @return the drop index */ public int getIndex() { return index; } /** * Returns whether or not this location represents an insert * location. * * @return whether or not this is an insert location */ public boolean isInsert() { return isInsert; } /** * Returns a string representation of this drop location. * This method is intended to be used for debugging purposes, * and the content and format of the returned string may vary * between implementations. * * @return a string representation of this drop location */ public String toString() { return getClass().getName() + "[dropPoint=" + getDropPoint() + "," + "index=" + index + "," + "insert=" + isInsert + "]"; } } /** * Constructs a {@code JList} that displays elements from the specified, * {@code non-null}, model. All {@code JList} constructors delegate to * this one. * <p> * This constructor registers the list with the {@code ToolTipManager}, * allowing for tooltips to be provided by the cell renderers. * * @param dataModel the model for the list * @exception IllegalArgumentException if the model is {@code null} */ public JList(ListModel<E> dataModel) { if (dataModel == null) { throw new IllegalArgumentException("dataModel must be non null"); } // Register with the ToolTipManager so that tooltips from the // renderer show through. ToolTipManager toolTipManager = ToolTipManager.sharedInstance(); toolTipManager.registerComponent(this); layoutOrientation = VERTICAL; this.dataModel = dataModel; selectionModel = createSelectionModel(); setAutoscrolls(true); setOpaque(true); updateUI(); } /** * Constructs a <code>JList</code> that displays the elements in * the specified array. This constructor creates a read-only model * for the given array, and then delegates to the constructor that * takes a {@code ListModel}. * <p> * Attempts to pass a {@code null} value to this method results in * undefined behavior and, most likely, exceptions. The created model * references the given array directly. Attempts to modify the array * after constructing the list results in undefined behavior. * * @param listData the array of Objects to be loaded into the data model, * {@code non-null} */ public JList(final E[] listData) { this ( new AbstractListModel<E>() { public int getSize() { return listData.length; } public E getElementAt(int i) { return listData[i]; } } ); } /** * Constructs a <code>JList</code> that displays the elements in * the specified <code>Vector</code>. This constructor creates a read-only * model for the given {@code Vector}, and then delegates to the constructor * that takes a {@code ListModel}. * <p> * Attempts to pass a {@code null} value to this method results in * undefined behavior and, most likely, exceptions. The created model * references the given {@code Vector} directly. Attempts to modify the * {@code Vector} after constructing the list results in undefined behavior. * * @param listData the <code>Vector</code> to be loaded into the * data model, {@code non-null} */ public JList(final Vector<? extends E> listData) { this ( new AbstractListModel<E>() { public int getSize() { return listData.size(); } public E getElementAt(int i) { return listData.elementAt(i); } } ); } /** * Constructs a <code>JList</code> with an empty, read-only, model. */ public JList() { this ( new AbstractListModel<E>() { public int getSize() { return 0; } public E getElementAt(int i) { throw new IndexOutOfBoundsException("No Data Model"); } } ); } Lines 1–500 of 3735. Load more
/* * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package javax.swing; import java.awt.*; import java.awt.event.*; import java.util.Vector; import java.util.Locale; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.beans.Transient; import javax.swing.event.*; import javax.accessibility.*; import javax.swing.plaf.*; import javax.swing.text.Position; import java.io.ObjectOutputStream; import java.io.ObjectInputStream; import java.io.IOException; import java.io.Serializable; import sun.swing.SwingUtilities2; import sun.swing.SwingUtilities2.Section; import static sun.swing.SwingUtilities2.Section.*; /** * A component that displays a list of objects and allows the user to select * one or more items. A separate model, {@code ListModel}, maintains the * contents of the list. * <p> * It's easy to display an array or Vector of objects, using the {@code JList} * constructor that automatically builds a read-only {@code ListModel} instance * for you: * <pre> * {@code * // 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)); * } * } * </pre> * <p> * A {@code ListModel} can be supplied directly to a {@code JList} by way of a * constructor or the {@code setModel} method. The contents need not be static - * the number of items, and the values of items can change over time. A correct * {@code ListModel} implementation notifies the set of * {@code javax.swing.event.ListDataListener}s that have been added to it, each * time a change occurs. These changes are characterized by a * {@code javax.swing.event.ListDataEvent}, which identifies the range of list * indices that have been modified, added, or removed. {@code JList}'s * {@code ListUI} is responsible for keeping the visual representation up to * date with changes, by listening to the model. * <p> * Simple, dynamic-content, {@code JList} applications can use the * {@code DefaultListModel} class to maintain list elements. This class * implements the {@code ListModel} interface and also provides a * <code>java.util.Vector</code>-like API. Applications that need a more * custom <code>ListModel</code> implementation may instead wish to subclass * {@code AbstractListModel}, which provides basic support for managing and * notifying listeners. For example, a read-only implementation of * {@code AbstractListModel}: * <pre> * {@code * // 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; } * }; * } * </pre> * <p> * The selection state of a {@code JList} is managed by another separate * model, an instance of {@code ListSelectionModel}. {@code JList} is * initialized with a selection model on construction, and also contains * methods to query or set this selection model. Additionally, {@code JList} * provides convenient methods for easily managing the selection. These methods, * such as {@code setSelectedIndex} and {@code getSelectedValue}, are cover * methods that take care of the details of interacting with the selection * model. By default, {@code JList}'s selection model is configured to allow any * combination of items to be selected at a time; selection mode * {@code MULTIPLE_INTERVAL_SELECTION}. The selection mode can be changed * on the selection model directly, or via {@code JList}'s cover method. * Responsibility for updating the selection model in response to user gestures * lies with the list's {@code ListUI}. * <p> * A correct {@code ListSelectionModel} implementation notifies the set of * {@code javax.swing.event.ListSelectionListener}s that have been added to it * each time a change to the selection occurs. These changes are characterized * by a {@code javax.swing.event.ListSelectionEvent}, which identifies the range * of the selection change. * <p> * The preferred way to listen for changes in list selection is to add * {@code ListSelectionListener}s directly to the {@code JList}. {@code JList} * then takes care of listening to the the selection model and notifying your * listeners of change. * <p> * Responsibility for listening to selection changes in order to keep the list's * visual representation up to date lies with the list's {@code ListUI}. * <p> * <a name="renderer"> * Painting of cells in a {@code JList} is handled by a delegate called a * cell renderer, installed on the list as the {@code cellRenderer} property. * The renderer provides a {@code 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 {@code 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 * {@code paint} method. A default cell renderer, which uses a {@code JLabel} * component to render, is installed by the lists's {@code ListUI}. You can * substitute your own renderer using code like this: * <pre> * {@code * // Display an icon and a string for each object in the list. * * class MyCellRenderer extends JLabel implements ListCellRenderer<Object> { * final static ImageIcon longIcon = new ImageIcon("long.gif"); * final static 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()); * } * </pre> * <p> * Another job for the cell renderer is in helping to determine sizing * information for the list. By default, the list's {@code 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 {@code fixedCellWidth} and * {@code fixedCellHeight} on the list, or have these values calculated * automatically based on a single prototype value: * <a name="prototype_example"> * <pre> * {@code * 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"); * } * </pre> * <p> * {@code JList} doesn't implement scrolling directly. To create a list that * scrolls, make it the viewport view of a {@code JScrollPane}. For example: * <pre> * JScrollPane scrollPane = new JScrollPane(myList); * * // Or in two steps: * JScrollPane scrollPane = new JScrollPane(); * scrollPane.getViewport().setView(myList); * </pre> * <p> * {@code JList} doesn't provide any special handling of double or triple * (or N) mouse clicks, but it's easy to add a {@code MouseListener} if you * wish to take action on these events. Use the {@code locationToIndex} * method to determine what cell was clicked. For example: * <pre> * 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); * </pre> * <p> * <strong>Warning:</strong> Swing is not thread safe. For more * information see <a * href="package-summary.html#threading">Swing's Threading * Policy</a>. * <p> * <strong>Warning:</strong> * 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<sup><font size="-2">TM</font></sup> * has been added to the <code>java.beans</code> package. * Please see {@link java.beans.XMLEncoder}. * <p> * See <a href="http://java.sun.com/docs/books/tutorial/uiswing/components/list.html">How to Use Lists</a> * in <a href="http://java.sun.com/Series/Tutorial/index.html"><em>The Java Tutorial</em></a> * for further documentation. * Also see the article <a href="http://java.sun.com/products/jfc/tsc/tech_topics/jlist_1/jlist.html">Advanced JList Programming</a> * in <a href="http://java.sun.com/products/jfc/tsc"><em>The Swing Connection</em></a>. * <p> * @see ListModel * @see AbstractListModel * @see DefaultListModel * @see ListSelectionModel * @see DefaultListSelectionModel * @see ListCellRenderer * @see DefaultListCellRenderer * * @param <E> the type of the elements of this list * * @beaninfo * attribute: isContainer false * description: A component which allows for the selection of one or more objects from a list. * * @author Hans Muller */ public class JList<E> extends JComponent implements Scrollable, Accessible { /** * @see #getUIClassID * @see #readObject */ private static final String uiClassID = "ListUI"; /** * Indicates a vertical layout of cells, in a single column; * the default layout. * @see #setLayoutOrientation * @since 1.4 */ public static final int VERTICAL = 0; /** * Indicates a "newspaper style" layout with cells flowing vertically * then horizontally. * @see #setLayoutOrientation * @since 1.4 */ public static final int VERTICAL_WRAP = 1; /** * Indicates a "newspaper style" layout with cells flowing horizontally * then vertically. * @see #setLayoutOrientation * @since 1.4 */ public static final int HORIZONTAL_WRAP = 2; private int fixedCellWidth = -1; private int fixedCellHeight = -1; private int horizontalScrollIncrement = -1; private E prototypeCellValue; private int visibleRowCount = 8; private Color selectionForeground; private Color selectionBackground; private boolean dragEnabled; private ListSelectionModel selectionModel; private ListModel<E> dataModel; private ListCellRenderer<? super E> cellRenderer; private ListSelectionListener selectionListener; /** * How to lay out the cells; defaults to <code>VERTICAL</code>. */ private int layoutOrientation; /** * The drop mode for this component. */ private DropMode dropMode = DropMode.USE_SELECTION; /** * The drop location. */ private transient DropLocation dropLocation; /** * A subclass of <code>TransferHandler.DropLocation</code> representing * a drop location for a <code>JList</code>. * * @see #getDropLocation * @since 1.6 */ public static final class DropLocation extends TransferHandler.DropLocation { private final int index; private final boolean isInsert; private DropLocation(Point p, int index, boolean isInsert) { super(p); this.index = index; this.isInsert = isInsert; } /** * Returns the index where dropped data should be placed in the * list. Interpretation of the value depends on the drop mode set on * the associated component. If the drop mode is either * <code>DropMode.USE_SELECTION</code> or <code>DropMode.ON</code>, * the return value is an index of a row in the list. If the drop mode is * <code>DropMode.INSERT</code>, the return value refers to the index * where the data should be inserted. If the drop mode is * <code>DropMode.ON_OR_INSERT</code>, the value of * <code>isInsert()</code> indicates whether the index is an index * of a row, or an insert index. * <p> * <code>-1</code> indicates that the drop occurred over empty space, * and no index could be calculated. * * @return the drop index */ public int getIndex() { return index; } /** * Returns whether or not this location represents an insert * location. * * @return whether or not this is an insert location */ public boolean isInsert() { return isInsert; } /** * Returns a string representation of this drop location. * This method is intended to be used for debugging purposes, * and the content and format of the returned string may vary * between implementations. * * @return a string representation of this drop location */ public String toString() { return getClass().getName() + "[dropPoint=" + getDropPoint() + "," + "index=" + index + "," + "insert=" + isInsert + "]"; } } /** * Constructs a {@code JList} that displays elements from the specified, * {@code non-null}, model. All {@code JList} constructors delegate to * this one. * <p> * This constructor registers the list with the {@code ToolTipManager}, * allowing for tooltips to be provided by the cell renderers. * * @param dataModel the model for the list * @exception IllegalArgumentException if the model is {@code null} */ public JList(ListModel<E> dataModel) { if (dataModel == null) { throw new IllegalArgumentException("dataModel must be non null"); } // Register with the ToolTipManager so that tooltips from the // renderer show through. ToolTipManager toolTipManager = ToolTipManager.sharedInstance(); toolTipManager.registerComponent(this); layoutOrientation = VERTICAL; this.dataModel = dataModel; selectionModel = createSelectionModel(); setAutoscrolls(true); setOpaque(true); updateUI(); } /** * Constructs a <code>JList</code> that displays the elements in * the specified array. This constructor creates a read-only model * for the given array, and then delegates to the constructor that * takes a {@code ListModel}. * <p> * Attempts to pass a {@code null} value to this method results in * undefined behavior and, most likely, exceptions. The created model * references the given array directly. Attempts to modify the array * after constructing the list results in undefined behavior. * * @param listData the array of Objects to be loaded into the data model, * {@code non-null} */ public JList(final E[] listData) { this ( new AbstractListModel<E>() { public int getSize() { return listData.length; } public E getElementAt(int i) { return listData[i]; } } ); } /** * Constructs a <code>JList</code> that displays the elements in * the specified <code>Vector</code>. This constructor creates a read-only * model for the given {@code Vector}, and then delegates to the constructor * that takes a {@code ListModel}. * <p> * Attempts to pass a {@code null} value to this method results in * undefined behavior and, most likely, exceptions. The created model * references the given {@code Vector} directly. Attempts to modify the * {@code Vector} after constructing the list results in undefined behavior. * * @param listData the <code>Vector</code> to be loaded into the * data model, {@code non-null} */ public JList(final Vector<? extends E> listData) { this ( new AbstractListModel<E>() { public int getSize() { return listData.size(); } public E getElementAt(int i) { return listData.elementAt(i); } } ); } /** * Constructs a <code>JList</code> with an empty, read-only, model. */ public JList() { this ( new AbstractListModel<E>() { public int getSize() { return 0; } public E getElementAt(int i) { throw new IndexOutOfBoundsException("No Data Model"); } } ); }