/*
* Copyright (c) 1997, 2017, 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.JavaBean;
import java.beans.BeanProperty;
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.IOException;
import java.io.Serializable;
import sun.awt.AWTAccessor;
import sun.awt.AWTAccessor.MouseEventAccessor;
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, 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.ListDataListener
s 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.ListSelectionListener
s 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 ListSelectionListener
s 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.
Author: Hans Muller Type parameters: - <E> – the type of the elements of this list
See Also: Since: 1.2
/**
* 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 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 id="renderer"></a>
* 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> {
* 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());
* }
* </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 id="prototype_example"></a>
* <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™
* has been added to the <code>java.beans</code> package.
* Please see {@link java.beans.XMLEncoder}.
* <p>
* See <a href="http://docs.oracle.com/javase/tutorial/uiswing/components/list.html">How to Use Lists</a>
* in <a href="http://docs.oracle.com/javase/tutorial/"><em>The Java Tutorial</em></a>
* for further documentation.
*
* @see ListModel
* @see AbstractListModel
* @see DefaultListModel
* @see ListSelectionModel
* @see DefaultListSelectionModel
* @see ListCellRenderer
* @see DefaultListCellRenderer
*
* @param <E> the type of the elements of this list
*
* @author Hans Muller
* @since 1.2
*/
@JavaBean(defaultProperty = "UI", description = "A component which allows for the selection of one or more objects from a list.")
@SwingContainer(false)
@SuppressWarnings("serial") // Same-version serialization only
public class JList<E> extends JComponent implements Scrollable, Accessible
{
See Also: - getUIClassID
- JComponent.readObject
/**
* @see #getUIClassID
* @see #readObject
*/
private static final String uiClassID = "ListUI";
Indicates a vertical layout of cells, in a single column;
the default layout.
See Also: - setLayoutOrientation
Since: 1.4
/**
* 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 Also: - setLayoutOrientation
Since: 1.4
/**
* 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 Also: - setLayoutOrientation
Since: 1.4
/**
* 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 VERTICAL
.
/**
* How to lay out the cells; defaults to <code>VERTICAL</code>.
*/
private int layoutOrientation;
The drop mode for this component.
/**
* The drop mode for this component.
*/
private DropMode dropMode = DropMode.USE_SELECTION;
The drop location.
/**
* The drop location.
*/
private transient DropLocation dropLocation;
Flag to indicate UI update is in progress
/**
* Flag to indicate UI update is in progress
*/
private transient boolean updateInProgress;
A subclass of TransferHandler.DropLocation
representing
a drop location for a JList
.
See Also: - getDropLocation
Since: 1.6
/**
* 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
DropMode.USE_SELECTION
or DropMode.ON
,
the return value is an index of a row in the list. If the drop mode is
DropMode.INSERT
, the return value refers to the index
where the data should be inserted. If the drop mode is
DropMode.ON_OR_INSERT
, the value of
isInsert()
indicates whether the index is an index
of a row, or an insert index.
-1
indicates that the drop occurred over empty space,
and no index could be calculated.
Returns: the drop index
/**
* 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.
Returns: whether or not this is an insert location
/**
* 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.
Returns: a string representation of this drop location
/**
* 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 JList
that displays elements from the specified, non-null
, model. All JList
constructors delegate to this one. This constructor registers the list with the ToolTipManager
, allowing for tooltips to be provided by the cell renderers.
Params: - dataModel – the model for the list
Throws: - IllegalArgumentException – if the model is
null
/**
* 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 JList
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 ListModel
. Attempts to pass a 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.
Params: - listData – the array of Objects to be loaded into the data model,
non-null
/**
* 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 JList
that displays the elements in
the specified Vector
. This constructor creates a read-only model for the given Vector
, and then delegates to the constructor that takes a ListModel
. Attempts to pass a null
value to this method results in undefined behavior and, most likely, exceptions. The created model references the given Vector
directly. Attempts to modify the Vector
after constructing the list results in undefined behavior.
Params: - listData – the
Vector
to be loaded into the data model, non-null
/**
* 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 JList
with an empty, read-only, model.
/**
* 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"); }
}
);
}
Returns the ListUI
, the look and feel object that renders this component. Returns: the ListUI
object that renders this component
/**
* Returns the {@code ListUI}, the look and feel object that
* renders this component.
*
* @return the <code>ListUI</code> object that renders this component
*/
public ListUI getUI() {
return (ListUI)ui;
}
Sets the ListUI
, the look and feel object that renders this component. Params: - ui – the
ListUI
object
See Also:
/**
* Sets the {@code ListUI}, the look and feel object that
* renders this component.
*
* @param ui the <code>ListUI</code> object
* @see UIDefaults#getUI
*/
@BeanProperty(hidden = true, visualUpdate = true, description
= "The UI object that implements the Component's LookAndFeel.")
public void setUI(ListUI ui) {
super.setUI(ui);
}
Resets the ListUI
property by setting it to the value provided by the current look and feel. If the current cell renderer was installed by the developer (rather than the look and feel itself), this also causes the cell renderer and its children to be updated, by calling SwingUtilities.updateComponentTreeUI
on it. See Also:
/**
* Resets the {@code ListUI} property by setting it to the value provided
* by the current look and feel. If the current cell renderer was installed
* by the developer (rather than the look and feel itself), this also causes
* the cell renderer and its children to be updated, by calling
* {@code SwingUtilities.updateComponentTreeUI} on it.
*
* @see UIManager#getUI
* @see SwingUtilities#updateComponentTreeUI
*/
public void updateUI() {
if (!updateInProgress) {
updateInProgress = true;
try {
setUI((ListUI)UIManager.getUI(this));
ListCellRenderer<? super E> renderer = getCellRenderer();
if (renderer instanceof Component) {
SwingUtilities.updateComponentTreeUI((Component)renderer);
}
} finally {
updateInProgress = false;
}
}
}
Returns "ListUI"
, the UIDefaults
key used to look up the name of the javax.swing.plaf.ListUI
class that defines the look and feel for this component. See Also: Returns: the string "ListUI"
/**
* Returns {@code "ListUI"}, the <code>UIDefaults</code> key used to look
* up the name of the {@code javax.swing.plaf.ListUI} class that defines
* the look and feel for this component.
*
* @return the string "ListUI"
* @see JComponent#getUIClassID
* @see UIDefaults#getUI
*/
@BeanProperty(bound = false)
public String getUIClassID() {
return uiClassID;
}
/* -----private-----
* This method is called by setPrototypeCellValue and setCellRenderer
* to update the fixedCellWidth and fixedCellHeight properties from the
* current value of prototypeCellValue (if it's non null).
* <p>
* This method sets fixedCellWidth and fixedCellHeight but does <b>not</b>
* generate PropertyChangeEvents for them.
*
* @see #setPrototypeCellValue
* @see #setCellRenderer
*/
private void updateFixedCellSize()
{
ListCellRenderer<? super E> cr = getCellRenderer();
E value = getPrototypeCellValue();
if ((cr != null) && (value != null)) {
Component c = cr.getListCellRendererComponent(this, value, 0, false, false);
/* The ListUI implementation will add Component c to its private
* CellRendererPane however we can't assume that's already
* been done here. So we temporarily set the one "inherited"
* property that may affect the renderer components preferred size:
* its font.
*/
Font f = c.getFont();
c.setFont(getFont());
Dimension d = c.getPreferredSize();
fixedCellWidth = d.width;
fixedCellHeight = d.height;
c.setFont(f);
}
}
Returns the "prototypical" cell value -- a value used to calculate a fixed width and height for cells. This can be null
if there is no such value. See Also: Returns: the value of the prototypeCellValue
property
/**
* Returns the "prototypical" cell value -- a value used to calculate a
* fixed width and height for cells. This can be {@code null} if there
* is no such value.
*
* @return the value of the {@code prototypeCellValue} property
* @see #setPrototypeCellValue
*/
public E getPrototypeCellValue() {
return prototypeCellValue;
}
Sets the prototypeCellValue
property, and then (if the new value is non-null
), computes the fixedCellWidth
and fixedCellHeight
properties by requesting the cell renderer component for the given value (and index 0) from the cell renderer, and using that component's preferred size. This method is useful when the list is too long to allow the ListUI
to compute the width/height of each cell, and there is a single cell value that is known to occupy as much space as any of the others, a so-called prototype.
While all three of the prototypeCellValue
, fixedCellHeight
, and fixedCellWidth
properties may be modified by this method, PropertyChangeEvent
notifications are only sent when the prototypeCellValue
property changes.
To see an example which sets this property, see the
class description above.
The default value of this property is null
.
This is a JavaBeans bound property.
Params: - prototypeCellValue – the value on which to base
fixedCellWidth
and
fixedCellHeight
See Also:
/**
* Sets the {@code prototypeCellValue} property, and then (if the new value
* is {@code non-null}), computes the {@code fixedCellWidth} and
* {@code fixedCellHeight} properties by requesting the cell renderer
* component for the given value (and index 0) from the cell renderer, and
* using that component's preferred size.
* <p>
* This method is useful when the list is too long to allow the
* {@code ListUI} to compute the width/height of each cell, and there is a
* single cell value that is known to occupy as much space as any of the
* others, a so-called prototype.
* <p>
* While all three of the {@code prototypeCellValue},
* {@code fixedCellHeight}, and {@code fixedCellWidth} properties may be
* modified by this method, {@code PropertyChangeEvent} notifications are
* only sent when the {@code prototypeCellValue} property changes.
* <p>
* To see an example which sets this property, see the
* <a href="#prototype_example">class description</a> above.
* <p>
* The default value of this property is <code>null</code>.
* <p>
* This is a JavaBeans bound property.
*
* @param prototypeCellValue the value on which to base
* <code>fixedCellWidth</code> and
* <code>fixedCellHeight</code>
* @see #getPrototypeCellValue
* @see #setFixedCellWidth
* @see #setFixedCellHeight
* @see JComponent#addPropertyChangeListener
*/
@BeanProperty(visualUpdate = true, description
= "The cell prototype value, used to compute cell width and height.")
public void setPrototypeCellValue(E prototypeCellValue) {
E oldValue = this.prototypeCellValue;
this.prototypeCellValue = prototypeCellValue;
/* If the prototypeCellValue has changed and is non-null,
* then recompute fixedCellWidth and fixedCellHeight.
*/
if ((prototypeCellValue != null) && !prototypeCellValue.equals(oldValue)) {
updateFixedCellSize();
}
firePropertyChange("prototypeCellValue", oldValue, prototypeCellValue);
}
Returns the value of the fixedCellWidth
property. See Also: Returns: the fixed cell width
/**
* Returns the value of the {@code fixedCellWidth} property.
*
* @return the fixed cell width
* @see #setFixedCellWidth
*/
public int getFixedCellWidth() {
return fixedCellWidth;
}
Sets a fixed value to be used for the width of every cell in the list. If width
is -1, cell widths are computed in the ListUI
by applying getPreferredSize
to the cell renderer component
for each list element.
The default value of this property is -1
.
This is a JavaBeans bound property.
Params: - width – the width to be used for all cells in the list
See Also:
/**
* Sets a fixed value to be used for the width of every cell in the list.
* If {@code width} is -1, cell widths are computed in the {@code ListUI}
* by applying <code>getPreferredSize</code> to the cell renderer component
* for each list element.
* <p>
* The default value of this property is {@code -1}.
* <p>
* This is a JavaBeans bound property.
*
* @param width the width to be used for all cells in the list
* @see #setPrototypeCellValue
* @see #setFixedCellWidth
* @see JComponent#addPropertyChangeListener
*/
@BeanProperty(visualUpdate = true, description
= "Defines a fixed cell width when greater than zero.")
public void setFixedCellWidth(int width) {
int oldValue = fixedCellWidth;
fixedCellWidth = width;
firePropertyChange("fixedCellWidth", oldValue, fixedCellWidth);
}
Returns the value of the fixedCellHeight
property. See Also: Returns: the fixed cell height
/**
* Returns the value of the {@code fixedCellHeight} property.
*
* @return the fixed cell height
* @see #setFixedCellHeight
*/
public int getFixedCellHeight() {
return fixedCellHeight;
}
Sets a fixed value to be used for the height of every cell in the list. If height
is -1, cell heights are computed in the ListUI
by applying getPreferredSize
to the cell renderer component
for each list element.
The default value of this property is -1
.
This is a JavaBeans bound property.
Params: - height – the height to be used for all cells in the list
See Also:
/**
* Sets a fixed value to be used for the height of every cell in the list.
* If {@code height} is -1, cell heights are computed in the {@code ListUI}
* by applying <code>getPreferredSize</code> to the cell renderer component
* for each list element.
* <p>
* The default value of this property is {@code -1}.
* <p>
* This is a JavaBeans bound property.
*
* @param height the height to be used for all cells in the list
* @see #setPrototypeCellValue
* @see #setFixedCellWidth
* @see JComponent#addPropertyChangeListener
*/
@BeanProperty(visualUpdate = true, description
= "Defines a fixed cell height when greater than zero.")
public void setFixedCellHeight(int height) {
int oldValue = fixedCellHeight;
fixedCellHeight = height;
firePropertyChange("fixedCellHeight", oldValue, fixedCellHeight);
}
Returns the object responsible for painting list items.
See Also: Returns: the value of the cellRenderer
property
/**
* Returns the object responsible for painting list items.
*
* @return the value of the {@code cellRenderer} property
* @see #setCellRenderer
*/
@Transient
public ListCellRenderer<? super E> getCellRenderer() {
return cellRenderer;
}
Sets the delegate that is used to paint each cell in the list.
The job of a cell renderer is discussed in detail in the
class level documentation.
If the prototypeCellValue
property is non-null
, setting the cell renderer also causes the fixedCellWidth
and fixedCellHeight
properties to be re-calculated. Only one PropertyChangeEvent
is generated however -
for the cellRenderer
property.
The default value of this property is provided by the ListUI
delegate, i.e. by the look and feel implementation.
This is a JavaBeans bound property.
Params: - cellRenderer – the
ListCellRenderer
that paints list cells
See Also:
/**
* Sets the delegate that is used to paint each cell in the list.
* The job of a cell renderer is discussed in detail in the
* <a href="#renderer">class level documentation</a>.
* <p>
* If the {@code prototypeCellValue} property is {@code non-null},
* setting the cell renderer also causes the {@code fixedCellWidth} and
* {@code fixedCellHeight} properties to be re-calculated. Only one
* <code>PropertyChangeEvent</code> is generated however -
* for the <code>cellRenderer</code> property.
* <p>
* The default value of this property is provided by the {@code ListUI}
* delegate, i.e. by the look and feel implementation.
* <p>
* This is a JavaBeans bound property.
*
* @param cellRenderer the <code>ListCellRenderer</code>
* that paints list cells
* @see #getCellRenderer
*/
@BeanProperty(visualUpdate = true, description
= "The component used to draw the cells.")
public void setCellRenderer(ListCellRenderer<? super E> cellRenderer) {
ListCellRenderer<? super E> oldValue = this.cellRenderer;
this.cellRenderer = cellRenderer;
/* If the cellRenderer has changed and prototypeCellValue
* was set, then recompute fixedCellWidth and fixedCellHeight.
*/
if ((cellRenderer != null) && !cellRenderer.equals(oldValue)) {
updateFixedCellSize();
}
firePropertyChange("cellRenderer", oldValue, cellRenderer);
}
Returns the color used to draw the foreground of selected items. DefaultListCellRenderer
uses this color to draw the foreground of items in the selected state, as do the renderers installed by most ListUI
implementations. See Also: Returns: the color to draw the foreground of selected items
/**
* Returns the color used to draw the foreground of selected items.
* {@code DefaultListCellRenderer} uses this color to draw the foreground
* of items in the selected state, as do the renderers installed by most
* {@code ListUI} implementations.
*
* @return the color to draw the foreground of selected items
* @see #setSelectionForeground
* @see DefaultListCellRenderer
*/
public Color getSelectionForeground() {
return selectionForeground;
}
Sets the color used to draw the foreground of selected items, which cell renderers can use to render text and graphics. DefaultListCellRenderer
uses this color to draw the foreground of items in the selected state, as do the renderers installed by most ListUI
implementations.
The default value of this property is defined by the look and feel
implementation.
This is a JavaBeans bound property.
Params: - selectionForeground – the
Color
to use in the foreground for selected list items
See Also:
/**
* Sets the color used to draw the foreground of selected items, which
* cell renderers can use to render text and graphics.
* {@code DefaultListCellRenderer} uses this color to draw the foreground
* of items in the selected state, as do the renderers installed by most
* {@code ListUI} implementations.
* <p>
* The default value of this property is defined by the look and feel
* implementation.
* <p>
* This is a JavaBeans bound property.
*
* @param selectionForeground the {@code Color} to use in the foreground
* for selected list items
* @see #getSelectionForeground
* @see #setSelectionBackground
* @see #setForeground
* @see #setBackground
* @see #setFont
* @see DefaultListCellRenderer
*/
@BeanProperty(visualUpdate = true, description
= "The foreground color of selected cells.")
public void setSelectionForeground(Color selectionForeground) {
Color oldValue = this.selectionForeground;
this.selectionForeground = selectionForeground;
firePropertyChange("selectionForeground", oldValue, selectionForeground);
}
Returns the color used to draw the background of selected items. DefaultListCellRenderer
uses this color to draw the background of items in the selected state, as do the renderers installed by most ListUI
implementations. See Also: Returns: the color to draw the background of selected items
/**
* Returns the color used to draw the background of selected items.
* {@code DefaultListCellRenderer} uses this color to draw the background
* of items in the selected state, as do the renderers installed by most
* {@code ListUI} implementations.
*
* @return the color to draw the background of selected items
* @see #setSelectionBackground
* @see DefaultListCellRenderer
*/
public Color getSelectionBackground() {
return selectionBackground;
}
Sets the color used to draw the background of selected items, which cell renderers can use fill selected cells. DefaultListCellRenderer
uses this color to fill the background of items in the selected state, as do the renderers installed by most ListUI
implementations.
The default value of this property is defined by the look
and feel implementation.
This is a JavaBeans bound property.
Params: - selectionBackground – the
Color
to use for the background of selected cells
See Also:
/**
* Sets the color used to draw the background of selected items, which
* cell renderers can use fill selected cells.
* {@code DefaultListCellRenderer} uses this color to fill the background
* of items in the selected state, as do the renderers installed by most
* {@code ListUI} implementations.
* <p>
* The default value of this property is defined by the look
* and feel implementation.
* <p>
* This is a JavaBeans bound property.
*
* @param selectionBackground the {@code Color} to use for the
* background of selected cells
* @see #getSelectionBackground
* @see #setSelectionForeground
* @see #setForeground
* @see #setBackground
* @see #setFont
* @see DefaultListCellRenderer
*/
@BeanProperty(visualUpdate = true, description
= "The background color of selected cells.")
public void setSelectionBackground(Color selectionBackground) {
Color oldValue = this.selectionBackground;
this.selectionBackground = selectionBackground;
firePropertyChange("selectionBackground", oldValue, selectionBackground);
}
Returns the value of the visibleRowCount
property. See the documentation for setVisibleRowCount
for details on how to interpret this value. See Also: Returns: the value of the visibleRowCount
property.
/**
* Returns the value of the {@code visibleRowCount} property. See the
* documentation for {@link #setVisibleRowCount} for details on how to
* interpret this value.
*
* @return the value of the {@code visibleRowCount} property.
* @see #setVisibleRowCount
*/
public int getVisibleRowCount() {
return visibleRowCount;
}
Sets the visibleRowCount
property, which has different meanings depending on the layout orientation: For a VERTICAL
layout orientation, this sets the preferred number of rows to display without requiring scrolling; for other orientations, it affects the wrapping of cells. In VERTICAL
orientation:
Setting this property affects the return value of the getPreferredScrollableViewportSize
method, which is used to calculate the preferred size of an enclosing viewport. See that method's documentation for more details.
In HORIZONTAL_WRAP
and VERTICAL_WRAP
orientations:
This affects how cells are wrapped. See the documentation of setLayoutOrientation
for more details.
The default value of this property is 8
.
Calling this method with a negative value results in the property being set to 0
.
This is a JavaBeans bound property.
Params: - visibleRowCount – an integer specifying the preferred number of
rows to display without requiring scrolling
See Also:
/**
* Sets the {@code visibleRowCount} property, which has different meanings
* depending on the layout orientation: For a {@code VERTICAL} layout
* orientation, this sets the preferred number of rows to display without
* requiring scrolling; for other orientations, it affects the wrapping of
* cells.
* <p>
* In {@code VERTICAL} orientation:<br>
* Setting this property affects the return value of the
* {@link #getPreferredScrollableViewportSize} method, which is used to
* calculate the preferred size of an enclosing viewport. See that method's
* documentation for more details.
* <p>
* In {@code HORIZONTAL_WRAP} and {@code VERTICAL_WRAP} orientations:<br>
* This affects how cells are wrapped. See the documentation of
* {@link #setLayoutOrientation} for more details.
* <p>
* The default value of this property is {@code 8}.
* <p>
* Calling this method with a negative value results in the property
* being set to {@code 0}.
* <p>
* This is a JavaBeans bound property.
*
* @param visibleRowCount an integer specifying the preferred number of
* rows to display without requiring scrolling
* @see #getVisibleRowCount
* @see #getPreferredScrollableViewportSize
* @see #setLayoutOrientation
* @see JComponent#getVisibleRect
* @see JViewport
*/
@BeanProperty(visualUpdate = true, description
= "The preferred number of rows to display without requiring scrolling")
public void setVisibleRowCount(int visibleRowCount) {
int oldValue = this.visibleRowCount;
this.visibleRowCount = Math.max(0, visibleRowCount);
firePropertyChange("visibleRowCount", oldValue, visibleRowCount);
}
Returns the layout orientation property for the list: VERTICAL
if the layout is a single column of cells, VERTICAL_WRAP
if the layout is "newspaper style" with the content flowing vertically then horizontally, or HORIZONTAL_WRAP
if the layout is "newspaper style" with the content flowing horizontally then vertically. See Also: Returns: the value of the layoutOrientation
property Since: 1.4
/**
* Returns the layout orientation property for the list: {@code VERTICAL}
* if the layout is a single column of cells, {@code VERTICAL_WRAP} if the
* layout is "newspaper style" with the content flowing vertically then
* horizontally, or {@code HORIZONTAL_WRAP} if the layout is "newspaper
* style" with the content flowing horizontally then vertically.
*
* @return the value of the {@code layoutOrientation} property
* @see #setLayoutOrientation
* @since 1.4
*/
public int getLayoutOrientation() {
return layoutOrientation;
}
Defines the way list cells are layed out. Consider a JList
with five cells. Cells can be layed out in one of the following ways: VERTICAL: 0
1
2
3
4
HORIZONTAL_WRAP: 0 1 2
3 4
VERTICAL_WRAP: 0 3
1 4
2
A description of these layouts follows:
Describes layouts VERTICAL,HORIZONTAL_WRAP, and VERTICAL_WRAP
Value
Description
VERTICAL
Cells are layed out vertically in a single column.
HORIZONTAL_WRAP
Cells are layed out horizontally, wrapping to a new row as necessary. If the visibleRowCount
property is less than or equal to zero, wrapping is determined by the width of the list; otherwise wrapping is done in such a way as to ensure visibleRowCount
rows in the list.
VERTICAL_WRAP
Cells are layed out vertically, wrapping to a new column as necessary. If the visibleRowCount
property is less than or equal to zero, wrapping is determined by the height of the list; otherwise wrapping is done at visibleRowCount
rows.
The default value of this property is VERTICAL
.
Params: - layoutOrientation – the new layout orientation, one of:
VERTICAL
, HORIZONTAL_WRAP
or VERTICAL_WRAP
Throws: - IllegalArgumentException – if
layoutOrientation
isn't one of the allowable values
See Also: Since: 1.4
/**
* Defines the way list cells are layed out. Consider a {@code JList}
* with five cells. Cells can be layed out in one of the following ways:
*
* <pre>
* VERTICAL: 0
* 1
* 2
* 3
* 4
*
* HORIZONTAL_WRAP: 0 1 2
* 3 4
*
* VERTICAL_WRAP: 0 3
* 1 4
* 2
* </pre>
* <p>
* A description of these layouts follows:
*
* <table class="striped">
* <caption>Describes layouts VERTICAL,HORIZONTAL_WRAP, and VERTICAL_WRAP
* </caption>
* <thead>
* <tr>
* <th scope="col">Value
* <th scope="col">Description
* </thead>
* <tbody>
* <tr>
* <th scope="row">{@code VERTICAL}
* <td>Cells are layed out vertically in a single column.
* <tr>
* <th scope="row">{@code HORIZONTAL_WRAP}
* <td>Cells are layed out horizontally, wrapping to a new row as
* necessary. If the {@code visibleRowCount} property is less than or
* equal to zero, wrapping is determined by the width of the list;
* otherwise wrapping is done in such a way as to ensure
* {@code visibleRowCount} rows in the list.
* <tr>
* <th scope="row">{@code VERTICAL_WRAP}
* <td>Cells are layed out vertically, wrapping to a new column as
* necessary. If the {@code visibleRowCount} property is less than or
* equal to zero, wrapping is determined by the height of the list;
* otherwise wrapping is done at {@code visibleRowCount} rows.
* </tbody>
* </table>
*
* The default value of this property is <code>VERTICAL</code>.
*
* @param layoutOrientation the new layout orientation, one of:
* {@code VERTICAL}, {@code HORIZONTAL_WRAP} or {@code VERTICAL_WRAP}
* @see #getLayoutOrientation
* @see #setVisibleRowCount
* @see #getScrollableTracksViewportHeight
* @see #getScrollableTracksViewportWidth
* @throws IllegalArgumentException if {@code layoutOrientation} isn't one of the
* allowable values
* @since 1.4
*/
@BeanProperty(visualUpdate = true, enumerationValues = {
"JList.VERTICAL",
"JList.HORIZONTAL_WRAP",
"JList.VERTICAL_WRAP"}, description
= "Defines the way list cells are layed out.")
public void setLayoutOrientation(int layoutOrientation) {
int oldValue = this.layoutOrientation;
switch (layoutOrientation) {
case VERTICAL:
case VERTICAL_WRAP:
case HORIZONTAL_WRAP:
this.layoutOrientation = layoutOrientation;
firePropertyChange("layoutOrientation", oldValue, layoutOrientation);
break;
default:
throw new IllegalArgumentException("layoutOrientation must be one of: VERTICAL, HORIZONTAL_WRAP or VERTICAL_WRAP");
}
}
Returns the smallest list index that is currently visible. In a left-to-right componentOrientation
, the first visible cell is found closest to the list's upper-left corner. In right-to-left orientation, it is found closest to the upper-right corner. If nothing is visible or the list is empty, -1
is returned. Note that the returned cell may only be partially visible. See Also: Returns: the index of the first visible cell
/**
* Returns the smallest list index that is currently visible.
* In a left-to-right {@code componentOrientation}, the first visible
* cell is found closest to the list's upper-left corner. In right-to-left
* orientation, it is found closest to the upper-right corner.
* If nothing is visible or the list is empty, {@code -1} is returned.
* Note that the returned cell may only be partially visible.
*
* @return the index of the first visible cell
* @see #getLastVisibleIndex
* @see JComponent#getVisibleRect
*/
@BeanProperty(bound = false)
public int getFirstVisibleIndex() {
Rectangle r = getVisibleRect();
int first;
if (this.getComponentOrientation().isLeftToRight()) {
first = locationToIndex(r.getLocation());
} else {
first = locationToIndex(new Point((r.x + r.width) - 1, r.y));
}
if (first != -1) {
Rectangle bounds = getCellBounds(first, first);
if (bounds != null) {
SwingUtilities.computeIntersection(r.x, r.y, r.width, r.height, bounds);
if (bounds.width == 0 || bounds.height == 0) {
first = -1;
}
}
}
return first;
}
Returns the largest list index that is currently visible. If nothing is visible or the list is empty, -1
is returned. Note that the returned cell may only be partially visible. See Also: Returns: the index of the last visible cell
/**
* Returns the largest list index that is currently visible.
* If nothing is visible or the list is empty, {@code -1} is returned.
* Note that the returned cell may only be partially visible.
*
* @return the index of the last visible cell
* @see #getFirstVisibleIndex
* @see JComponent#getVisibleRect
*/
@BeanProperty(bound = false)
public int getLastVisibleIndex() {
boolean leftToRight = this.getComponentOrientation().isLeftToRight();
Rectangle r = getVisibleRect();
Point lastPoint;
if (leftToRight) {
lastPoint = new Point((r.x + r.width) - 1, (r.y + r.height) - 1);
} else {
lastPoint = new Point(r.x, (r.y + r.height) - 1);
}
int location = locationToIndex(lastPoint);
if (location != -1) {
Rectangle bounds = getCellBounds(location, location);
if (bounds != null) {
SwingUtilities.computeIntersection(r.x, r.y, r.width, r.height, bounds);
if (bounds.width == 0 || bounds.height == 0) {
// Try the top left(LTR) or top right(RTL) corner, and
// then go across checking each cell for HORIZONTAL_WRAP.
// Try the lower left corner, and then go across checking
// each cell for other list layout orientation.
boolean isHorizontalWrap =
(getLayoutOrientation() == HORIZONTAL_WRAP);
Point visibleLocation = isHorizontalWrap ?
new Point(lastPoint.x, r.y) :
new Point(r.x, lastPoint.y);
int last;
int visIndex = -1;
int lIndex = location;
location = -1;
do {
last = visIndex;
visIndex = locationToIndex(visibleLocation);
if (visIndex != -1) {
bounds = getCellBounds(visIndex, visIndex);
if (visIndex != lIndex && bounds != null &&
bounds.contains(visibleLocation)) {
location = visIndex;
if (isHorizontalWrap) {
visibleLocation.y = bounds.y + bounds.height;
if (visibleLocation.y >= lastPoint.y) {
// Past visible region, bail.
last = visIndex;
}
}
else {
visibleLocation.x = bounds.x + bounds.width;
if (visibleLocation.x >= lastPoint.x) {
// Past visible region, bail.
last = visIndex;
}
}
}
else {
last = visIndex;
}
}
} while (visIndex != -1 && last != visIndex);
}
}
}
return location;
}
Scrolls the list within an enclosing viewport to make the specified cell completely visible. This calls scrollRectToVisible
with the bounds of the specified cell. For this method to work, the JList
must be within a JViewport
.
If the given index is outside the list's range of cells, this method
results in nothing.
Params: - index – the index of the cell to make visible
See Also:
/**
* Scrolls the list within an enclosing viewport to make the specified
* cell completely visible. This calls {@code scrollRectToVisible} with
* the bounds of the specified cell. For this method to work, the
* {@code JList} must be within a <code>JViewport</code>.
* <p>
* If the given index is outside the list's range of cells, this method
* results in nothing.
*
* @param index the index of the cell to make visible
* @see JComponent#scrollRectToVisible
* @see #getVisibleRect
*/
public void ensureIndexIsVisible(int index) {
Rectangle cellBounds = getCellBounds(index, index);
if (cellBounds != null) {
scrollRectToVisible(cellBounds);
}
}
Turns on or off automatic drag handling. In order to enable automatic drag handling, this property should be set to true
, and the list's TransferHandler
needs to be non-null
. The default value of the dragEnabled
property is false
. The job of honoring this property, and recognizing a user drag gesture, lies with the look and feel implementation, and in particular, the list's ListUI
. When automatic drag handling is enabled, most look and feels (including those that subclass BasicLookAndFeel
) begin a drag and drop operation whenever the user presses the mouse button over an item and then moves the mouse a few pixels. Setting this property to true
can therefore have a subtle effect on how selections behave.
If a look and feel is used that ignores this property, you can still begin a drag and drop operation by calling exportAsDrag
on the list's TransferHandler
.
Params: - b – whether or not to enable automatic drag handling
Throws: - HeadlessException – if
b
is true
and
GraphicsEnvironment.isHeadless()
returns true
See Also: Since: 1.4
/**
* Turns on or off automatic drag handling. In order to enable automatic
* drag handling, this property should be set to {@code true}, and the
* list's {@code TransferHandler} needs to be {@code non-null}.
* The default value of the {@code dragEnabled} property is {@code false}.
* <p>
* The job of honoring this property, and recognizing a user drag gesture,
* lies with the look and feel implementation, and in particular, the list's
* {@code ListUI}. When automatic drag handling is enabled, most look and
* feels (including those that subclass {@code BasicLookAndFeel}) begin a
* drag and drop operation whenever the user presses the mouse button over
* an item and then moves the mouse a few pixels. Setting this property to
* {@code true} can therefore have a subtle effect on how selections behave.
* <p>
* If a look and feel is used that ignores this property, you can still
* begin a drag and drop operation by calling {@code exportAsDrag} on the
* list's {@code TransferHandler}.
*
* @param b whether or not to enable automatic drag handling
* @exception HeadlessException if
* <code>b</code> is <code>true</code> and
* <code>GraphicsEnvironment.isHeadless()</code>
* returns <code>true</code>
* @see java.awt.GraphicsEnvironment#isHeadless
* @see #getDragEnabled
* @see #setTransferHandler
* @see TransferHandler
* @since 1.4
*/
@BeanProperty(bound = false, description
= "determines whether automatic drag handling is enabled")
public void setDragEnabled(boolean b) {
if (b && GraphicsEnvironment.isHeadless()) {
throw new HeadlessException();
}
dragEnabled = b;
}
Returns whether or not automatic drag handling is enabled.
See Also: Returns: the value of the dragEnabled
property Since: 1.4
/**
* Returns whether or not automatic drag handling is enabled.
*
* @return the value of the {@code dragEnabled} property
* @see #setDragEnabled
* @since 1.4
*/
public boolean getDragEnabled() {
return dragEnabled;
}
Sets the drop mode for this component. For backward compatibility,
the default for this property is DropMode.USE_SELECTION
.
Usage of one of the other modes is recommended, however, for an
improved user experience. DropMode.ON
, for instance,
offers similar behavior of showing items as selected, but does so without
affecting the actual selection in the list.
JList
supports the following drop modes:
DropMode.USE_SELECTION
DropMode.ON
DropMode.INSERT
DropMode.ON_OR_INSERT
The drop mode is only meaningful if this component has a
TransferHandler
that accepts drops.
Params: - dropMode – the drop mode to use
Throws: - IllegalArgumentException – if the drop mode is unsupported
or
null
See Also: Since: 1.6
/**
* Sets the drop mode for this component. For backward compatibility,
* the default for this property is <code>DropMode.USE_SELECTION</code>.
* Usage of one of the other modes is recommended, however, for an
* improved user experience. <code>DropMode.ON</code>, for instance,
* offers similar behavior of showing items as selected, but does so without
* affecting the actual selection in the list.
* <p>
* <code>JList</code> supports the following drop modes:
* <ul>
* <li><code>DropMode.USE_SELECTION</code></li>
* <li><code>DropMode.ON</code></li>
* <li><code>DropMode.INSERT</code></li>
* <li><code>DropMode.ON_OR_INSERT</code></li>
* </ul>
* The drop mode is only meaningful if this component has a
* <code>TransferHandler</code> that accepts drops.
*
* @param dropMode the drop mode to use
* @throws IllegalArgumentException if the drop mode is unsupported
* or <code>null</code>
* @see #getDropMode
* @see #getDropLocation
* @see #setTransferHandler
* @see TransferHandler
* @since 1.6
*/
public final void setDropMode(DropMode dropMode) {
if (dropMode != null) {
switch (dropMode) {
case USE_SELECTION:
case ON:
case INSERT:
case ON_OR_INSERT:
this.dropMode = dropMode;
return;
}
}
throw new IllegalArgumentException(dropMode + ": Unsupported drop mode for list");
}
Returns the drop mode for this component.
See Also: Returns: the drop mode for this component Since: 1.6
/**
* Returns the drop mode for this component.
*
* @return the drop mode for this component
* @see #setDropMode
* @since 1.6
*/
public final DropMode getDropMode() {
return dropMode;
}
Calculates a drop location in this component, representing where a
drop at the given point should insert data.
Params: - p – the point to calculate a drop location for
Returns: the drop location, or null
/**
* Calculates a drop location in this component, representing where a
* drop at the given point should insert data.
*
* @param p the point to calculate a drop location for
* @return the drop location, or <code>null</code>
*/
DropLocation dropLocationForPoint(Point p) {
DropLocation location = null;
Rectangle rect = null;
int index = locationToIndex(p);
if (index != -1) {
rect = getCellBounds(index, index);
}
switch(dropMode) {
case USE_SELECTION:
case ON:
location = new DropLocation(p,
(rect != null && rect.contains(p)) ? index : -1,
false);
break;
case INSERT:
if (index == -1) {
location = new DropLocation(p, getModel().getSize(), true);
break;
}
if (layoutOrientation == HORIZONTAL_WRAP) {
boolean ltr = getComponentOrientation().isLeftToRight();
if (SwingUtilities2.liesInHorizontal(rect, p, ltr, false) == TRAILING) {
index++;
// special case for below all cells
} else if (index == getModel().getSize() - 1 && p.y >= rect.y + rect.height) {
index++;
}
} else {
if (SwingUtilities2.liesInVertical(rect, p, false) == TRAILING) {
index++;
}
}
location = new DropLocation(p, index, true);
break;
case ON_OR_INSERT:
if (index == -1) {
location = new DropLocation(p, getModel().getSize(), true);
break;
}
boolean between = false;
if (layoutOrientation == HORIZONTAL_WRAP) {
boolean ltr = getComponentOrientation().isLeftToRight();
Section section = SwingUtilities2.liesInHorizontal(rect, p, ltr, true);
if (section == TRAILING) {
index++;
between = true;
// special case for below all cells
} else if (index == getModel().getSize() - 1 && p.y >= rect.y + rect.height) {
index++;
between = true;
} else if (section == LEADING) {
between = true;
}
} else {
Section section = SwingUtilities2.liesInVertical(rect, p, true);
if (section == LEADING) {
between = true;
} else if (section == TRAILING) {
index++;
between = true;
}
}
location = new DropLocation(p, index, between);
break;
default:
assert false : "Unexpected drop mode";
}
return location;
}
Called to set or clear the drop location during a DnD operation.
In some cases, the component may need to use it's internal selection
temporarily to indicate the drop location. To help facilitate this,
this method returns and accepts as a parameter a state object.
This state object can be used to store, and later restore, the selection
state. Whatever this method returns will be passed back to it in
future calls, as the state parameter. If it wants the DnD system to
continue storing the same state, it must pass it back every time.
Here's how this is used:
Let's say that on the first call to this method the component decides
to save some state (because it is about to use the selection to show
a drop index). It can return a state object to the caller encapsulating
any saved selection state. On a second call, let's say the drop location
is being changed to something else. The component doesn't need to
restore anything yet, so it simply passes back the same state object
to have the DnD system continue storing it. Finally, let's say this
method is messaged with null
. This means DnD
is finished with this component for now, meaning it should restore
state. At this point, it can use the state parameter to restore
said state, and of course return null
since there's
no longer anything to store.
Params: - location – the drop location (as calculated by
dropLocationForPoint
) or null
if there's no longer a valid drop location - state – the state object saved earlier for this component,
or
null
- forDrop – whether or not the method is being called because an
actual drop occurred
Returns: any saved state for this component, or null
if none
/**
* Called to set or clear the drop location during a DnD operation.
* In some cases, the component may need to use it's internal selection
* temporarily to indicate the drop location. To help facilitate this,
* this method returns and accepts as a parameter a state object.
* This state object can be used to store, and later restore, the selection
* state. Whatever this method returns will be passed back to it in
* future calls, as the state parameter. If it wants the DnD system to
* continue storing the same state, it must pass it back every time.
* Here's how this is used:
* <p>
* Let's say that on the first call to this method the component decides
* to save some state (because it is about to use the selection to show
* a drop index). It can return a state object to the caller encapsulating
* any saved selection state. On a second call, let's say the drop location
* is being changed to something else. The component doesn't need to
* restore anything yet, so it simply passes back the same state object
* to have the DnD system continue storing it. Finally, let's say this
* method is messaged with <code>null</code>. This means DnD
* is finished with this component for now, meaning it should restore
* state. At this point, it can use the state parameter to restore
* said state, and of course return <code>null</code> since there's
* no longer anything to store.
*
* @param location the drop location (as calculated by
* <code>dropLocationForPoint</code>) or <code>null</code>
* if there's no longer a valid drop location
* @param state the state object saved earlier for this component,
* or <code>null</code>
* @param forDrop whether or not the method is being called because an
* actual drop occurred
* @return any saved state for this component, or <code>null</code> if none
*/
Object setDropLocation(TransferHandler.DropLocation location,
Object state,
boolean forDrop) {
Object retVal = null;
DropLocation listLocation = (DropLocation)location;
if (dropMode == DropMode.USE_SELECTION) {
if (listLocation == null) {
if (!forDrop && state != null) {
setSelectedIndices(((int[][])state)[0]);
int anchor = ((int[][])state)[1][0];
int lead = ((int[][])state)[1][1];
SwingUtilities2.setLeadAnchorWithoutSelection(
getSelectionModel(), lead, anchor);
}
} else {
if (dropLocation == null) {
int[] inds = getSelectedIndices();
retVal = new int[][] {inds, {getAnchorSelectionIndex(),
getLeadSelectionIndex()}};
} else {
retVal = state;
}
int index = listLocation.getIndex();
if (index == -1) {
clearSelection();
getSelectionModel().setAnchorSelectionIndex(-1);
getSelectionModel().setLeadSelectionIndex(-1);
} else {
setSelectionInterval(index, index);
}
}
}
DropLocation old = dropLocation;
dropLocation = listLocation;
firePropertyChange("dropLocation", old, dropLocation);
return retVal;
}
Returns the location that this component should visually indicate as the drop location during a DnD operation over the component, or null
if no location is to currently be shown. This method is not meant for querying the drop location from a TransferHandler
, as the drop location is only set after the TransferHandler
's canImport
has returned and has allowed for the location to be shown.
When this property changes, a property change event with
name "dropLocation" is fired by the component.
By default, responsibility for listening for changes to this property and indicating the drop location visually lies with the list's ListUI
, which may paint it directly and/or install a cell renderer to do so. Developers wishing to implement custom drop location painting and/or replace the default cell renderer, may need to honor this property.
See Also: Returns: the drop location Since: 1.6
/**
* Returns the location that this component should visually indicate
* as the drop location during a DnD operation over the component,
* or {@code null} if no location is to currently be shown.
* <p>
* This method is not meant for querying the drop location
* from a {@code TransferHandler}, as the drop location is only
* set after the {@code TransferHandler}'s <code>canImport</code>
* has returned and has allowed for the location to be shown.
* <p>
* When this property changes, a property change event with
* name "dropLocation" is fired by the component.
* <p>
* By default, responsibility for listening for changes to this property
* and indicating the drop location visually lies with the list's
* {@code ListUI}, which may paint it directly and/or install a cell
* renderer to do so. Developers wishing to implement custom drop location
* painting and/or replace the default cell renderer, may need to honor
* this property.
*
* @return the drop location
* @see #setDropMode
* @see TransferHandler#canImport(TransferHandler.TransferSupport)
* @since 1.6
*/
@BeanProperty(bound = false)
public final DropLocation getDropLocation() {
return dropLocation;
}
Returns the next list element whose toString
value starts with the given prefix. Params: - prefix – the string to test for a match
- startIndex – the index for starting the search
- bias – the search direction, either
Position.Bias.Forward or Position.Bias.Backward.
Throws: - IllegalArgumentException – if prefix is
null
or startIndex is out of bounds
Returns: the index of the next list element that starts with the prefix; otherwise -1
Since: 1.4
/**
* Returns the next list element whose {@code toString} value
* starts with the given prefix.
*
* @param prefix the string to test for a match
* @param startIndex the index for starting the search
* @param bias the search direction, either
* Position.Bias.Forward or Position.Bias.Backward.
* @return the index of the next list element that
* starts with the prefix; otherwise {@code -1}
* @exception IllegalArgumentException if prefix is {@code null}
* or startIndex is out of bounds
* @since 1.4
*/
public int getNextMatch(String prefix, int startIndex, Position.Bias bias) {
ListModel<E> model = getModel();
int max = model.getSize();
if (prefix == null) {
throw new IllegalArgumentException();
}
if (startIndex < 0 || startIndex >= max) {
throw new IllegalArgumentException();
}
prefix = prefix.toUpperCase();
// start search from the next element after the selected element
int increment = (bias == Position.Bias.Forward) ? 1 : -1;
int index = startIndex;
do {
E element = model.getElementAt(index);
if (element != null) {
String string;
if (element instanceof String) {
string = ((String)element).toUpperCase();
}
else {
string = element.toString();
if (string != null) {
string = string.toUpperCase();
}
}
if (string != null && string.startsWith(prefix)) {
return index;
}
}
index = (index + increment + max) % max;
} while (index != startIndex);
return -1;
}
Returns the tooltip text to be used for the given event. This overrides JComponent
's getToolTipText
to first check the cell renderer component for the cell over which the event occurred, returning its tooltip text, if any. This implementation allows you to specify tooltip text on the cell level, by using setToolTipText
on your cell renderer component.
Note: For JList
to properly display the
tooltips of its renderers in this manner, JList
must be a
registered component with the ToolTipManager
. This registration
is done automatically in the constructor. However, if at a later point
JList
is unregistered, by way of a call to setToolTipText(null)
, tips from the renderers will no longer display.
Params: - event – the
MouseEvent
to fetch the tooltip text for
See Also:
/**
* Returns the tooltip text to be used for the given event. This overrides
* {@code JComponent}'s {@code getToolTipText} to first check the cell
* renderer component for the cell over which the event occurred, returning
* its tooltip text, if any. This implementation allows you to specify
* tooltip text on the cell level, by using {@code setToolTipText} on your
* cell renderer component.
* <p>
* <strong>Note:</strong> For <code>JList</code> to properly display the
* tooltips of its renderers in this manner, <code>JList</code> must be a
* registered component with the <code>ToolTipManager</code>. This registration
* is done automatically in the constructor. However, if at a later point
* <code>JList</code> is unregistered, by way of a call to
* {@code setToolTipText(null)}, tips from the renderers will no longer display.
*
* @param event the {@code MouseEvent} to fetch the tooltip text for
* @see JComponent#setToolTipText
* @see JComponent#getToolTipText
*/
@SuppressWarnings("deprecation")
public String getToolTipText(MouseEvent event) {
if(event != null) {
Point p = event.getPoint();
int index = locationToIndex(p);
ListCellRenderer<? super E> r = getCellRenderer();
Rectangle cellBounds;
if (index != -1 && r != null && (cellBounds =
getCellBounds(index, index)) != null &&
cellBounds.contains(p.x, p.y)) {
ListSelectionModel lsm = getSelectionModel();
Component rComponent = r.getListCellRendererComponent(
this, getModel().getElementAt(index), index,
lsm.isSelectedIndex(index),
(hasFocus() && (lsm.getLeadSelectionIndex() ==
index)));
if(rComponent instanceof JComponent) {
MouseEvent newEvent;
p.translate(-cellBounds.x, -cellBounds.y);
newEvent = new MouseEvent(rComponent, event.getID(),
event.getWhen(),
event.getModifiers(),
p.x, p.y,
event.getXOnScreen(),
event.getYOnScreen(),
event.getClickCount(),
event.isPopupTrigger(),
MouseEvent.NOBUTTON);
MouseEventAccessor meAccessor =
AWTAccessor.getMouseEventAccessor();
meAccessor.setCausedByTouchEvent(newEvent,
meAccessor.isCausedByTouchEvent(event));
String tip = ((JComponent)rComponent).getToolTipText(
newEvent);
if (tip != null) {
return tip;
}
}
}
}
return super.getToolTipText();
}
/**
* --- ListUI Delegations ---
*/
Returns the cell index closest to the given location in the list's coordinate system. To determine if the cell actually contains the specified location, compare the point against the cell's bounds, as provided by getCellBounds
. This method returns -1
if the model is empty This is a cover method that delegates to the method of the same name in the list's ListUI
. It returns -1
if the list has no ListUI
.
Params: - location – the coordinates of the point
Returns: the cell index closest to the given location, or -1
/**
* Returns the cell index closest to the given location in the list's
* coordinate system. To determine if the cell actually contains the
* specified location, compare the point against the cell's bounds,
* as provided by {@code getCellBounds}. This method returns {@code -1}
* if the model is empty
* <p>
* This is a cover method that delegates to the method of the same name
* in the list's {@code ListUI}. It returns {@code -1} if the list has
* no {@code ListUI}.
*
* @param location the coordinates of the point
* @return the cell index closest to the given location, or {@code -1}
*/
public int locationToIndex(Point location) {
ListUI ui = getUI();
return (ui != null) ? ui.locationToIndex(this, location) : -1;
}
Returns the origin of the specified item in the list's coordinate system. This method returns null
if the index isn't valid. This is a cover method that delegates to the method of the same name in the list's ListUI
. It returns null
if the list has no ListUI
.
Params: - index – the cell index
Returns: the origin of the cell, or null
/**
* Returns the origin of the specified item in the list's coordinate
* system. This method returns {@code null} if the index isn't valid.
* <p>
* This is a cover method that delegates to the method of the same name
* in the list's {@code ListUI}. It returns {@code null} if the list has
* no {@code ListUI}.
*
* @param index the cell index
* @return the origin of the cell, or {@code null}
*/
public Point indexToLocation(int index) {
ListUI ui = getUI();
return (ui != null) ? ui.indexToLocation(this, index) : null;
}
Returns the bounding rectangle, in the list's coordinate system,
for the range of cells specified by the two indices.
These indices can be supplied in any order.
If the smaller index is outside the list's range of cells, this method returns null
. If the smaller index is valid, but the larger index is outside the list's range, the bounds of just the first index is returned. Otherwise, the bounds of the valid range is returned.
This is a cover method that delegates to the method of the same name in the list's ListUI
. It returns null
if the list has no ListUI
.
Params: - index0 – the first index in the range
- index1 – the second index in the range
Returns: the bounding rectangle for the range of cells, or null
/**
* Returns the bounding rectangle, in the list's coordinate system,
* for the range of cells specified by the two indices.
* These indices can be supplied in any order.
* <p>
* If the smaller index is outside the list's range of cells, this method
* returns {@code null}. If the smaller index is valid, but the larger
* index is outside the list's range, the bounds of just the first index
* is returned. Otherwise, the bounds of the valid range is returned.
* <p>
* This is a cover method that delegates to the method of the same name
* in the list's {@code ListUI}. It returns {@code null} if the list has
* no {@code ListUI}.
*
* @param index0 the first index in the range
* @param index1 the second index in the range
* @return the bounding rectangle for the range of cells, or {@code null}
*/
public Rectangle getCellBounds(int index0, int index1) {
ListUI ui = getUI();
return (ui != null) ? ui.getCellBounds(this, index0, index1) : null;
}
/**
* --- ListModel Support ---
*/
Returns the data model that holds the list of items displayed
by the JList
component.
See Also: Returns: the ListModel
that provides the displayed
list of items
/**
* Returns the data model that holds the list of items displayed
* by the <code>JList</code> component.
*
* @return the <code>ListModel</code> that provides the displayed
* list of items
* @see #setModel
*/
public ListModel<E> getModel() {
return dataModel;
}
Sets the model that represents the contents or "value" of the
list, notifies property change listeners, and then clears the
list's selection.
This is a JavaBeans bound property.
Params: - model – the
ListModel
that provides the
list of items for display
Throws: - IllegalArgumentException – if
model
is
null
See Also:
/**
* Sets the model that represents the contents or "value" of the
* list, notifies property change listeners, and then clears the
* list's selection.
* <p>
* This is a JavaBeans bound property.
*
* @param model the <code>ListModel</code> that provides the
* list of items for display
* @exception IllegalArgumentException if <code>model</code> is
* <code>null</code>
* @see #getModel
* @see #clearSelection
*/
@BeanProperty(visualUpdate = true, description
= "The object that contains the data to be drawn by this JList.")
public void setModel(ListModel<E> model) {
if (model == null) {
throw new IllegalArgumentException("model must be non null");
}
ListModel<E> oldValue = dataModel;
dataModel = model;
firePropertyChange("model", oldValue, dataModel);
clearSelection();
}
Constructs a read-only ListModel
from an array of items, and calls setModel
with this model. Attempts to pass a 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 invoking this method results in undefined behavior.
Params: - listData – an array of
E
containing the items to display in the list
See Also:
/**
* Constructs a read-only <code>ListModel</code> from an array of items,
* and calls {@code setModel} with this model.
* <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 invoking this method results in undefined behavior.
*
* @param listData an array of {@code E} containing the items to
* display in the list
* @see #setModel
*/
public void setListData(final E[] listData) {
setModel (
new AbstractListModel<E>() {
public int getSize() { return listData.length; }
public E getElementAt(int i) { return listData[i]; }
}
);
}
Constructs a read-only ListModel
from a Vector
and calls setModel
with this model. Attempts to pass a null
value to this method results in undefined behavior and, most likely, exceptions. The created model references the given Vector
directly. Attempts to modify the Vector
after invoking this method results in undefined behavior.
Params: - listData – a
Vector
containing the items to
display in the list
See Also:
/**
* Constructs a read-only <code>ListModel</code> from a <code>Vector</code>
* and calls {@code setModel} with this model.
* <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 invoking this method results in undefined behavior.
*
* @param listData a <code>Vector</code> containing the items to
* display in the list
* @see #setModel
*/
public void setListData(final Vector<? extends E> listData) {
setModel (
new AbstractListModel<E>() {
public int getSize() { return listData.size(); }
public E getElementAt(int i) { return listData.elementAt(i); }
}
);
}
/**
* --- ListSelectionModel delegations and extensions ---
*/
Returns an instance of DefaultListSelectionModel
; called during construction to initialize the list's selection model property. See Also: Returns: a DefaultListSelecitonModel
, used to initialize the list's selection model property during construction
/**
* Returns an instance of {@code DefaultListSelectionModel}; called
* during construction to initialize the list's selection model
* property.
*
* @return a {@code DefaultListSelecitonModel}, used to initialize
* the list's selection model property during construction
* @see #setSelectionModel
* @see DefaultListSelectionModel
*/
protected ListSelectionModel createSelectionModel() {
return new DefaultListSelectionModel();
}
Returns the current selection model. The selection model maintains the
selection state of the list. See the class level documentation for more
details.
See Also: Returns: the ListSelectionModel
that maintains the
list's selections
/**
* Returns the current selection model. The selection model maintains the
* selection state of the list. See the class level documentation for more
* details.
*
* @return the <code>ListSelectionModel</code> that maintains the
* list's selections
*
* @see #setSelectionModel
* @see ListSelectionModel
*/
public ListSelectionModel getSelectionModel() {
return selectionModel;
}
Notifies ListSelectionListener
s added directly to the list of selection changes made to the selection model. JList
listens for changes made to the selection in the selection model, and forwards notification to listeners added to the list directly, by calling this method. This method constructs a ListSelectionEvent
with this list as the source, and the specified arguments, and sends it to the registered ListSelectionListeners
.
Params: - firstIndex – the first index in the range,
<= lastIndex
- lastIndex – the last index in the range,
>= firstIndex
- isAdjusting – whether or not this is one in a series of
multiple events, where changes are still being made
See Also:
/**
* Notifies {@code ListSelectionListener}s added directly to the list
* of selection changes made to the selection model. {@code JList}
* listens for changes made to the selection in the selection model,
* and forwards notification to listeners added to the list directly,
* by calling this method.
* <p>
* This method constructs a {@code ListSelectionEvent} with this list
* as the source, and the specified arguments, and sends it to the
* registered {@code ListSelectionListeners}.
*
* @param firstIndex the first index in the range, {@code <= lastIndex}
* @param lastIndex the last index in the range, {@code >= firstIndex}
* @param isAdjusting whether or not this is one in a series of
* multiple events, where changes are still being made
*
* @see #addListSelectionListener
* @see #removeListSelectionListener
* @see javax.swing.event.ListSelectionEvent
* @see EventListenerList
*/
protected void fireSelectionValueChanged(int firstIndex, int lastIndex,
boolean isAdjusting)
{
Object[] listeners = listenerList.getListenerList();
ListSelectionEvent e = null;
for (int i = listeners.length - 2; i >= 0; i -= 2) {
if (listeners[i] == ListSelectionListener.class) {
if (e == null) {
e = new ListSelectionEvent(this, firstIndex, lastIndex,
isAdjusting);
}
((ListSelectionListener)listeners[i+1]).valueChanged(e);
}
}
}
/* A ListSelectionListener that forwards ListSelectionEvents from
* the selectionModel to the JList ListSelectionListeners. The
* forwarded events only differ from the originals in that their
* source is the JList instead of the selectionModel itself.
*/
private class ListSelectionHandler implements ListSelectionListener, Serializable
{
public void valueChanged(ListSelectionEvent e) {
fireSelectionValueChanged(e.getFirstIndex(),
e.getLastIndex(),
e.getValueIsAdjusting());
}
}
Adds a listener to the list, to be notified each time a change to the selection occurs; the preferred way of listening for selection state changes. JList
takes care of listening for selection state changes in the selection model, and notifies the given listener of each change. ListSelectionEvent
s sent to the listener have a source
property set to this list. Params: - listener – the
ListSelectionListener
to add
See Also:
/**
* Adds a listener to the list, to be notified each time a change to the
* selection occurs; the preferred way of listening for selection state
* changes. {@code JList} takes care of listening for selection state
* changes in the selection model, and notifies the given listener of
* each change. {@code ListSelectionEvent}s sent to the listener have a
* {@code source} property set to this list.
*
* @param listener the {@code ListSelectionListener} to add
* @see #getSelectionModel
* @see #getListSelectionListeners
*/
public void addListSelectionListener(ListSelectionListener listener)
{
if (selectionListener == null) {
selectionListener = new ListSelectionHandler();
getSelectionModel().addListSelectionListener(selectionListener);
}
listenerList.add(ListSelectionListener.class, listener);
}
Removes a selection listener from the list.
Params: - listener – the
ListSelectionListener
to remove
See Also:
/**
* Removes a selection listener from the list.
*
* @param listener the {@code ListSelectionListener} to remove
* @see #addListSelectionListener
* @see #getSelectionModel
*/
public void removeListSelectionListener(ListSelectionListener listener) {
listenerList.remove(ListSelectionListener.class, listener);
}
Returns an array of all the ListSelectionListener
s added to this JList
by way of addListSelectionListener
. See Also: Returns: all of the ListSelectionListener
s on this list, or an empty array if no listeners have been added Since: 1.4
/**
* Returns an array of all the {@code ListSelectionListener}s added
* to this {@code JList} by way of {@code addListSelectionListener}.
*
* @return all of the {@code ListSelectionListener}s on this list, or
* an empty array if no listeners have been added
* @see #addListSelectionListener
* @since 1.4
*/
@BeanProperty(bound = false)
public ListSelectionListener[] getListSelectionListeners() {
return listenerList.getListeners(ListSelectionListener.class);
}
Sets the selectionModel
for the list to a
non-null
ListSelectionModel
implementation. The selection model handles the task of making single
selections, selections of contiguous ranges, and non-contiguous
selections.
This is a JavaBeans bound property.
Params: - selectionModel – the
ListSelectionModel
that
implements the selections
Throws: - IllegalArgumentException – if
selectionModel
is null
See Also:
/**
* Sets the <code>selectionModel</code> for the list to a
* non-<code>null</code> <code>ListSelectionModel</code>
* implementation. The selection model handles the task of making single
* selections, selections of contiguous ranges, and non-contiguous
* selections.
* <p>
* This is a JavaBeans bound property.
*
* @param selectionModel the <code>ListSelectionModel</code> that
* implements the selections
* @exception IllegalArgumentException if <code>selectionModel</code>
* is <code>null</code>
* @see #getSelectionModel
*/
@BeanProperty(description
= "The selection model, recording which cells are selected.")
public void setSelectionModel(ListSelectionModel selectionModel) {
if (selectionModel == null) {
throw new IllegalArgumentException("selectionModel must be non null");
}
/* Remove the forwarding ListSelectionListener from the old
* selectionModel, and add it to the new one, if necessary.
*/
if (selectionListener != null) {
this.selectionModel.removeListSelectionListener(selectionListener);
selectionModel.addListSelectionListener(selectionListener);
}
ListSelectionModel oldValue = this.selectionModel;
this.selectionModel = selectionModel;
firePropertyChange("selectionModel", oldValue, selectionModel);
}
Sets the selection mode for the list. This is a cover method that sets
the selection mode directly on the selection model.
The following list describes the accepted selection modes:
ListSelectionModel.SINGLE_SELECTION
- Only one list index can be selected at a time. In this mode, setSelectionInterval
and addSelectionInterval
are equivalent, both replacing the current selection with the index represented by the second argument (the "lead"). ListSelectionModel.SINGLE_INTERVAL_SELECTION
- Only one contiguous interval can be selected at a time. In this mode, addSelectionInterval
behaves like setSelectionInterval
(replacing the current selection}, unless the given interval is immediately adjacent to or overlaps the existing selection, and can be used to grow the selection. ListSelectionModel.MULTIPLE_INTERVAL_SELECTION
- In this mode, there's no restriction on what can be selected. This mode is the default.
Params: - selectionMode – the selection mode
Throws: - IllegalArgumentException – if the selection mode isn't
one of those allowed
See Also:
/**
* Sets the selection mode for the list. This is a cover method that sets
* the selection mode directly on the selection model.
* <p>
* The following list describes the accepted selection modes:
* <ul>
* <li>{@code ListSelectionModel.SINGLE_SELECTION} -
* Only one list index can be selected at a time. In this mode,
* {@code setSelectionInterval} and {@code addSelectionInterval} are
* equivalent, both replacing the current selection with the index
* represented by the second argument (the "lead").
* <li>{@code ListSelectionModel.SINGLE_INTERVAL_SELECTION} -
* Only one contiguous interval can be selected at a time.
* In this mode, {@code addSelectionInterval} behaves like
* {@code setSelectionInterval} (replacing the current selection},
* unless the given interval is immediately adjacent to or overlaps
* the existing selection, and can be used to grow the selection.
* <li>{@code ListSelectionModel.MULTIPLE_INTERVAL_SELECTION} -
* In this mode, there's no restriction on what can be selected.
* This mode is the default.
* </ul>
*
* @param selectionMode the selection mode
* @see #getSelectionMode
* @throws IllegalArgumentException if the selection mode isn't
* one of those allowed
*/
@BeanProperty(bound = false, enumerationValues = {
"ListSelectionModel.SINGLE_SELECTION",
"ListSelectionModel.SINGLE_INTERVAL_SELECTION",
"ListSelectionModel.MULTIPLE_INTERVAL_SELECTION"}, description
= "The selection mode.")
public void setSelectionMode(int selectionMode) {
getSelectionModel().setSelectionMode(selectionMode);
}
Returns the current selection mode for the list. This is a cover
method that delegates to the method of the same name on the
list's selection model.
See Also: Returns: the current selection mode
/**
* Returns the current selection mode for the list. This is a cover
* method that delegates to the method of the same name on the
* list's selection model.
*
* @return the current selection mode
* @see #setSelectionMode
*/
public int getSelectionMode() {
return getSelectionModel().getSelectionMode();
}
Returns the anchor selection index. This is a cover method that
delegates to the method of the same name on the list's selection model.
See Also: Returns: the anchor selection index
/**
* Returns the anchor selection index. This is a cover method that
* delegates to the method of the same name on the list's selection model.
*
* @return the anchor selection index
* @see ListSelectionModel#getAnchorSelectionIndex
*/
@BeanProperty(bound = false)
public int getAnchorSelectionIndex() {
return getSelectionModel().getAnchorSelectionIndex();
}
Returns the lead selection index. This is a cover method that
delegates to the method of the same name on the list's selection model.
See Also: Returns: the lead selection index
/**
* Returns the lead selection index. This is a cover method that
* delegates to the method of the same name on the list's selection model.
*
* @return the lead selection index
* @see ListSelectionModel#getLeadSelectionIndex
*/
@BeanProperty(bound = false, description
= "The lead selection index.")
public int getLeadSelectionIndex() {
return getSelectionModel().getLeadSelectionIndex();
}
Returns the smallest selected cell index, or -1
if the selection is empty. This is a cover method that delegates to the method of the same name on the list's selection model. See Also: Returns: the smallest selected cell index, or -1
/**
* Returns the smallest selected cell index, or {@code -1} if the selection
* is empty. This is a cover method that delegates to the method of the same
* name on the list's selection model.
*
* @return the smallest selected cell index, or {@code -1}
* @see ListSelectionModel#getMinSelectionIndex
*/
@BeanProperty(bound = false)
public int getMinSelectionIndex() {
return getSelectionModel().getMinSelectionIndex();
}
Returns the largest selected cell index, or -1
if the selection is empty. This is a cover method that delegates to the method of the same name on the list's selection model. See Also: Returns: the largest selected cell index
/**
* Returns the largest selected cell index, or {@code -1} if the selection
* is empty. This is a cover method that delegates to the method of the same
* name on the list's selection model.
*
* @return the largest selected cell index
* @see ListSelectionModel#getMaxSelectionIndex
*/
@BeanProperty(bound = false)
public int getMaxSelectionIndex() {
return getSelectionModel().getMaxSelectionIndex();
}
Returns true
if the specified index is selected, else false
. This is a cover method that delegates to the method of the same name on the list's selection model. Params: - index – index to be queried for selection state
See Also: Returns: true
if the specified index is selected, else false
/**
* Returns {@code true} if the specified index is selected,
* else {@code false}. This is a cover method that delegates to the method
* of the same name on the list's selection model.
*
* @param index index to be queried for selection state
* @return {@code true} if the specified index is selected,
* else {@code false}
* @see ListSelectionModel#isSelectedIndex
* @see #setSelectedIndex
*/
public boolean isSelectedIndex(int index) {
return getSelectionModel().isSelectedIndex(index);
}
Returns true
if nothing is selected, else false
. This is a cover method that delegates to the method of the same name on the list's selection model. See Also: Returns: true
if nothing is selected, else false
/**
* Returns {@code true} if nothing is selected, else {@code false}.
* This is a cover method that delegates to the method of the same
* name on the list's selection model.
*
* @return {@code true} if nothing is selected, else {@code false}
* @see ListSelectionModel#isSelectionEmpty
* @see #clearSelection
*/
@BeanProperty(bound = false)
public boolean isSelectionEmpty() {
return getSelectionModel().isSelectionEmpty();
}
Clears the selection; after calling this method, isSelectionEmpty
will return true
. This is a cover method that delegates to the method of the same name on the list's selection model. See Also:
/**
* Clears the selection; after calling this method, {@code isSelectionEmpty}
* will return {@code true}. This is a cover method that delegates to the
* method of the same name on the list's selection model.
*
* @see ListSelectionModel#clearSelection
* @see #isSelectionEmpty
*/
public void clearSelection() {
getSelectionModel().clearSelection();
}
Selects the specified interval. Both anchor
and lead
indices are included. anchor
doesn't have to be less than or equal to lead
. This is a cover method that delegates to the method of the same name on the list's selection model. Refer to the documentation of the selection model class being used for details on how values less than 0
are handled.
Params: - anchor – the first index to select
- lead – the last index to select
See Also:
/**
* Selects the specified interval. Both {@code anchor} and {@code lead}
* indices are included. {@code anchor} doesn't have to be less than or
* equal to {@code lead}. This is a cover method that delegates to the
* method of the same name on the list's selection model.
* <p>
* Refer to the documentation of the selection model class being used
* for details on how values less than {@code 0} are handled.
*
* @param anchor the first index to select
* @param lead the last index to select
* @see ListSelectionModel#setSelectionInterval
* @see DefaultListSelectionModel#setSelectionInterval
* @see #createSelectionModel
* @see #addSelectionInterval
* @see #removeSelectionInterval
*/
public void setSelectionInterval(int anchor, int lead) {
getSelectionModel().setSelectionInterval(anchor, lead);
}
Sets the selection to be the union of the specified interval with current selection. Both the anchor
and lead
indices are included. anchor
doesn't have to be less than or equal to lead
. This is a cover method that delegates to the method of the same name on the list's selection model. Refer to the documentation of the selection model class being used for details on how values less than 0
are handled.
Params: - anchor – the first index to add to the selection
- lead – the last index to add to the selection
See Also:
/**
* Sets the selection to be the union of the specified interval with current
* selection. Both the {@code anchor} and {@code lead} indices are
* included. {@code anchor} doesn't have to be less than or
* equal to {@code lead}. This is a cover method that delegates to the
* method of the same name on the list's selection model.
* <p>
* Refer to the documentation of the selection model class being used
* for details on how values less than {@code 0} are handled.
*
* @param anchor the first index to add to the selection
* @param lead the last index to add to the selection
* @see ListSelectionModel#addSelectionInterval
* @see DefaultListSelectionModel#addSelectionInterval
* @see #createSelectionModel
* @see #setSelectionInterval
* @see #removeSelectionInterval
*/
public void addSelectionInterval(int anchor, int lead) {
getSelectionModel().addSelectionInterval(anchor, lead);
}
Sets the selection to be the set difference of the specified interval and the current selection. Both the index0
and index1
indices are removed. index0
doesn't have to be less than or equal to index1
. This is a cover method that delegates to the method of the same name on the list's selection model. Refer to the documentation of the selection model class being used for details on how values less than 0
are handled.
Params: - index0 – the first index to remove from the selection
- index1 – the last index to remove from the selection
See Also:
/**
* Sets the selection to be the set difference of the specified interval
* and the current selection. Both the {@code index0} and {@code index1}
* indices are removed. {@code index0} doesn't have to be less than or
* equal to {@code index1}. This is a cover method that delegates to the
* method of the same name on the list's selection model.
* <p>
* Refer to the documentation of the selection model class being used
* for details on how values less than {@code 0} are handled.
*
* @param index0 the first index to remove from the selection
* @param index1 the last index to remove from the selection
* @see ListSelectionModel#removeSelectionInterval
* @see DefaultListSelectionModel#removeSelectionInterval
* @see #createSelectionModel
* @see #setSelectionInterval
* @see #addSelectionInterval
*/
public void removeSelectionInterval(int index0, int index1) {
getSelectionModel().removeSelectionInterval(index0, index1);
}
Sets the selection model's valueIsAdjusting
property. When true
, upcoming changes to selection should be considered part of a single change. This property is used internally and developers typically need not call this method. For example, when the model is being updated in response to a user drag, the value of the property is set to true
when the drag is initiated and set to false
when the drag is finished. This allows listeners to update only when a change has been finalized, rather than handling all of the intermediate values.
You may want to use this directly if making a series of changes
that should be considered part of a single change.
This is a cover method that delegates to the method of the same name on the list's selection model. See the documentation for ListSelectionModel.setValueIsAdjusting
for more details.
Params: - b – the new value for the property
See Also:
/**
* Sets the selection model's {@code valueIsAdjusting} property. When
* {@code true}, upcoming changes to selection should be considered part
* of a single change. This property is used internally and developers
* typically need not call this method. For example, when the model is being
* updated in response to a user drag, the value of the property is set
* to {@code true} when the drag is initiated and set to {@code false}
* when the drag is finished. This allows listeners to update only
* when a change has been finalized, rather than handling all of the
* intermediate values.
* <p>
* You may want to use this directly if making a series of changes
* that should be considered part of a single change.
* <p>
* This is a cover method that delegates to the method of the same name on
* the list's selection model. See the documentation for
* {@link javax.swing.ListSelectionModel#setValueIsAdjusting} for
* more details.
*
* @param b the new value for the property
* @see ListSelectionModel#setValueIsAdjusting
* @see javax.swing.event.ListSelectionEvent#getValueIsAdjusting
* @see #getValueIsAdjusting
*/
public void setValueIsAdjusting(boolean b) {
getSelectionModel().setValueIsAdjusting(b);
}
Returns the value of the selection model's isAdjusting
property.
This is a cover method that delegates to the method of the same name on
the list's selection model.
See Also: Returns: the value of the selection model's isAdjusting
property.
/**
* Returns the value of the selection model's {@code isAdjusting} property.
* <p>
* This is a cover method that delegates to the method of the same name on
* the list's selection model.
*
* @return the value of the selection model's {@code isAdjusting} property.
*
* @see #setValueIsAdjusting
* @see ListSelectionModel#getValueIsAdjusting
*/
public boolean getValueIsAdjusting() {
return getSelectionModel().getValueIsAdjusting();
}
Returns an array of all of the selected indices, in increasing
order.
See Also: Returns: all of the selected indices, in increasing order,
or an empty array if nothing is selected
/**
* Returns an array of all of the selected indices, in increasing
* order.
*
* @return all of the selected indices, in increasing order,
* or an empty array if nothing is selected
* @see #removeSelectionInterval
* @see #addListSelectionListener
*/
@Transient
public int[] getSelectedIndices() {
return getSelectionModel().getSelectedIndices();
}
Selects a single cell. Does nothing if the given index is greater than or equal to the model size. This is a convenience method that uses setSelectionInterval
on the selection model. Refer to the documentation for the selection model class being used for details on how values less than 0
are handled. Params: - index – the index of the cell to select
See Also:
/**
* Selects a single cell. Does nothing if the given index is greater
* than or equal to the model size. This is a convenience method that uses
* {@code setSelectionInterval} on the selection model. Refer to the
* documentation for the selection model class being used for details on
* how values less than {@code 0} are handled.
*
* @param index the index of the cell to select
* @see ListSelectionModel#setSelectionInterval
* @see #isSelectedIndex
* @see #addListSelectionListener
*/
@BeanProperty(bound = false, description
= "The index of the selected cell.")
public void setSelectedIndex(int index) {
if (index >= getModel().getSize()) {
return;
}
getSelectionModel().setSelectionInterval(index, index);
}
Changes the selection to be the set of indices specified by the given array. Indices greater than or equal to the model size are ignored. This is a convenience method that clears the selection and then uses addSelectionInterval
on the selection model to add the indices. Refer to the documentation of the selection model class being used for details on how values less than 0
are handled. Params: - indices – an array of the indices of the cells to select,
non-null
Throws: - NullPointerException – if the given array is
null
See Also:
/**
* Changes the selection to be the set of indices specified by the given
* array. Indices greater than or equal to the model size are ignored.
* This is a convenience method that clears the selection and then uses
* {@code addSelectionInterval} on the selection model to add the indices.
* Refer to the documentation of the selection model class being used for
* details on how values less than {@code 0} are handled.
*
* @param indices an array of the indices of the cells to select,
* {@code non-null}
* @see ListSelectionModel#addSelectionInterval
* @see #isSelectedIndex
* @see #addListSelectionListener
* @throws NullPointerException if the given array is {@code null}
*/
public void setSelectedIndices(int[] indices) {
ListSelectionModel sm = getSelectionModel();
sm.clearSelection();
int size = getModel().getSize();
for (int i : indices) {
if (i < size) {
sm.addSelectionInterval(i, i);
}
}
}
Returns an array of all the selected values, in increasing order based
on their indices in the list.
See Also: Returns: the selected values, or an empty array if nothing is selected Deprecated: As of JDK 1.7, replaced by getSelectedValuesList()
/**
* Returns an array of all the selected values, in increasing order based
* on their indices in the list.
*
* @return the selected values, or an empty array if nothing is selected
* @see #isSelectedIndex
* @see #getModel
* @see #addListSelectionListener
*
* @deprecated As of JDK 1.7, replaced by {@link #getSelectedValuesList()}
*/
@Deprecated
@BeanProperty(bound = false)
public Object[] getSelectedValues() {
ListSelectionModel sm = getSelectionModel();
ListModel<E> dm = getModel();
int iMin = sm.getMinSelectionIndex();
int iMax = sm.getMaxSelectionIndex();
int size = dm.getSize();
if ((iMin < 0) || (iMax < 0) || (iMin >= size)) {
return new Object[0];
}
iMax = iMax < size ? iMax : size - 1;
Object[] rvTmp = new Object[1+ (iMax - iMin)];
int n = 0;
for(int i = iMin; i <= iMax; i++) {
if (sm.isSelectedIndex(i)) {
rvTmp[n++] = dm.getElementAt(i);
}
}
Object[] rv = new Object[n];
System.arraycopy(rvTmp, 0, rv, 0, n);
return rv;
}
Returns a list of all the selected items, in increasing order based
on their indices in the list.
See Also: Returns: the selected items, or an empty list if nothing is selected Since: 1.7
/**
* Returns a list of all the selected items, in increasing order based
* on their indices in the list.
*
* @return the selected items, or an empty list if nothing is selected
* @see #isSelectedIndex
* @see #getModel
* @see #addListSelectionListener
*
* @since 1.7
*/
@BeanProperty(bound = false)
public List<E> getSelectedValuesList() {
ListModel<E> dm = getModel();
int[] selectedIndices = getSelectedIndices();
if (selectedIndices.length > 0) {
int size = dm.getSize();
if (selectedIndices[0] >= size) {
return Collections.emptyList();
}
List<E> selectedItems = new ArrayList<E>();
for (int i : selectedIndices) {
if (i >= size)
break;
selectedItems.add(dm.getElementAt(i));
}
return selectedItems;
}
return Collections.emptyList();
}
Returns the smallest selected cell index; the selection when only a single item is selected in the list. When multiple items are selected, it is simply the smallest selected index. Returns -1
if there is no selection. This method is a cover that delegates to getMinSelectionIndex
.
See Also: Returns: the smallest selected cell index
/**
* Returns the smallest selected cell index; <i>the selection</i> when only
* a single item is selected in the list. When multiple items are selected,
* it is simply the smallest selected index. Returns {@code -1} if there is
* no selection.
* <p>
* This method is a cover that delegates to {@code getMinSelectionIndex}.
*
* @return the smallest selected cell index
* @see #getMinSelectionIndex
* @see #addListSelectionListener
*/
public int getSelectedIndex() {
return getMinSelectionIndex();
}
Returns the value for the smallest selected cell index;
the selected value when only a single item is selected in the list. When multiple items are selected, it is simply the value for the smallest selected index. Returns null
if there is no selection. This is a convenience method that simply returns the model value for getMinSelectionIndex
.
See Also: Returns: the first selected value
/**
* Returns the value for the smallest selected cell index;
* <i>the selected value</i> when only a single item is selected in the
* list. When multiple items are selected, it is simply the value for the
* smallest selected index. Returns {@code null} if there is no selection.
* <p>
* This is a convenience method that simply returns the model value for
* {@code getMinSelectionIndex}.
*
* @return the first selected value
* @see #getMinSelectionIndex
* @see #getModel
* @see #addListSelectionListener
*/
@BeanProperty(bound = false)
public E getSelectedValue() {
int i = getMinSelectionIndex();
return ((i == -1) || (i >= getModel().getSize())) ? null :
getModel().getElementAt(i);
}
Selects the specified object from the list. If the object passed is null
, the selection is cleared. Params: - anObject – the object to select
- shouldScroll –
true
if the list should scroll to display the selected object, if one exists; otherwise false
/**
* Selects the specified object from the list.
* If the object passed is {@code null}, the selection is cleared.
*
* @param anObject the object to select
* @param shouldScroll {@code true} if the list should scroll to display
* the selected object, if one exists; otherwise {@code false}
*/
public void setSelectedValue(Object anObject,boolean shouldScroll) {
if(anObject == null)
clearSelection();
else if(!anObject.equals(getSelectedValue())) {
int i,c;
ListModel<E> dm = getModel();
for(i=0,c=dm.getSize();i<c;i++)
if(anObject.equals(dm.getElementAt(i))){
setSelectedIndex(i);
if(shouldScroll)
ensureIndexIsVisible(i);
repaint(); /** FIX-ME setSelectedIndex does not redraw all the time with the basic l&f**/
return;
}
setSelectedIndex(-1);
}
repaint(); /** FIX-ME setSelectedIndex does not redraw all the time with the basic l&f**/
}
--- The Scrollable Implementation ---
/**
* --- The Scrollable Implementation ---
*/
private void checkScrollableParameters(Rectangle visibleRect, int orientation) {
if (visibleRect == null) {
throw new IllegalArgumentException("visibleRect must be non-null");
}
switch (orientation) {
case SwingConstants.VERTICAL:
case SwingConstants.HORIZONTAL:
break;
default:
throw new IllegalArgumentException("orientation must be one of: VERTICAL, HORIZONTAL");
}
}
Computes the size of viewport needed to display visibleRowCount
rows. The value returned by this method depends on the layout orientation:
VERTICAL
:
This is trivial if both fixedCellWidth
and fixedCellHeight
have been set (either explicitly or by specifying a prototype cell value). The width is simply the fixedCellWidth
plus the list's horizontal insets. The height is the fixedCellHeight
multiplied by the visibleRowCount
, plus the list's vertical insets.
If either fixedCellWidth
or fixedCellHeight
haven't been specified, heuristics are used. If the model is empty, the width is the fixedCellWidth
, if greater than 0
, or a hard-coded value of 256
. The height is the fixedCellHeight
multiplied by visibleRowCount
, if fixedCellHeight
is greater than 0
, otherwise it is a hard-coded value of 16
multiplied by visibleRowCount
.
If the model isn't empty, the width is the preferred size's width, typically the width of the widest list element. The height is the height of the cell with index 0 multiplied by the visibleRowCount
, plus the list's vertical insets.
VERTICAL_WRAP
or HORIZONTAL_WRAP
:
This method simply returns the value from getPreferredSize
. The list's ListUI
is expected to override getPreferredSize
to return an appropriate value.
See Also: Returns: a dimension containing the size of the viewport needed to display visibleRowCount
rows
/**
* Computes the size of viewport needed to display {@code visibleRowCount}
* rows. The value returned by this method depends on the layout
* orientation:
* <p>
* <b>{@code VERTICAL}:</b>
* <br>
* This is trivial if both {@code fixedCellWidth} and {@code fixedCellHeight}
* have been set (either explicitly or by specifying a prototype cell value).
* The width is simply the {@code fixedCellWidth} plus the list's horizontal
* insets. The height is the {@code fixedCellHeight} multiplied by the
* {@code visibleRowCount}, plus the list's vertical insets.
* <p>
* If either {@code fixedCellWidth} or {@code fixedCellHeight} haven't been
* specified, heuristics are used. If the model is empty, the width is
* the {@code fixedCellWidth}, if greater than {@code 0}, or a hard-coded
* value of {@code 256}. The height is the {@code fixedCellHeight} multiplied
* by {@code visibleRowCount}, if {@code fixedCellHeight} is greater than
* {@code 0}, otherwise it is a hard-coded value of {@code 16} multiplied by
* {@code visibleRowCount}.
* <p>
* If the model isn't empty, the width is the preferred size's width,
* typically the width of the widest list element. The height is the
* height of the cell with index 0 multiplied by the {@code visibleRowCount},
* plus the list's vertical insets.
* <p>
* <b>{@code VERTICAL_WRAP} or {@code HORIZONTAL_WRAP}:</b>
* <br>
* This method simply returns the value from {@code getPreferredSize}.
* The list's {@code ListUI} is expected to override {@code getPreferredSize}
* to return an appropriate value.
*
* @return a dimension containing the size of the viewport needed
* to display {@code visibleRowCount} rows
* @see #getPreferredScrollableViewportSize
* @see #setPrototypeCellValue
*/
@BeanProperty(bound = false)
public Dimension getPreferredScrollableViewportSize()
{
if (getLayoutOrientation() != VERTICAL) {
return getPreferredSize();
}
Insets insets = getInsets();
int dx = insets.left + insets.right;
int dy = insets.top + insets.bottom;
int visibleRowCount = getVisibleRowCount();
int fixedCellWidth = getFixedCellWidth();
int fixedCellHeight = getFixedCellHeight();
if ((fixedCellWidth > 0) && (fixedCellHeight > 0)) {
int width = fixedCellWidth + dx;
int height = (visibleRowCount * fixedCellHeight) + dy;
return new Dimension(width, height);
}
else if (getModel().getSize() > 0) {
int width = getPreferredSize().width;
int height;
Rectangle r = getCellBounds(0, 0);
if (r != null) {
height = (visibleRowCount * r.height) + dy;
}
else {
// Will only happen if UI null, shouldn't matter what we return
height = 1;
}
return new Dimension(width, height);
}
else {
fixedCellWidth = (fixedCellWidth > 0) ? fixedCellWidth : 256;
fixedCellHeight = (fixedCellHeight > 0) ? fixedCellHeight : 16;
return new Dimension(fixedCellWidth, fixedCellHeight * visibleRowCount);
}
}
Returns the distance to scroll to expose the next or previous
row (for vertical scrolling) or column (for horizontal scrolling).
For horizontal scrolling, if the layout orientation is VERTICAL
, then the list's font size is returned (or 1
if the font is null
).
Params: - visibleRect – the view area visible within the viewport
- orientation –
SwingConstants.HORIZONTAL
or SwingConstants.VERTICAL
- direction – less or equal to zero to scroll up/back,
greater than zero for down/forward
Throws: - IllegalArgumentException – if
visibleRect
is null
, or orientation
isn't one of SwingConstants.VERTICAL
or SwingConstants.HORIZONTAL
See Also: Returns: the "unit" increment for scrolling in the specified direction;
always positive
/**
* Returns the distance to scroll to expose the next or previous
* row (for vertical scrolling) or column (for horizontal scrolling).
* <p>
* For horizontal scrolling, if the layout orientation is {@code VERTICAL},
* then the list's font size is returned (or {@code 1} if the font is
* {@code null}).
*
* @param visibleRect the view area visible within the viewport
* @param orientation {@code SwingConstants.HORIZONTAL} or
* {@code SwingConstants.VERTICAL}
* @param direction less or equal to zero to scroll up/back,
* greater than zero for down/forward
* @return the "unit" increment for scrolling in the specified direction;
* always positive
* @see #getScrollableBlockIncrement
* @see Scrollable#getScrollableUnitIncrement
* @throws IllegalArgumentException if {@code visibleRect} is {@code null}, or
* {@code orientation} isn't one of {@code SwingConstants.VERTICAL} or
* {@code SwingConstants.HORIZONTAL}
*/
public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction)
{
checkScrollableParameters(visibleRect, orientation);
if (orientation == SwingConstants.VERTICAL) {
int row = locationToIndex(visibleRect.getLocation());
if (row == -1) {
return 0;
}
else {
/* Scroll Down */
if (direction > 0) {
Rectangle r = getCellBounds(row, row);
return (r == null) ? 0 : r.height - (visibleRect.y - r.y);
}
/* Scroll Up */
else {
Rectangle r = getCellBounds(row, row);
/* The first row is completely visible and it's row 0.
* We're done.
*/
if ((r.y == visibleRect.y) && (row == 0)) {
return 0;
}
/* The first row is completely visible, return the
* height of the previous row or 0 if the first row
* is the top row of the list.
*/
else if (r.y == visibleRect.y) {
Point loc = r.getLocation();
loc.y--;
int prevIndex = locationToIndex(loc);
Rectangle prevR = getCellBounds(prevIndex, prevIndex);
if (prevR == null || prevR.y >= r.y) {
return 0;
}
return prevR.height;
}
/* The first row is partially visible, return the
* height of hidden part.
*/
else {
return visibleRect.y - r.y;
}
}
}
} else if (orientation == SwingConstants.HORIZONTAL &&
getLayoutOrientation() != JList.VERTICAL) {
boolean leftToRight = getComponentOrientation().isLeftToRight();
int index;
Point leadingPoint;
if (leftToRight) {
leadingPoint = visibleRect.getLocation();
}
else {
leadingPoint = new Point(visibleRect.x + visibleRect.width -1,
visibleRect.y);
}
index = locationToIndex(leadingPoint);
if (index != -1) {
Rectangle cellBounds = getCellBounds(index, index);
if (cellBounds != null && cellBounds.contains(leadingPoint)) {
int leadingVisibleEdge;
int leadingCellEdge;
if (leftToRight) {
leadingVisibleEdge = visibleRect.x;
leadingCellEdge = cellBounds.x;
}
else {
leadingVisibleEdge = visibleRect.x + visibleRect.width;
leadingCellEdge = cellBounds.x + cellBounds.width;
}
if (leadingCellEdge != leadingVisibleEdge) {
if (direction < 0) {
// Show remainder of leading cell
return Math.abs(leadingVisibleEdge - leadingCellEdge);
}
else if (leftToRight) {
// Hide rest of leading cell
return leadingCellEdge + cellBounds.width - leadingVisibleEdge;
}
else {
// Hide rest of leading cell
return leadingVisibleEdge - cellBounds.x;
}
}
// ASSUME: All cells are the same width
return cellBounds.width;
}
}
}
Font f = getFont();
return (f != null) ? f.getSize() : 1;
}
Returns the distance to scroll to expose the next or previous block.
For vertical scrolling, the following rules are used:
- if scrolling down, returns the distance to scroll so that the last
visible element becomes the first completely visible element
- if scrolling up, returns the distance to scroll so that the first
visible element becomes the last completely visible element
- returns
visibleRect.height
if the list is empty
For horizontal scrolling, when the layout orientation is either VERTICAL_WRAP
or HORIZONTAL_WRAP
:
- if scrolling right, returns the distance to scroll so that the
last visible element becomes
the first completely visible element
- if scrolling left, returns the distance to scroll so that the first
visible element becomes the last completely visible element
- returns
visibleRect.width
if the list is empty
For horizontal scrolling and VERTICAL
orientation, returns visibleRect.width
.
Note that the value of visibleRect
must be the equal to this.getVisibleRect()
.
Params: - visibleRect – the view area visible within the viewport
- orientation –
SwingConstants.HORIZONTAL
or SwingConstants.VERTICAL
- direction – less or equal to zero to scroll up/back,
greater than zero for down/forward
Throws: - IllegalArgumentException – if
visibleRect
is null
, or orientation
isn't one of SwingConstants.VERTICAL
or SwingConstants.HORIZONTAL
See Also: Returns: the "block" increment for scrolling in the specified direction;
always positive
/**
* Returns the distance to scroll to expose the next or previous block.
* <p>
* For vertical scrolling, the following rules are used:
* <ul>
* <li>if scrolling down, returns the distance to scroll so that the last
* visible element becomes the first completely visible element
* <li>if scrolling up, returns the distance to scroll so that the first
* visible element becomes the last completely visible element
* <li>returns {@code visibleRect.height} if the list is empty
* </ul>
* <p>
* For horizontal scrolling, when the layout orientation is either
* {@code VERTICAL_WRAP} or {@code HORIZONTAL_WRAP}:
* <ul>
* <li>if scrolling right, returns the distance to scroll so that the
* last visible element becomes
* the first completely visible element
* <li>if scrolling left, returns the distance to scroll so that the first
* visible element becomes the last completely visible element
* <li>returns {@code visibleRect.width} if the list is empty
* </ul>
* <p>
* For horizontal scrolling and {@code VERTICAL} orientation,
* returns {@code visibleRect.width}.
* <p>
* Note that the value of {@code visibleRect} must be the equal to
* {@code this.getVisibleRect()}.
*
* @param visibleRect the view area visible within the viewport
* @param orientation {@code SwingConstants.HORIZONTAL} or
* {@code SwingConstants.VERTICAL}
* @param direction less or equal to zero to scroll up/back,
* greater than zero for down/forward
* @return the "block" increment for scrolling in the specified direction;
* always positive
* @see #getScrollableUnitIncrement
* @see Scrollable#getScrollableBlockIncrement
* @throws IllegalArgumentException if {@code visibleRect} is {@code null}, or
* {@code orientation} isn't one of {@code SwingConstants.VERTICAL} or
* {@code SwingConstants.HORIZONTAL}
*/
public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) {
checkScrollableParameters(visibleRect, orientation);
if (orientation == SwingConstants.VERTICAL) {
int inc = visibleRect.height;
/* Scroll Down */
if (direction > 0) {
// last cell is the lowest left cell
int last = locationToIndex(new Point(visibleRect.x, visibleRect.y+visibleRect.height-1));
if (last != -1) {
Rectangle lastRect = getCellBounds(last,last);
if (lastRect != null) {
inc = lastRect.y - visibleRect.y;
if ( (inc == 0) && (last < getModel().getSize()-1) ) {
inc = lastRect.height;
}
}
}
}
/* Scroll Up */
else {
int newFirst = locationToIndex(new Point(visibleRect.x, visibleRect.y-visibleRect.height));
int first = getFirstVisibleIndex();
if (newFirst != -1) {
if (first == -1) {
first = locationToIndex(visibleRect.getLocation());
}
Rectangle newFirstRect = getCellBounds(newFirst,newFirst);
Rectangle firstRect = getCellBounds(first,first);
if ((newFirstRect != null) && (firstRect!=null)) {
while ( (newFirstRect.y + visibleRect.height <
firstRect.y + firstRect.height) &&
(newFirstRect.y < firstRect.y) ) {
newFirst++;
newFirstRect = getCellBounds(newFirst,newFirst);
}
inc = visibleRect.y - newFirstRect.y;
if ( (inc <= 0) && (newFirstRect.y > 0)) {
newFirst--;
newFirstRect = getCellBounds(newFirst,newFirst);
if (newFirstRect != null) {
inc = visibleRect.y - newFirstRect.y;
}
}
}
}
}
return inc;
}
else if (orientation == SwingConstants.HORIZONTAL &&
getLayoutOrientation() != JList.VERTICAL) {
boolean leftToRight = getComponentOrientation().isLeftToRight();
int inc = visibleRect.width;
/* Scroll Right (in ltr mode) or Scroll Left (in rtl mode) */
if (direction > 0) {
// position is upper right if ltr, or upper left otherwise
int x = visibleRect.x + (leftToRight ? (visibleRect.width - 1) : 0);
int last = locationToIndex(new Point(x, visibleRect.y));
if (last != -1) {
Rectangle lastRect = getCellBounds(last,last);
if (lastRect != null) {
if (leftToRight) {
inc = lastRect.x - visibleRect.x;
} else {
inc = visibleRect.x + visibleRect.width
- (lastRect.x + lastRect.width);
}
if (inc < 0) {
inc += lastRect.width;
} else if ( (inc == 0) && (last < getModel().getSize()-1) ) {
inc = lastRect.width;
}
}
}
}
/* Scroll Left (in ltr mode) or Scroll Right (in rtl mode) */
else {
// position is upper left corner of the visibleRect shifted
// left by the visibleRect.width if ltr, or upper right shifted
// right by the visibleRect.width otherwise
int x = visibleRect.x + (leftToRight
? -visibleRect.width
: visibleRect.width - 1 + visibleRect.width);
int first = locationToIndex(new Point(x, visibleRect.y));
if (first != -1) {
Rectangle firstRect = getCellBounds(first,first);
if (firstRect != null) {
// the right of the first cell
int firstRight = firstRect.x + firstRect.width;
if (leftToRight) {
if ((firstRect.x < visibleRect.x - visibleRect.width)
&& (firstRight < visibleRect.x)) {
inc = visibleRect.x - firstRight;
} else {
inc = visibleRect.x - firstRect.x;
}
} else {
int visibleRight = visibleRect.x + visibleRect.width;
if ((firstRight > visibleRight + visibleRect.width)
&& (firstRect.x > visibleRight)) {
inc = firstRect.x - visibleRight;
} else {
inc = firstRight - visibleRight;
}
}
}
}
}
return inc;
}
return visibleRect.width;
}
Returns true
if this JList
is displayed in a JViewport
and the viewport is wider than the list's preferred width, or if the layout orientation is HORIZONTAL_WRAP
and visibleRowCount <= 0
; otherwise returns false
. If false
, then don't track the viewport's width. This allows horizontal scrolling if the JViewport
is itself embedded in a JScrollPane
.
See Also: Returns: whether or not an enclosing viewport should force the list's
width to match its own
/**
* Returns {@code true} if this {@code JList} is displayed in a
* {@code JViewport} and the viewport is wider than the list's
* preferred width, or if the layout orientation is {@code HORIZONTAL_WRAP}
* and {@code visibleRowCount <= 0}; otherwise returns {@code false}.
* <p>
* If {@code false}, then don't track the viewport's width. This allows
* horizontal scrolling if the {@code JViewport} is itself embedded in a
* {@code JScrollPane}.
*
* @return whether or not an enclosing viewport should force the list's
* width to match its own
* @see Scrollable#getScrollableTracksViewportWidth
*/
@BeanProperty(bound = false)
public boolean getScrollableTracksViewportWidth() {
if (getLayoutOrientation() == HORIZONTAL_WRAP &&
getVisibleRowCount() <= 0) {
return true;
}
Container parent = SwingUtilities.getUnwrappedParent(this);
if (parent instanceof JViewport) {
return parent.getWidth() > getPreferredSize().width;
}
return false;
}
Returns true
if this JList
is displayed in a JViewport
and the viewport is taller than the list's preferred height, or if the layout orientation is VERTICAL_WRAP
and visibleRowCount <= 0
; otherwise returns false
. If false
, then don't track the viewport's height. This allows vertical scrolling if the JViewport
is itself embedded in a JScrollPane
.
See Also: Returns: whether or not an enclosing viewport should force the list's
height to match its own
/**
* Returns {@code true} if this {@code JList} is displayed in a
* {@code JViewport} and the viewport is taller than the list's
* preferred height, or if the layout orientation is {@code VERTICAL_WRAP}
* and {@code visibleRowCount <= 0}; otherwise returns {@code false}.
* <p>
* If {@code false}, then don't track the viewport's height. This allows
* vertical scrolling if the {@code JViewport} is itself embedded in a
* {@code JScrollPane}.
*
* @return whether or not an enclosing viewport should force the list's
* height to match its own
* @see Scrollable#getScrollableTracksViewportHeight
*/
@BeanProperty(bound = false)
public boolean getScrollableTracksViewportHeight() {
if (getLayoutOrientation() == VERTICAL_WRAP &&
getVisibleRowCount() <= 0) {
return true;
}
Container parent = SwingUtilities.getUnwrappedParent(this);
if (parent instanceof JViewport) {
return parent.getHeight() > getPreferredSize().height;
}
return false;
}
/*
* See {@code readObject} and {@code writeObject} in {@code JComponent}
* for more information about serialization in Swing.
*/
private void writeObject(ObjectOutputStream s) throws IOException {
s.defaultWriteObject();
if (getUIClassID().equals(uiClassID)) {
byte count = JComponent.getWriteObjCounter(this);
JComponent.setWriteObjCounter(this, --count);
if (count == 0 && ui != null) {
ui.installUI(this);
}
}
}
Returns a String
representation of this JList
. This method is intended to be used only for debugging purposes, and the content and format of the returned String
may vary between implementations. The returned String
may be empty, but may not be null
. Returns: a String
representation of this JList
.
/**
* Returns a {@code String} representation of this {@code JList}.
* This method is intended to be used only for debugging purposes,
* and the content and format of the returned {@code String} may vary
* between implementations. The returned {@code String} may be empty,
* but may not be {@code null}.
*
* @return a {@code String} representation of this {@code JList}.
*/
protected String paramString() {
String selectionForegroundString = (selectionForeground != null ?
selectionForeground.toString() :
"");
String selectionBackgroundString = (selectionBackground != null ?
selectionBackground.toString() :
"");
return super.paramString() +
",fixedCellHeight=" + fixedCellHeight +
",fixedCellWidth=" + fixedCellWidth +
",horizontalScrollIncrement=" + horizontalScrollIncrement +
",selectionBackground=" + selectionBackgroundString +
",selectionForeground=" + selectionForegroundString +
",visibleRowCount=" + visibleRowCount +
",layoutOrientation=" + layoutOrientation;
}
/**
* --- Accessibility Support ---
*/
Gets the AccessibleContext
associated with this JList
. For JList
, the AccessibleContext
takes the form of an AccessibleJList
. A new AccessibleJList
instance is created if necessary.
Returns: an AccessibleJList
that serves as the AccessibleContext
of this JList
/**
* Gets the {@code AccessibleContext} associated with this {@code JList}.
* For {@code JList}, the {@code AccessibleContext} takes the form of an
* {@code AccessibleJList}.
* <p>
* A new {@code AccessibleJList} instance is created if necessary.
*
* @return an {@code AccessibleJList} that serves as the
* {@code AccessibleContext} of this {@code JList}
*/
@BeanProperty(bound = false)
public AccessibleContext getAccessibleContext() {
if (accessibleContext == null) {
accessibleContext = new AccessibleJList();
}
return accessibleContext;
}
This class implements accessibility support for the JList
class. It provides an implementation of the Java Accessibility API appropriate to list user-interface elements.
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
.
/**
* This class implements accessibility support for the
* {@code JList} class. It provides an implementation of the
* Java Accessibility API appropriate to list user-interface
* elements.
* <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™
* has been added to the <code>java.beans</code> package.
* Please see {@link java.beans.XMLEncoder}.
*/
@SuppressWarnings("serial") // Same-version serialization only
protected class AccessibleJList extends AccessibleJComponent
implements AccessibleSelection, PropertyChangeListener,
ListSelectionListener, ListDataListener {
int leadSelectionIndex;
Constructs an AccessibleJList
. /**
* Constructs an {@code AccessibleJList}.
*/
public AccessibleJList() {
super();
JList.this.addPropertyChangeListener(this);
JList.this.getSelectionModel().addListSelectionListener(this);
JList.this.getModel().addListDataListener(this);
leadSelectionIndex = JList.this.getLeadSelectionIndex();
}
Property Change Listener change method. Used to track changes
to the DataModel and ListSelectionModel, in order to re-set
listeners to those for reporting changes there via the Accessibility
PropertyChange mechanism.
Params: - e – PropertyChangeEvent
/**
* Property Change Listener change method. Used to track changes
* to the DataModel and ListSelectionModel, in order to re-set
* listeners to those for reporting changes there via the Accessibility
* PropertyChange mechanism.
*
* @param e PropertyChangeEvent
*/
public void propertyChange(PropertyChangeEvent e) {
String name = e.getPropertyName();
Object oldValue = e.getOldValue();
Object newValue = e.getNewValue();
// re-set listData listeners
if (name.compareTo("model") == 0) {
if (oldValue != null && oldValue instanceof ListModel) {
((ListModel) oldValue).removeListDataListener(this);
}
if (newValue != null && newValue instanceof ListModel) {
((ListModel) newValue).addListDataListener(this);
}
// re-set listSelectionModel listeners
} else if (name.compareTo("selectionModel") == 0) {
if (oldValue != null && oldValue instanceof ListSelectionModel) {
((ListSelectionModel) oldValue).removeListSelectionListener(this);
}
if (newValue != null && newValue instanceof ListSelectionModel) {
((ListSelectionModel) newValue).addListSelectionListener(this);
}
firePropertyChange(
AccessibleContext.ACCESSIBLE_SELECTION_PROPERTY,
Boolean.valueOf(false), Boolean.valueOf(true));
}
}
List Selection Listener value change method. Used to fire
the property change
Params: - e – ListSelectionEvent
/**
* List Selection Listener value change method. Used to fire
* the property change
*
* @param e ListSelectionEvent
*
*/
public void valueChanged(ListSelectionEvent e) {
int oldLeadSelectionIndex = leadSelectionIndex;
leadSelectionIndex = JList.this.getLeadSelectionIndex();
if (oldLeadSelectionIndex != leadSelectionIndex) {
Accessible oldLS, newLS;
oldLS = (oldLeadSelectionIndex >= 0)
? getAccessibleChild(oldLeadSelectionIndex)
: null;
newLS = (leadSelectionIndex >= 0)
? getAccessibleChild(leadSelectionIndex)
: null;
firePropertyChange(AccessibleContext.ACCESSIBLE_ACTIVE_DESCENDANT_PROPERTY,
oldLS, newLS);
}
firePropertyChange(AccessibleContext.ACCESSIBLE_VISIBLE_DATA_PROPERTY,
Boolean.valueOf(false), Boolean.valueOf(true));
firePropertyChange(AccessibleContext.ACCESSIBLE_SELECTION_PROPERTY,
Boolean.valueOf(false), Boolean.valueOf(true));
// Process the State changes for Multiselectable
AccessibleStateSet s = getAccessibleStateSet();
ListSelectionModel lsm = JList.this.getSelectionModel();
if (lsm.getSelectionMode() != ListSelectionModel.SINGLE_SELECTION) {
if (!s.contains(AccessibleState.MULTISELECTABLE)) {
s.add(AccessibleState.MULTISELECTABLE);
firePropertyChange(AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
null, AccessibleState.MULTISELECTABLE);
}
} else {
if (s.contains(AccessibleState.MULTISELECTABLE)) {
s.remove(AccessibleState.MULTISELECTABLE);
firePropertyChange(AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
AccessibleState.MULTISELECTABLE, null);
}
}
}
List Data Listener interval added method. Used to fire the visible data property change
Params: - e – ListDataEvent
/**
* List Data Listener interval added method. Used to fire the visible data property change
*
* @param e ListDataEvent
*
*/
public void intervalAdded(ListDataEvent e) {
firePropertyChange(AccessibleContext.ACCESSIBLE_VISIBLE_DATA_PROPERTY,
Boolean.valueOf(false), Boolean.valueOf(true));
}
List Data Listener interval removed method. Used to fire the visible data property change
Params: - e – ListDataEvent
/**
* List Data Listener interval removed method. Used to fire the visible data property change
*
* @param e ListDataEvent
*
*/
public void intervalRemoved(ListDataEvent e) {
firePropertyChange(AccessibleContext.ACCESSIBLE_VISIBLE_DATA_PROPERTY,
Boolean.valueOf(false), Boolean.valueOf(true));
}
List Data Listener contents changed method. Used to fire the visible data property change
Params: - e – ListDataEvent
/**
* List Data Listener contents changed method. Used to fire the visible data property change
*
* @param e ListDataEvent
*
*/
public void contentsChanged(ListDataEvent e) {
firePropertyChange(AccessibleContext.ACCESSIBLE_VISIBLE_DATA_PROPERTY,
Boolean.valueOf(false), Boolean.valueOf(true));
}
// AccessibleContext methods
Get the state set of this object.
See Also: Returns: an instance of AccessibleState containing the current state
of the object
/**
* Get the state set of this object.
*
* @return an instance of AccessibleState containing the current state
* of the object
* @see AccessibleState
*/
public AccessibleStateSet getAccessibleStateSet() {
AccessibleStateSet states = super.getAccessibleStateSet();
if (selectionModel.getSelectionMode() !=
ListSelectionModel.SINGLE_SELECTION) {
states.add(AccessibleState.MULTISELECTABLE);
}
return states;
}
Get the role of this object.
See Also: Returns: an instance of AccessibleRole describing the role of the
object
/**
* Get the role of this object.
*
* @return an instance of AccessibleRole describing the role of the
* object
* @see AccessibleRole
*/
public AccessibleRole getAccessibleRole() {
return AccessibleRole.LIST;
}
Returns the Accessible
child contained at
the local coordinate Point
, if one exists.
Otherwise returns null
.
Returns: the Accessible
at the specified
location, if it exists
/**
* Returns the <code>Accessible</code> child contained at
* the local coordinate <code>Point</code>, if one exists.
* Otherwise returns <code>null</code>.
*
* @return the <code>Accessible</code> at the specified
* location, if it exists
*/
public Accessible getAccessibleAt(Point p) {
int i = locationToIndex(p);
if (i >= 0) {
return new AccessibleJListChild(JList.this, i);
} else {
return null;
}
}
Returns the number of accessible children in the object. If all
of the children of this object implement Accessible, than this
method should return the number of children of this object.
Returns: the number of accessible children in the object.
/**
* Returns the number of accessible children in the object. If all
* of the children of this object implement Accessible, than this
* method should return the number of children of this object.
*
* @return the number of accessible children in the object.
*/
public int getAccessibleChildrenCount() {
return getModel().getSize();
}
Return the nth Accessible child of the object.
Params: - i – zero-based index of child
Returns: the nth Accessible child of the object
/**
* Return the nth Accessible child of the object.
*
* @param i zero-based index of child
* @return the nth Accessible child of the object
*/
public Accessible getAccessibleChild(int i) {
if (i >= getModel().getSize()) {
return null;
} else {
return new AccessibleJListChild(JList.this, i);
}
}
Get the AccessibleSelection associated with this object. In the
implementation of the Java Accessibility API for this class,
return this object, which is responsible for implementing the
AccessibleSelection interface on behalf of itself.
Returns: this object
/**
* Get the AccessibleSelection associated with this object. In the
* implementation of the Java Accessibility API for this class,
* return this object, which is responsible for implementing the
* AccessibleSelection interface on behalf of itself.
*
* @return this object
*/
public AccessibleSelection getAccessibleSelection() {
return this;
}
// AccessibleSelection methods
Returns the number of items currently selected.
If no items are selected, the return value will be 0.
Returns: the number of items currently selected.
/**
* Returns the number of items currently selected.
* If no items are selected, the return value will be 0.
*
* @return the number of items currently selected.
*/
public int getAccessibleSelectionCount() {
return JList.this.getSelectedIndices().length;
}
Returns an Accessible representing the specified selected item
in the object. If there isn't a selection, or there are
fewer items selected than the integer passed in, the return
value will be null
.
Params: - i – the zero-based index of selected items
Returns: an Accessible containing the selected item
/**
* Returns an Accessible representing the specified selected item
* in the object. If there isn't a selection, or there are
* fewer items selected than the integer passed in, the return
* value will be <code>null</code>.
*
* @param i the zero-based index of selected items
* @return an Accessible containing the selected item
*/
public Accessible getAccessibleSelection(int i) {
int len = getAccessibleSelectionCount();
if (i < 0 || i >= len) {
return null;
} else {
return getAccessibleChild(JList.this.getSelectedIndices()[i]);
}
}
Returns true if the current child of this object is selected.
Params: - i – the zero-based index of the child in this Accessible
object.
See Also:
/**
* Returns true if the current child of this object is selected.
*
* @param i the zero-based index of the child in this Accessible
* object.
* @see AccessibleContext#getAccessibleChild
*/
public boolean isAccessibleChildSelected(int i) {
return isSelectedIndex(i);
}
Adds the specified selected item in the object to the object's
selection. If the object supports multiple selections,
the specified item is added to any existing selection, otherwise
it replaces any existing selection in the object. If the
specified item is already selected, this method has no effect.
Params: - i – the zero-based index of selectable items
/**
* Adds the specified selected item in the object to the object's
* selection. If the object supports multiple selections,
* the specified item is added to any existing selection, otherwise
* it replaces any existing selection in the object. If the
* specified item is already selected, this method has no effect.
*
* @param i the zero-based index of selectable items
*/
public void addAccessibleSelection(int i) {
JList.this.addSelectionInterval(i, i);
}
Removes the specified selected item in the object from the object's
selection. If the specified item isn't currently selected, this
method has no effect.
Params: - i – the zero-based index of selectable items
/**
* Removes the specified selected item in the object from the object's
* selection. If the specified item isn't currently selected, this
* method has no effect.
*
* @param i the zero-based index of selectable items
*/
public void removeAccessibleSelection(int i) {
JList.this.removeSelectionInterval(i, i);
}
Clears the selection in the object, so that nothing in the
object is selected.
/**
* Clears the selection in the object, so that nothing in the
* object is selected.
*/
public void clearAccessibleSelection() {
JList.this.clearSelection();
}
Causes every selected item in the object to be selected
if the object supports multiple selections.
/**
* Causes every selected item in the object to be selected
* if the object supports multiple selections.
*/
public void selectAllAccessibleSelection() {
JList.this.addSelectionInterval(0, getAccessibleChildrenCount() -1);
}
This class implements accessibility support appropriate
for list children.
/**
* This class implements accessibility support appropriate
* for list children.
*/
protected class AccessibleJListChild extends AccessibleContext
implements Accessible, AccessibleComponent, AccessibleAction {
private JList<E> parent = null;
int indexInParent;
private Component component = null;
private AccessibleContext accessibleContext = null;
private ListModel<E> listModel;
private ListCellRenderer<? super E> cellRenderer = null;
Constructs an AccessibleJListChild
. Params: - parent – the parent
- indexInParent – the index in the parent
/**
* Constructs an {@code AccessibleJListChild}.
* @param parent the parent
* @param indexInParent the index in the parent
*/
public AccessibleJListChild(JList<E> parent, int indexInParent) {
this.parent = parent;
this.setAccessibleParent(parent);
this.indexInParent = indexInParent;
if (parent != null) {
listModel = parent.getModel();
cellRenderer = parent.getCellRenderer();
}
}
private Component getCurrentComponent() {
return getComponentAtIndex(indexInParent);
}
AccessibleContext getCurrentAccessibleContext() {
Component c = getComponentAtIndex(indexInParent);
if (c instanceof Accessible) {
return c.getAccessibleContext();
} else {
return null;
}
}
private Component getComponentAtIndex(int index) {
if (index < 0 || index >= listModel.getSize()) {
return null;
}
if ((parent != null)
&& (listModel != null)
&& cellRenderer != null) {
E value = listModel.getElementAt(index);
boolean isSelected = parent.isSelectedIndex(index);
boolean isFocussed = parent.isFocusOwner()
&& (index == parent.getLeadSelectionIndex());
return cellRenderer.getListCellRendererComponent(
parent,
value,
index,
isSelected,
isFocussed);
} else {
return null;
}
}
// Accessible Methods
Get the AccessibleContext for this object. In the
implementation of the Java Accessibility API for this class,
returns this object, which is its own AccessibleContext.
Returns: this object
/**
* Get the AccessibleContext for this object. In the
* implementation of the Java Accessibility API for this class,
* returns this object, which is its own AccessibleContext.
*
* @return this object
*/
public AccessibleContext getAccessibleContext() {
return this;
}
// AccessibleContext methods
public String getAccessibleName() {
AccessibleContext ac = getCurrentAccessibleContext();
if (ac != null) {
return ac.getAccessibleName();
} else {
return null;
}
}
public void setAccessibleName(String s) {
AccessibleContext ac = getCurrentAccessibleContext();
if (ac != null) {
ac.setAccessibleName(s);
}
}
public String getAccessibleDescription() {
AccessibleContext ac = getCurrentAccessibleContext();
if (ac != null) {
return ac.getAccessibleDescription();
} else {
return null;
}
}
public void setAccessibleDescription(String s) {
AccessibleContext ac = getCurrentAccessibleContext();
if (ac != null) {
ac.setAccessibleDescription(s);
}
}
public AccessibleRole getAccessibleRole() {
AccessibleContext ac = getCurrentAccessibleContext();
if (ac != null) {
return ac.getAccessibleRole();
} else {
return null;
}
}
public AccessibleStateSet getAccessibleStateSet() {
AccessibleContext ac = getCurrentAccessibleContext();
AccessibleStateSet s;
if (ac != null) {
s = ac.getAccessibleStateSet();
} else {
s = new AccessibleStateSet();
}
s.add(AccessibleState.SELECTABLE);
if (parent.isFocusOwner()
&& (indexInParent == parent.getLeadSelectionIndex())) {
s.add(AccessibleState.ACTIVE);
}
if (parent.isSelectedIndex(indexInParent)) {
s.add(AccessibleState.SELECTED);
}
if (this.isShowing()) {
s.add(AccessibleState.SHOWING);
} else if (s.contains(AccessibleState.SHOWING)) {
s.remove(AccessibleState.SHOWING);
}
if (this.isVisible()) {
s.add(AccessibleState.VISIBLE);
} else if (s.contains(AccessibleState.VISIBLE)) {
s.remove(AccessibleState.VISIBLE);
}
s.add(AccessibleState.TRANSIENT); // cell-rendered
return s;
}
public int getAccessibleIndexInParent() {
return indexInParent;
}
public int getAccessibleChildrenCount() {
AccessibleContext ac = getCurrentAccessibleContext();
if (ac != null) {
return ac.getAccessibleChildrenCount();
} else {
return 0;
}
}
public Accessible getAccessibleChild(int i) {
AccessibleContext ac = getCurrentAccessibleContext();
if (ac != null) {
Accessible accessibleChild = ac.getAccessibleChild(i);
ac.setAccessibleParent(this);
return accessibleChild;
} else {
return null;
}
}
public Locale getLocale() {
AccessibleContext ac = getCurrentAccessibleContext();
if (ac != null) {
return ac.getLocale();
} else {
return null;
}
}
public void addPropertyChangeListener(PropertyChangeListener l) {
AccessibleContext ac = getCurrentAccessibleContext();
if (ac != null) {
ac.addPropertyChangeListener(l);
}
}
public void removePropertyChangeListener(PropertyChangeListener l) {
AccessibleContext ac = getCurrentAccessibleContext();
if (ac != null) {
ac.removePropertyChangeListener(l);
}
}
Get the AccessibleComponent associated with this object. In the
implementation of the Java Accessibility API for this class,
return this object, which is responsible for implementing the
AccessibleComponent interface on behalf of itself.
Returns: this object
/**
* Get the AccessibleComponent associated with this object. In the
* implementation of the Java Accessibility API for this class,
* return this object, which is responsible for implementing the
* AccessibleComponent interface on behalf of itself.
*
* @return this object
*/
public AccessibleComponent getAccessibleComponent() {
return this; // to override getBounds()
}
public AccessibleSelection getAccessibleSelection() {
AccessibleContext ac = getCurrentAccessibleContext();
return ac != null ? ac.getAccessibleSelection() : null;
}
public AccessibleText getAccessibleText() {
AccessibleContext ac = getCurrentAccessibleContext();
return ac != null ? ac.getAccessibleText() : null;
}
public AccessibleValue getAccessibleValue() {
AccessibleContext ac = getCurrentAccessibleContext();
return ac != null ? ac.getAccessibleValue() : null;
}
// AccessibleComponent methods
public Color getBackground() {
AccessibleContext ac = getCurrentAccessibleContext();
if (ac instanceof AccessibleComponent) {
return ((AccessibleComponent) ac).getBackground();
} else {
Component c = getCurrentComponent();
if (c != null) {
return c.getBackground();
} else {
return null;
}
}
}
public void setBackground(Color c) {
AccessibleContext ac = getCurrentAccessibleContext();
if (ac instanceof AccessibleComponent) {
((AccessibleComponent) ac).setBackground(c);
} else {
Component cp = getCurrentComponent();
if (cp != null) {
cp.setBackground(c);
}
}
}
public Color getForeground() {
AccessibleContext ac = getCurrentAccessibleContext();
if (ac instanceof AccessibleComponent) {
return ((AccessibleComponent) ac).getForeground();
} else {
Component c = getCurrentComponent();
if (c != null) {
return c.getForeground();
} else {
return null;
}
}
}
public void setForeground(Color c) {
AccessibleContext ac = getCurrentAccessibleContext();
if (ac instanceof AccessibleComponent) {
((AccessibleComponent) ac).setForeground(c);
} else {
Component cp = getCurrentComponent();
if (cp != null) {
cp.setForeground(c);
}
}
}
public Cursor getCursor() {
AccessibleContext ac = getCurrentAccessibleContext();
if (ac instanceof AccessibleComponent) {
return ((AccessibleComponent) ac).getCursor();
} else {
Component c = getCurrentComponent();
if (c != null) {
return c.getCursor();
} else {
Accessible ap = getAccessibleParent();
if (ap instanceof AccessibleComponent) {
return ((AccessibleComponent) ap).getCursor();
} else {
return null;
}
}
}
}
public void setCursor(Cursor c) {
AccessibleContext ac = getCurrentAccessibleContext();
if (ac instanceof AccessibleComponent) {
((AccessibleComponent) ac).setCursor(c);
} else {
Component cp = getCurrentComponent();
if (cp != null) {
cp.setCursor(c);
}
}
}
public Font getFont() {
AccessibleContext ac = getCurrentAccessibleContext();
if (ac instanceof AccessibleComponent) {
return ((AccessibleComponent) ac).getFont();
} else {
Component c = getCurrentComponent();
if (c != null) {
return c.getFont();
} else {
return null;
}
}
}
public void setFont(Font f) {
AccessibleContext ac = getCurrentAccessibleContext();
if (ac instanceof AccessibleComponent) {
((AccessibleComponent) ac).setFont(f);
} else {
Component c = getCurrentComponent();
if (c != null) {
c.setFont(f);
}
}
}
public FontMetrics getFontMetrics(Font f) {
AccessibleContext ac = getCurrentAccessibleContext();
if (ac instanceof AccessibleComponent) {
return ((AccessibleComponent) ac).getFontMetrics(f);
} else {
Component c = getCurrentComponent();
if (c != null) {
return c.getFontMetrics(f);
} else {
return null;
}
}
}
public boolean isEnabled() {
AccessibleContext ac = getCurrentAccessibleContext();
if (ac instanceof AccessibleComponent) {
return ((AccessibleComponent) ac).isEnabled();
} else {
Component c = getCurrentComponent();
if (c != null) {
return c.isEnabled();
} else {
return false;
}
}
}
public void setEnabled(boolean b) {
AccessibleContext ac = getCurrentAccessibleContext();
if (ac instanceof AccessibleComponent) {
((AccessibleComponent) ac).setEnabled(b);
} else {
Component c = getCurrentComponent();
if (c != null) {
c.setEnabled(b);
}
}
}
public boolean isVisible() {
int fi = parent.getFirstVisibleIndex();
int li = parent.getLastVisibleIndex();
// The UI incorrectly returns a -1 for the last
// visible index if the list is smaller than the
// viewport size.
if (li == -1) {
li = parent.getModel().getSize() - 1;
}
return ((indexInParent >= fi)
&& (indexInParent <= li));
}
public void setVisible(boolean b) {
}
public boolean isShowing() {
return (parent.isShowing() && isVisible());
}
public boolean contains(Point p) {
AccessibleContext ac = getCurrentAccessibleContext();
if (ac instanceof AccessibleComponent) {
Rectangle r = ((AccessibleComponent) ac).getBounds();
return r.contains(p);
} else {
Component c = getCurrentComponent();
if (c != null) {
Rectangle r = c.getBounds();
return r.contains(p);
} else {
return getBounds().contains(p);
}
}
}
public Point getLocationOnScreen() {
if (parent != null) {
Point listLocation;
try {
listLocation = parent.getLocationOnScreen();
} catch (IllegalComponentStateException e) {
// This can happen if the component isn't visisble
return null;
}
Point componentLocation = parent.indexToLocation(indexInParent);
if (componentLocation != null) {
componentLocation.translate(listLocation.x, listLocation.y);
return componentLocation;
} else {
return null;
}
} else {
return null;
}
}
public Point getLocation() {
if (parent != null) {
return parent.indexToLocation(indexInParent);
} else {
return null;
}
}
public void setLocation(Point p) {
if ((parent != null) && (parent.contains(p))) {
ensureIndexIsVisible(indexInParent);
}
}
public Rectangle getBounds() {
if (parent != null) {
return parent.getCellBounds(indexInParent,indexInParent);
} else {
return null;
}
}
public void setBounds(Rectangle r) {
AccessibleContext ac = getCurrentAccessibleContext();
if (ac instanceof AccessibleComponent) {
((AccessibleComponent) ac).setBounds(r);
}
}
public Dimension getSize() {
Rectangle cellBounds = this.getBounds();
if (cellBounds != null) {
return cellBounds.getSize();
} else {
return null;
}
}
public void setSize (Dimension d) {
AccessibleContext ac = getCurrentAccessibleContext();
if (ac instanceof AccessibleComponent) {
((AccessibleComponent) ac).setSize(d);
} else {
Component c = getCurrentComponent();
if (c != null) {
c.setSize(d);
}
}
}
public Accessible getAccessibleAt(Point p) {
AccessibleContext ac = getCurrentAccessibleContext();
if (ac instanceof AccessibleComponent) {
return ((AccessibleComponent) ac).getAccessibleAt(p);
} else {
return null;
}
}
@SuppressWarnings("deprecation")
public boolean isFocusTraversable() {
AccessibleContext ac = getCurrentAccessibleContext();
if (ac instanceof AccessibleComponent) {
return ((AccessibleComponent) ac).isFocusTraversable();
} else {
Component c = getCurrentComponent();
if (c != null) {
return c.isFocusTraversable();
} else {
return false;
}
}
}
public void requestFocus() {
AccessibleContext ac = getCurrentAccessibleContext();
if (ac instanceof AccessibleComponent) {
((AccessibleComponent) ac).requestFocus();
} else {
Component c = getCurrentComponent();
if (c != null) {
c.requestFocus();
}
}
}
public void addFocusListener(FocusListener l) {
AccessibleContext ac = getCurrentAccessibleContext();
if (ac instanceof AccessibleComponent) {
((AccessibleComponent) ac).addFocusListener(l);
} else {
Component c = getCurrentComponent();
if (c != null) {
c.addFocusListener(l);
}
}
}
public void removeFocusListener(FocusListener l) {
AccessibleContext ac = getCurrentAccessibleContext();
if (ac instanceof AccessibleComponent) {
((AccessibleComponent) ac).removeFocusListener(l);
} else {
Component c = getCurrentComponent();
if (c != null) {
c.removeFocusListener(l);
}
}
}
// TIGER - 4733624
Returns the icon for the element renderer, as the only item
of an array of AccessibleIcon
s or a null
array
if the renderer component contains no icons.
Returns: an array containing the accessible icon
or a null
array if none Since: 1.3
/**
* Returns the icon for the element renderer, as the only item
* of an array of <code>AccessibleIcon</code>s or a <code>null</code> array
* if the renderer component contains no icons.
*
* @return an array containing the accessible icon
* or a <code>null</code> array if none
* @since 1.3
*/
public AccessibleIcon [] getAccessibleIcon() {
AccessibleContext ac = getCurrentAccessibleContext();
if (ac != null) {
return ac.getAccessibleIcon();
} else {
return null;
}
}
{@inheritDoc}
Implementation Requirements: Returns the AccessibleAction for this AccessibleJListChild
as follows: First getListCellRendererComponent of the ListCellRenderer
for the component at the "index in parent" of this child is called.
Then its AccessibleContext is fetched and that AccessibleContext's
AccessibleAction is returned. Note that if an AccessibleAction
is not found using this process then this object with its implementation
of the AccessibleAction interface is returned. Since: 9
/**
* {@inheritDoc}
* @implSpec Returns the AccessibleAction for this AccessibleJListChild
* as follows: First getListCellRendererComponent of the ListCellRenderer
* for the component at the "index in parent" of this child is called.
* Then its AccessibleContext is fetched and that AccessibleContext's
* AccessibleAction is returned. Note that if an AccessibleAction
* is not found using this process then this object with its implementation
* of the AccessibleAction interface is returned.
* @since 9
*/
@Override
public AccessibleAction getAccessibleAction() {
AccessibleContext ac = getCurrentAccessibleContext();
if (ac == null) {
return null;
} else {
AccessibleAction aa = ac.getAccessibleAction();
if (aa != null) {
return aa;
} else {
return this;
}
}
}
{@inheritDoc}
Implementation Requirements: If i == 0 selects this AccessibleJListChild by calling
JList.this.setSelectedIndex(indexInParent) and then returns true;
otherwise returns false. Since: 9
/**
* {@inheritDoc}
* @implSpec If i == 0 selects this AccessibleJListChild by calling
* JList.this.setSelectedIndex(indexInParent) and then returns true;
* otherwise returns false.
* @since 9
*/
@Override
public boolean doAccessibleAction(int i) {
if (i == 0) {
JList.this.setSelectedIndex(indexInParent);
return true;
} else {
return false;
}
}
{@inheritDoc}
Implementation Requirements: If i == 0 returns the action description fetched from
UIManager.getString("AbstractButton.clickText");
otherwise returns null. Since: 9
/**
* {@inheritDoc}
* @implSpec If i == 0 returns the action description fetched from
* UIManager.getString("AbstractButton.clickText");
* otherwise returns null.
* @since 9
*/
@Override
public String getAccessibleActionDescription(int i) {
if (i == 0) {
return UIManager.getString("AbstractButton.clickText");
} else {
return null;
}
}
{@inheritDoc}
Implementation Requirements: Returns 1, i.e. there is only one action. Since: 9
/**
* {@inheritDoc}
* @implSpec Returns 1, i.e. there is only one action.
* @since 9
*/
@Override
public int getAccessibleActionCount() {
return 1;
}
} // inner class AccessibleJListChild
} // inner class AccessibleJList
}