6823603: Generics: JList
Reviewed-by: peterz, alexp
Contributed-by: fbrunnerlist@gmx.ch
--- a/jdk/src/share/classes/javax/swing/AbstractListModel.java Wed Nov 18 17:36:46 2009 +0300
+++ b/jdk/src/share/classes/javax/swing/AbstractListModel.java Mon Nov 23 20:57:17 2009 +0300
@@ -42,9 +42,11 @@
* has been added to the <code>java.beans</code> package.
* Please see {@link java.beans.XMLEncoder}.
*
+ * @param <E> the type of the elements of this model
+ *
* @author Hans Muller
*/
-public abstract class AbstractListModel implements ListModel, Serializable
+public abstract class AbstractListModel<E> implements ListModel<E>, Serializable
{
protected EventListenerList listenerList = new EventListenerList();
--- a/jdk/src/share/classes/javax/swing/DefaultListCellRenderer.java Wed Nov 18 17:36:46 2009 +0300
+++ b/jdk/src/share/classes/javax/swing/DefaultListCellRenderer.java Mon Nov 23 20:57:17 2009 +0300
@@ -71,7 +71,7 @@
* @author Hans Muller
*/
public class DefaultListCellRenderer extends JLabel
- implements ListCellRenderer, Serializable
+ implements ListCellRenderer<Object>, Serializable
{
/**
@@ -111,7 +111,7 @@
}
public Component getListCellRendererComponent(
- JList list,
+ JList<?> list,
Object value,
int index,
boolean isSelected,
--- a/jdk/src/share/classes/javax/swing/DefaultListModel.java Wed Nov 18 17:36:46 2009 +0300
+++ b/jdk/src/share/classes/javax/swing/DefaultListModel.java Mon Nov 23 20:57:17 2009 +0300
@@ -48,11 +48,13 @@
* has been added to the <code>java.beans</code> package.
* Please see {@link java.beans.XMLEncoder}.
*
+ * @param <E> the type of the elements of this model
+ *
* @author Hans Muller
*/
-public class DefaultListModel extends AbstractListModel
+public class DefaultListModel<E> extends AbstractListModel<E>
{
- private Vector delegate = new Vector();
+ private Vector<E> delegate = new Vector<E>();
/**
* Returns the number of components in this list.
@@ -83,7 +85,7 @@
* list
* @see #get(int)
*/
- public Object getElementAt(int index) {
+ public E getElementAt(int index) {
return delegate.elementAt(index);
}
@@ -175,7 +177,7 @@
* @return an enumeration of the components of this list
* @see Vector#elements()
*/
- public Enumeration<?> elements() {
+ public Enumeration<E> elements() {
return delegate.elements();
}
@@ -260,7 +262,7 @@
* @see #get(int)
* @see Vector#elementAt(int)
*/
- public Object elementAt(int index) {
+ public E elementAt(int index) {
return delegate.elementAt(index);
}
@@ -271,7 +273,7 @@
* @return the first component of this list
* @see Vector#firstElement()
*/
- public Object firstElement() {
+ public E firstElement() {
return delegate.firstElement();
}
@@ -283,13 +285,13 @@
* @return the last component of the list
* @see Vector#lastElement()
*/
- public Object lastElement() {
+ public E lastElement() {
return delegate.lastElement();
}
/**
* Sets the component at the specified <code>index</code> of this
- * list to be the specified object. The previous component at that
+ * list to be the specified element. The previous component at that
* position is discarded.
* <p>
* Throws an <code>ArrayIndexOutOfBoundsException</code> if the index
@@ -300,13 +302,13 @@
* <code>List</code> interface defined in the 1.2 Collections framework.
* </blockquote>
*
- * @param obj what the component is to be set to
+ * @param element what the component is to be set to
* @param index the specified index
* @see #set(int,Object)
* @see Vector#setElementAt(Object,int)
*/
- public void setElementAt(Object obj, int index) {
- delegate.setElementAt(obj, index);
+ public void setElementAt(E element, int index) {
+ delegate.setElementAt(element, index);
fireContentsChanged(this, index, index);
}
@@ -331,7 +333,7 @@
}
/**
- * Inserts the specified object as a component in this list at the
+ * Inserts the specified element as a component in this list at the
* specified <code>index</code>.
* <p>
* Throws an <code>ArrayIndexOutOfBoundsException</code> if the index
@@ -342,26 +344,26 @@
* <code>List</code> interface defined in the 1.2 Collections framework.
* </blockquote>
*
- * @param obj the component to insert
+ * @param element the component to insert
* @param index where to insert the new component
* @exception ArrayIndexOutOfBoundsException if the index was invalid
* @see #add(int,Object)
* @see Vector#insertElementAt(Object,int)
*/
- public void insertElementAt(Object obj, int index) {
- delegate.insertElementAt(obj, index);
+ public void insertElementAt(E element, int index) {
+ delegate.insertElementAt(element, index);
fireIntervalAdded(this, index, index);
}
/**
* Adds the specified component to the end of this list.
*
- * @param obj the component to be added
+ * @param element the component to be added
* @see Vector#addElement(Object)
*/
- public void addElement(Object obj) {
+ public void addElement(E element) {
int index = delegate.size();
- delegate.addElement(obj);
+ delegate.addElement(element);
fireIntervalAdded(this, index, index);
}
@@ -441,7 +443,7 @@
*
* @param index index of element to return
*/
- public Object get(int index) {
+ public E get(int index) {
return delegate.elementAt(index);
}
@@ -457,8 +459,8 @@
* @param element element to be stored at the specified position
* @return the element previously at the specified position
*/
- public Object set(int index, Object element) {
- Object rv = delegate.elementAt(index);
+ public E set(int index, E element) {
+ E rv = delegate.elementAt(index);
delegate.setElementAt(element, index);
fireContentsChanged(this, index, index);
return rv;
@@ -474,7 +476,7 @@
* @param index index at which the specified element is to be inserted
* @param element element to be inserted
*/
- public void add(int index, Object element) {
+ public void add(int index, E element) {
delegate.insertElementAt(element, index);
fireIntervalAdded(this, index, index);
}
@@ -488,9 +490,10 @@
* (<code>index < 0 || index >= size()</code>).
*
* @param index the index of the element to removed
+ * @return the element previously at the specified position
*/
- public Object remove(int index) {
- Object rv = delegate.elementAt(index);
+ public E remove(int index) {
+ E rv = delegate.elementAt(index);
delegate.removeElementAt(index);
fireIntervalRemoved(this, index, index);
return rv;
--- a/jdk/src/share/classes/javax/swing/JList.java Wed Nov 18 17:36:46 2009 +0300
+++ b/jdk/src/share/classes/javax/swing/JList.java Mon Nov 23 20:57:17 2009 +0300
@@ -25,11 +25,24 @@
package javax.swing;
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Cursor;
+import java.awt.Dimension;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.GraphicsEnvironment;
+import java.awt.HeadlessException;
+import java.awt.Insets;
+import java.awt.Point;
+import java.awt.Rectangle;
import java.awt.event.*;
-import java.awt.*;
import java.util.Vector;
import java.util.Locale;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
@@ -59,28 +72,30 @@
* 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 myList = new JList(data);
+ * 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 superClasses = new Vector();
- * Class rootClass = javax.swing.JList.class;
- * for(Class cls = rootClass; cls != null; cls = cls.getSuperclass()) {
+ * 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 myList = new JList(superClasses);
+ * JList<Class<?>> myList = new JList<Class<?>>(superClasses);
*
* // The automatically created model is stored in JList's "model"
* // property, which you can retrieve
*
- * ListModel model = myList.getModel();
+ * 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
@@ -103,12 +118,14 @@
* notifying listeners. For example, a read-only implementation of
* {@code AbstractListModel}:
* <pre>
+ * {@code
* // This list model has about 2^16 elements. Enjoy scrolling.
*
- * ListModel bigData = new AbstractListModel() {
+ * ListModel<String> bigData = new AbstractListModel<String>() {
* public int getSize() { return Short.MAX_VALUE; }
- * public Object getElementAt(int index) { return "Index " + index; }
+ * public String getElementAt(int index) { return "Index " + index; }
* };
+ * }
* </pre>
* <p>
* The selection state of a {@code JList} is managed by another separate
@@ -150,9 +167,10 @@
* 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 {
+ * class MyCellRenderer extends JLabel implements ListCellRenderer<Object> {
* final static ImageIcon longIcon = new ImageIcon("long.gif");
* final static ImageIcon shortIcon = new ImageIcon("short.gif");
*
@@ -160,7 +178,7 @@
* // We just reconfigure the JLabel each time we're called.
*
* public Component getListCellRendererComponent(
- * JList list, // the list
+ * JList<?> list, // the list
* Object value, // value to display
* int index, // cell index
* boolean isSelected, // is the cell selected
@@ -184,6 +202,7 @@
* }
*
* myList.setCellRenderer(new MyCellRenderer());
+ * }
* </pre>
* <p>
* Another job for the cell renderer is in helping to determine sizing
@@ -195,7 +214,8 @@
* automatically based on a single prototype value:
* <a name="prototype_example">
* <pre>
- * JList bigDataList = new JList(bigData);
+ * {@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
@@ -204,6 +224,7 @@
* // properties.
*
* bigDataList.setPrototypeCellValue("Index 1234567890");
+ * }
* </pre>
* <p>
* {@code JList} doesn't implement scrolling directly. To create a list that
@@ -260,13 +281,15 @@
* @see ListCellRenderer
* @see DefaultListCellRenderer
*
+ * @param <E> the type of the elements of this list
+ *
* @beaninfo
* attribute: isContainer false
* description: A component which allows for the selection of one or more objects from a list.
*
* @author Hans Muller
*/
-public class JList extends JComponent implements Scrollable, Accessible
+public class JList<E> extends JComponent implements Scrollable, Accessible
{
/**
* @see #getUIClassID
@@ -301,15 +324,15 @@
private int fixedCellWidth = -1;
private int fixedCellHeight = -1;
private int horizontalScrollIncrement = -1;
- private Object prototypeCellValue;
+ private E prototypeCellValue;
private int visibleRowCount = 8;
private Color selectionForeground;
private Color selectionBackground;
private boolean dragEnabled;
private ListSelectionModel selectionModel;
- private ListModel dataModel;
- private ListCellRenderer cellRenderer;
+ private ListModel<E> dataModel;
+ private ListCellRenderer<? super E> cellRenderer;
private ListSelectionListener selectionListener;
/**
@@ -402,7 +425,7 @@
* @param dataModel the model for the list
* @exception IllegalArgumentException if the model is {@code null}
*/
- public JList(ListModel dataModel)
+ public JList(ListModel<E> dataModel)
{
if (dataModel == null) {
throw new IllegalArgumentException("dataModel must be non null");
@@ -437,12 +460,12 @@
* @param listData the array of Objects to be loaded into the data model,
* {@code non-null}
*/
- public JList(final Object[] listData)
+ public JList(final E[] listData)
{
this (
- new AbstractListModel() {
+ new AbstractListModel<E>() {
public int getSize() { return listData.length; }
- public Object getElementAt(int i) { return listData[i]; }
+ public E getElementAt(int i) { return listData[i]; }
}
);
}
@@ -462,11 +485,11 @@
* @param listData the <code>Vector</code> to be loaded into the
* data model, {@code non-null}
*/
- public JList(final Vector<?> listData) {
+ public JList(final Vector<? extends E> listData) {
this (
- new AbstractListModel() {
+ new AbstractListModel<E>() {
public int getSize() { return listData.size(); }
- public Object getElementAt(int i) { return listData.elementAt(i); }
+ public E getElementAt(int i) { return listData.elementAt(i); }
}
);
}
@@ -477,9 +500,9 @@
*/
public JList() {
this (
- new AbstractListModel() {
+ new AbstractListModel<E>() {
public int getSize() { return 0; }
- public Object getElementAt(int i) { return "No Data Model"; }
+ public E getElementAt(int i) { throw new IndexOutOfBoundsException("No Data Model"); }
}
);
}
@@ -526,7 +549,7 @@
public void updateUI() {
setUI((ListUI)UIManager.getUI(this));
- ListCellRenderer renderer = getCellRenderer();
+ ListCellRenderer<? super E> renderer = getCellRenderer();
if (renderer instanceof Component) {
SwingUtilities.updateComponentTreeUI((Component)renderer);
}
@@ -560,8 +583,8 @@
*/
private void updateFixedCellSize()
{
- ListCellRenderer cr = getCellRenderer();
- Object value = getPrototypeCellValue();
+ ListCellRenderer<? super E> cr = getCellRenderer();
+ E value = getPrototypeCellValue();
if ((cr != null) && (value != null)) {
Component c = cr.getListCellRendererComponent(this, value, 0, false, false);
@@ -592,7 +615,7 @@
* @return the value of the {@code prototypeCellValue} property
* @see #setPrototypeCellValue
*/
- public Object getPrototypeCellValue() {
+ public E getPrototypeCellValue() {
return prototypeCellValue;
}
@@ -632,8 +655,8 @@
* attribute: visualUpdate true
* description: The cell prototype value, used to compute cell width and height.
*/
- public void setPrototypeCellValue(Object prototypeCellValue) {
- Object oldValue = this.prototypeCellValue;
+ public void setPrototypeCellValue(E prototypeCellValue) {
+ E oldValue = this.prototypeCellValue;
this.prototypeCellValue = prototypeCellValue;
/* If the prototypeCellValue has changed and is non-null,
@@ -727,7 +750,7 @@
* @see #setCellRenderer
*/
@Transient
- public ListCellRenderer getCellRenderer() {
+ public ListCellRenderer<? super E> getCellRenderer() {
return cellRenderer;
}
@@ -755,8 +778,8 @@
* attribute: visualUpdate true
* description: The component used to draw the cells.
*/
- public void setCellRenderer(ListCellRenderer cellRenderer) {
- ListCellRenderer oldValue = this.cellRenderer;
+ public void setCellRenderer(ListCellRenderer<? super E> cellRenderer) {
+ ListCellRenderer<? super E> oldValue = this.cellRenderer;
this.cellRenderer = cellRenderer;
/* If the cellRenderer has changed and prototypeCellValue
@@ -1455,7 +1478,7 @@
* @since 1.4
*/
public int getNextMatch(String prefix, int startIndex, Position.Bias bias) {
- ListModel model = getModel();
+ ListModel<E> model = getModel();
int max = model.getSize();
if (prefix == null) {
throw new IllegalArgumentException();
@@ -1469,16 +1492,16 @@
int increment = (bias == Position.Bias.Forward) ? 1 : -1;
int index = startIndex;
do {
- Object o = model.getElementAt(index);
-
- if (o != null) {
+ E element = model.getElementAt(index);
+
+ if (element != null) {
String string;
- if (o instanceof String) {
- string = ((String)o).toUpperCase();
+ if (element instanceof String) {
+ string = ((String)element).toUpperCase();
}
else {
- string = o.toString();
+ string = element.toString();
if (string != null) {
string = string.toUpperCase();
}
@@ -1516,7 +1539,7 @@
if(event != null) {
Point p = event.getPoint();
int index = locationToIndex(p);
- ListCellRenderer r = getCellRenderer();
+ ListCellRenderer<? super E> r = getCellRenderer();
Rectangle cellBounds;
if (index != -1 && r != null && (cellBounds =
@@ -1634,7 +1657,7 @@
* list of items
* @see #setModel
*/
- public ListModel getModel() {
+ public ListModel<E> getModel() {
return dataModel;
}
@@ -1656,11 +1679,11 @@
* attribute: visualUpdate true
* description: The object that contains the data to be drawn by this JList.
*/
- public void setModel(ListModel model) {
+ public void setModel(ListModel<E> model) {
if (model == null) {
throw new IllegalArgumentException("model must be non null");
}
- ListModel oldValue = dataModel;
+ ListModel<E> oldValue = dataModel;
dataModel = model;
firePropertyChange("model", oldValue, dataModel);
clearSelection();
@@ -1668,7 +1691,7 @@
/**
- * Constructs a read-only <code>ListModel</code> from an array of objects,
+ * 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
@@ -1676,15 +1699,15 @@
* references the given array directly. Attempts to modify the array
* after invoking this method results in undefined behavior.
*
- * @param listData an array of {@code Objects} containing the items to
+ * @param listData an array of {@code E} containing the items to
* display in the list
* @see #setModel
*/
- public void setListData(final Object[] listData) {
+ public void setListData(final E[] listData) {
setModel (
- new AbstractListModel() {
+ new AbstractListModel<E>() {
public int getSize() { return listData.length; }
- public Object getElementAt(int i) { return listData[i]; }
+ public E getElementAt(int i) { return listData[i]; }
}
);
}
@@ -1703,11 +1726,11 @@
* display in the list
* @see #setModel
*/
- public void setListData(final Vector<?> listData) {
+ public void setListData(final Vector<? extends E> listData) {
setModel (
- new AbstractListModel() {
+ new AbstractListModel<E>() {
public int getSize() { return listData.size(); }
- public Object getElementAt(int i) { return listData.elementAt(i); }
+ public E getElementAt(int i) { return listData.elementAt(i); }
}
);
}
@@ -2235,10 +2258,13 @@
* @see #isSelectedIndex
* @see #getModel
* @see #addListSelectionListener
+ *
+ * @deprecated As of JDK 1.7, replaced by {@link #getSelectedValuesList()}
*/
+ @Deprecated
public Object[] getSelectedValues() {
ListSelectionModel sm = getSelectionModel();
- ListModel dm = getModel();
+ ListModel<E> dm = getModel();
int iMin = sm.getMinSelectionIndex();
int iMax = sm.getMaxSelectionIndex();
@@ -2259,6 +2285,37 @@
return rv;
}
+ /**
+ * 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
+ */
+ public List<E> getSelectedValuesList() {
+ ListSelectionModel sm = getSelectionModel();
+ ListModel<E> dm = getModel();
+
+ int iMin = sm.getMinSelectionIndex();
+ int iMax = sm.getMaxSelectionIndex();
+
+ if ((iMin < 0) || (iMax < 0)) {
+ return Collections.emptyList();
+ }
+
+ List<E> selectedItems = new ArrayList<E>();
+ for(int i = iMin; i <= iMax; i++) {
+ if (sm.isSelectedIndex(i)) {
+ selectedItems.add(dm.getElementAt(i));
+ }
+ }
+ return selectedItems;
+ }
+
/**
* Returns the smallest selected cell index; <i>the selection</i> when only
@@ -2291,7 +2348,7 @@
* @see #getModel
* @see #addListSelectionListener
*/
- public Object getSelectedValue() {
+ public E getSelectedValue() {
int i = getMinSelectionIndex();
return (i == -1) ? null : getModel().getElementAt(i);
}
@@ -2309,7 +2366,7 @@
setSelectedIndex(-1);
else if(!anObject.equals(getSelectedValue())) {
int i,c;
- ListModel dm = getModel();
+ ListModel<E> dm = getModel();
for(i=0,c=dm.getSize();i<c;i++)
if(anObject.equals(dm.getElementAt(i))){
setSelectedIndex(i);
@@ -3138,14 +3195,14 @@
*/
protected class AccessibleJListChild extends AccessibleContext
implements Accessible, AccessibleComponent {
- private JList parent = null;
+ private JList<E> parent = null;
private int indexInParent;
private Component component = null;
private AccessibleContext accessibleContext = null;
- private ListModel listModel;
- private ListCellRenderer cellRenderer = null;
-
- public AccessibleJListChild(JList parent, int indexInParent) {
+ private ListModel<E> listModel;
+ private ListCellRenderer<? super E> cellRenderer = null;
+
+ public AccessibleJListChild(JList<E> parent, int indexInParent) {
this.parent = parent;
this.setAccessibleParent(parent);
this.indexInParent = indexInParent;
@@ -3175,7 +3232,7 @@
if ((parent != null)
&& (listModel != null)
&& cellRenderer != null) {
- Object value = listModel.getElementAt(index);
+ E value = listModel.getElementAt(index);
boolean isSelected = parent.isSelectedIndex(index);
boolean isFocussed = parent.isFocusOwner()
&& (index == parent.getLeadSelectionIndex());
--- a/jdk/src/share/classes/javax/swing/ListCellRenderer.java Wed Nov 18 17:36:46 2009 +0300
+++ b/jdk/src/share/classes/javax/swing/ListCellRenderer.java Mon Nov 23 20:57:17 2009 +0300
@@ -33,12 +33,13 @@
* the cells in a JList. For example, to use a JLabel as a
* ListCellRenderer, you would write something like this:
* <pre>
- * class MyCellRenderer extends JLabel implements ListCellRenderer {
+ * {@code
+ * class MyCellRenderer extends JLabel implements ListCellRenderer<Object> {
* public MyCellRenderer() {
* setOpaque(true);
* }
*
- * public Component getListCellRendererComponent(JList list,
+ * public Component getListCellRendererComponent(JList<?> list,
* Object value,
* int index,
* boolean isSelected,
@@ -75,14 +76,17 @@
* return this;
* }
* }
+ * }
* </pre>
*
+ * @param <E> the type of values this renderer can be used for
+ *
* @see JList
* @see DefaultListCellRenderer
*
* @author Hans Muller
*/
-public interface ListCellRenderer
+public interface ListCellRenderer<E>
{
/**
* Return a component that has been configured to display the specified
@@ -104,8 +108,8 @@
* @see ListModel
*/
Component getListCellRendererComponent(
- JList list,
- Object value,
+ JList<? extends E> list,
+ E value,
int index,
boolean isSelected,
boolean cellHasFocus);
--- a/jdk/src/share/classes/javax/swing/ListModel.java Wed Nov 18 17:36:46 2009 +0300
+++ b/jdk/src/share/classes/javax/swing/ListModel.java Mon Nov 23 20:57:17 2009 +0300
@@ -35,10 +35,12 @@
* length of the data model must be reported to all of the
* ListDataListeners.
*
+ * @param <E> the type of the elements of this model
+ *
* @author Hans Muller
* @see JList
*/
-public interface ListModel
+public interface ListModel<E>
{
/**
* Returns the length of the list.
@@ -51,7 +53,7 @@
* @param index the requested index
* @return the value at <code>index</code>
*/
- Object getElementAt(int index);
+ E getElementAt(int index);
/**
* Adds a listener to the list that's notified each time a change
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/JList/6823603/bug6823603.java Mon Nov 23 20:57:17 2009 +0300
@@ -0,0 +1,247 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc. 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.
+ *
+ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+ @bug 6823603
+ @summary Generics: JList
+ @author Florian Brunner
+ @run main bug6823603
+ */
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Vector;
+import java.util.Enumeration;
+import java.awt.*;
+import javax.swing.*;
+
+public class bug6823603 {
+
+ private static final String TEST_ELEMENT = "Test1";
+
+ /**
+ * @param args the command line arguments
+ */
+ @SuppressWarnings("unchecked")
+ public static void main(String[] args) {
+ testRawSignatures();
+ testGenericSignatures();
+
+ testGetSelectedValuesList(); // new method
+ }
+
+ @SuppressWarnings("unchecked")
+ private static void testRawSignatures() {
+ // Test JList
+ ListModel rawTestModel = new DefaultListModel();
+
+ new JList();
+ new JList(rawTestModel);
+ new JList(new Object[]{TEST_ELEMENT});
+ JList rawTestList = new JList(new Vector());
+ rawTestList.getPrototypeCellValue();
+ rawTestList.setPrototypeCellValue(TEST_ELEMENT);
+ rawTestList.getCellRenderer();
+ rawTestList.setCellRenderer(new DefaultListCellRenderer());
+ rawTestList.getModel();
+ rawTestList.setModel(rawTestModel);
+ rawTestList.setListData(new Object[]{TEST_ELEMENT});
+ rawTestList.setListData(new Vector());
+
+ @SuppressWarnings("deprecation")
+ Object[] selectedValues = rawTestList.getSelectedValues();
+ rawTestList.getSelectedValue();
+
+ // Test ListCellRenderer
+ ListCellRenderer rawTestCellRenderer = new DefaultListCellRenderer();
+ String testEntry = "Test";
+ @SuppressWarnings("unchecked")
+ JList rawJList = new JList(new Object[]{testEntry});
+
+ rawTestCellRenderer.getListCellRendererComponent(rawJList,
+ testEntry, 0, true, true);
+
+ // Test ListModel
+ DefaultListModel testModel = new DefaultListModel();
+ testModel.addElement(TEST_ELEMENT);
+ rawTestModel = testModel;
+ rawTestModel.getElementAt(0);
+
+ // Test DefaultListModel
+ DefaultListModel defaultListModel = new DefaultListModel();
+
+ defaultListModel.addElement(TEST_ELEMENT);
+ defaultListModel.getElementAt(0);
+ defaultListModel.elements();
+ defaultListModel.elementAt(0);
+ defaultListModel.firstElement();
+ defaultListModel.lastElement();
+
+ String testElement2 = "Test2";
+
+ defaultListModel.setElementAt(testElement2, 0);
+ defaultListModel.insertElementAt(TEST_ELEMENT, 0);
+ defaultListModel.get(0);
+ defaultListModel.set(0, testElement2);
+ defaultListModel.add(0, TEST_ELEMENT);
+ defaultListModel.remove(0);
+
+ // Test AbstractListModel
+ @SuppressWarnings("serial")
+ ListModel abstractListModel = new AbstractListModel() {
+ public int getSize() {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ public Object getElementAt(int index) {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+ };
+
+ // Test DefaultListCellRenderer
+ DefaultListCellRenderer cellRenderer = new DefaultListCellRenderer();
+
+ @SuppressWarnings("unchecked")
+ JList list = new JList(new Object[]{testEntry});
+
+ cellRenderer.getListCellRendererComponent(rawJList, testEntry, 0, true, true);
+ }
+
+ private static <E> void testGenericSignatures() {
+ // Test JList
+ ListModel<String> stringListModel = new DefaultListModel<String>();
+
+ new JList<String>();
+ new JList<String>(stringListModel);
+ new JList<String>(new String[]{TEST_ELEMENT});
+
+ JList<String> stringTestList = new JList<String>(new Vector<String>());
+
+ stringTestList.getPrototypeCellValue();
+ stringTestList.setPrototypeCellValue(TEST_ELEMENT);
+
+ ListCellRenderer<? super String> cellRenderer = stringTestList.getCellRenderer();
+
+ stringTestList.setCellRenderer(new DefaultListCellRenderer());
+
+ ListModel<String> model = stringTestList.getModel();
+
+ stringTestList.setModel(stringListModel);
+ stringTestList.setListData(new String[]{TEST_ELEMENT});
+ stringTestList.setListData(new Vector<String>());
+
+ @SuppressWarnings("deprecation")
+ Object[] selectedValues = stringTestList.getSelectedValues();
+
+ stringTestList.getSelectedValue();
+
+ // Test ListCellRenderer
+ ListCellRenderer<Object> stringTestCellRenderer =
+ new DefaultListCellRenderer();
+ String testEntry = "Test";
+ JList<String> stringJList = new JList<String>(new String[]{testEntry});
+
+ Component listCellRendererComponent2 =
+ stringTestCellRenderer.getListCellRendererComponent(stringJList,
+ testEntry, 0, true, true);
+
+ // Test ListModel
+ DefaultListModel<String> testModel = new DefaultListModel<String>();
+ testModel.addElement(TEST_ELEMENT);
+ stringListModel = testModel;
+
+ String element1 = stringListModel.getElementAt(0);
+
+ // Test DefaultListModel
+ DefaultListModel<String> stringTestModel = new DefaultListModel<String>();
+
+ stringTestModel.addElement(TEST_ELEMENT);
+ element1 = stringTestModel.getElementAt(0);
+ Enumeration<String> elements = stringTestModel.elements();
+ String element2 = stringTestModel.elementAt(0);
+ String firstElement = stringTestModel.firstElement();
+ String lastElement = stringTestModel.lastElement();
+
+ String testElement2 = "Test2";
+ stringTestModel.setElementAt(testElement2, 0);
+ stringTestModel.insertElementAt(TEST_ELEMENT, 0);
+ String element3 = stringTestModel.get(0);
+ String element4 = stringTestModel.set(0, testElement2);
+ stringTestModel.add(0, TEST_ELEMENT);
+ String removedElement = stringTestModel.remove(0);
+
+ // Test AbstractListModel
+ stringListModel = new AbstractListModel<String>() {
+
+ public int getSize() {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ public String getElementAt(int index) {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+ };
+
+ @SuppressWarnings("serial")
+ ListModel<E> genericTestModel = new AbstractListModel<E>() {
+
+ public int getSize() {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ public E getElementAt(int index) {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+ };
+
+ // Test DefaultListCellRenderer
+ cellRenderer = new DefaultListCellRenderer();
+
+ stringJList = new JList<String>(new String[]{testEntry});
+
+ listCellRendererComponent2 = cellRenderer.getListCellRendererComponent(stringJList, testEntry, 0, true, true);
+ }
+
+ private static void testGetSelectedValuesList() {
+ Vector<Integer> data = new Vector<Integer>();
+ for (int i = 0; i < 10; i++) {
+ data.add(i);
+ }
+ JList<Integer> list = new JList<Integer>(data);
+ list.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
+ list.setSelectedIndices(new int[]{1, 2, 3, 5, 6, 8});
+
+ @SuppressWarnings("deprecation")
+ Object[] expectedSelectedValues = list.getSelectedValues();
+ List<Integer> selectedValuesList = list.getSelectedValuesList();
+ assertEquals(expectedSelectedValues, selectedValuesList.toArray());
+ }
+
+ private static void assertEquals(Object[] expectedArray,
+ Object[] actualArray) {
+ if (!Arrays.equals(expectedArray, actualArray)) {
+ throw new RuntimeException("Expected: " + Arrays.toString(
+ expectedArray) + " but was: " + Arrays.toString(actualArray));
+ }
+ }
+}