src/java.desktop/share/classes/javax/swing/JList.java

Print this page




   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package javax.swing;
  27 
  28 import java.awt.*;
  29 import java.awt.event.*;
  30 
  31 import java.util.Vector;
  32 import java.util.Locale;
  33 import java.util.ArrayList;
  34 import java.util.Collections;
  35 import java.util.List;
  36 


  37 import java.beans.PropertyChangeEvent;
  38 import java.beans.PropertyChangeListener;
  39 import java.beans.Transient;
  40 
  41 import javax.swing.event.*;
  42 import javax.accessibility.*;
  43 import javax.swing.plaf.*;
  44 import javax.swing.text.Position;
  45 
  46 import java.io.ObjectOutputStream;
  47 import java.io.ObjectInputStream;
  48 import java.io.IOException;
  49 import java.io.Serializable;
  50 
  51 import sun.swing.SwingUtilities2;
  52 import sun.swing.SwingUtilities2.Section;
  53 import static sun.swing.SwingUtilities2.Section.*;
  54 
  55 
  56 /**
  57  * A component that displays a list of objects and allows the user to select
  58  * one or more items. A separate model, {@code ListModel}, maintains the
  59  * contents of the list.
  60  * <p>
  61  * It's easy to display an array or Vector of objects, using the {@code JList}
  62  * constructor that automatically builds a read-only {@code ListModel} instance
  63  * for you:
  64  * <pre>
  65  * {@code
  66  * // Create a JList that displays strings from an array
  67  *
  68  * String[] data = {"one", "two", "three", "four"};
  69  * JList<String> myList = new JList<String>(data);
  70  *
  71  * // Create a JList that displays the superclasses of JList.class, by
  72  * // creating it with a Vector populated with this data
  73  *
  74  * Vector<Class<?>> superClasses = new Vector<Class<?>>();
  75  * Class<JList> rootClass = javax.swing.JList.class;


 254  * appropriate for short term storage or RMI between applications running
 255  * the same version of Swing.  As of 1.4, support for long term storage
 256  * of all JavaBeans&trade;
 257  * has been added to the <code>java.beans</code> package.
 258  * Please see {@link java.beans.XMLEncoder}.
 259  * <p>
 260  * See <a href="http://docs.oracle.com/javase/tutorial/uiswing/components/list.html">How to Use Lists</a>
 261  * in <a href="http://docs.oracle.com/javase/tutorial/"><em>The Java Tutorial</em></a>
 262  * for further documentation.
 263  *
 264  * @see ListModel
 265  * @see AbstractListModel
 266  * @see DefaultListModel
 267  * @see ListSelectionModel
 268  * @see DefaultListSelectionModel
 269  * @see ListCellRenderer
 270  * @see DefaultListCellRenderer
 271  *
 272  * @param <E> the type of the elements of this list
 273  *
 274  * @beaninfo
 275  *   attribute: isContainer false
 276  * description: A component which allows for the selection of one or more objects from a list.
 277  *
 278  * @author Hans Muller
 279  * @since 1.2
 280  */


 281 @SuppressWarnings("serial") // Same-version serialization only
 282 public class JList<E> extends JComponent implements Scrollable, Accessible
 283 {
 284     /**
 285      * @see #getUIClassID
 286      * @see #readObject
 287      */
 288     private static final String uiClassID = "ListUI";
 289 
 290     /**
 291      * Indicates a vertical layout of cells, in a single column;
 292      * the default layout.
 293      * @see #setLayoutOrientation
 294      * @since 1.4
 295      */
 296     public static final int VERTICAL = 0;
 297 
 298     /**
 299      * Indicates a "newspaper style" layout with cells flowing vertically
 300      * then horizontally.


 498     }
 499 
 500 
 501     /**
 502      * Returns the {@code ListUI}, the look and feel object that
 503      * renders this component.
 504      *
 505      * @return the <code>ListUI</code> object that renders this component
 506      */
 507     public ListUI getUI() {
 508         return (ListUI)ui;
 509     }
 510 
 511 
 512     /**
 513      * Sets the {@code ListUI}, the look and feel object that
 514      * renders this component.
 515      *
 516      * @param ui  the <code>ListUI</code> object
 517      * @see UIDefaults#getUI
 518      * @beaninfo
 519      *        bound: true
 520      *       hidden: true
 521      *    attribute: visualUpdate true
 522      *  description: The UI object that implements the Component's LookAndFeel.
 523      */


 524     public void setUI(ListUI ui) {
 525         super.setUI(ui);
 526     }
 527 
 528 
 529     /**
 530      * Resets the {@code ListUI} property by setting it to the value provided
 531      * by the current look and feel. If the current cell renderer was installed
 532      * by the developer (rather than the look and feel itself), this also causes
 533      * the cell renderer and its children to be updated, by calling
 534      * {@code SwingUtilities.updateComponentTreeUI} on it.
 535      *
 536      * @see UIManager#getUI
 537      * @see SwingUtilities#updateComponentTreeUI
 538      */
 539     public void updateUI() {
 540         setUI((ListUI)UIManager.getUI(this));
 541 
 542         ListCellRenderer<? super E> renderer = getCellRenderer();
 543         if (renderer instanceof Component) {
 544             SwingUtilities.updateComponentTreeUI((Component)renderer);
 545         }
 546     }
 547 
 548 
 549     /**
 550      * Returns {@code "ListUI"}, the <code>UIDefaults</code> key used to look
 551      * up the name of the {@code javax.swing.plaf.ListUI} class that defines
 552      * the look and feel for this component.
 553      *
 554      * @return the string "ListUI"
 555      * @see JComponent#getUIClassID
 556      * @see UIDefaults#getUI
 557      */

 558     public String getUIClassID() {
 559         return uiClassID;
 560     }
 561 
 562 
 563     /* -----private-----
 564      * This method is called by setPrototypeCellValue and setCellRenderer
 565      * to update the fixedCellWidth and fixedCellHeight properties from the
 566      * current value of prototypeCellValue (if it's non null).
 567      * <p>
 568      * This method sets fixedCellWidth and fixedCellHeight but does <b>not</b>
 569      * generate PropertyChangeEvents for them.
 570      *
 571      * @see #setPrototypeCellValue
 572      * @see #setCellRenderer
 573      */
 574     private void updateFixedCellSize()
 575     {
 576         ListCellRenderer<? super E> cr = getCellRenderer();
 577         E value = getPrototypeCellValue();


 623      * <p>
 624      * While all three of the {@code prototypeCellValue},
 625      * {@code fixedCellHeight}, and {@code fixedCellWidth} properties may be
 626      * modified by this method, {@code PropertyChangeEvent} notifications are
 627      * only sent when the {@code prototypeCellValue} property changes.
 628      * <p>
 629      * To see an example which sets this property, see the
 630      * <a href="#prototype_example">class description</a> above.
 631      * <p>
 632      * The default value of this property is <code>null</code>.
 633      * <p>
 634      * This is a JavaBeans bound property.
 635      *
 636      * @param prototypeCellValue  the value on which to base
 637      *                          <code>fixedCellWidth</code> and
 638      *                          <code>fixedCellHeight</code>
 639      * @see #getPrototypeCellValue
 640      * @see #setFixedCellWidth
 641      * @see #setFixedCellHeight
 642      * @see JComponent#addPropertyChangeListener
 643      * @beaninfo
 644      *       bound: true
 645      *   attribute: visualUpdate true
 646      * description: The cell prototype value, used to compute cell width and height.
 647      */


 648     public void setPrototypeCellValue(E prototypeCellValue) {
 649         E oldValue = this.prototypeCellValue;
 650         this.prototypeCellValue = prototypeCellValue;
 651 
 652         /* If the prototypeCellValue has changed and is non-null,
 653          * then recompute fixedCellWidth and fixedCellHeight.
 654          */
 655 
 656         if ((prototypeCellValue != null) && !prototypeCellValue.equals(oldValue)) {
 657             updateFixedCellSize();
 658         }
 659 
 660         firePropertyChange("prototypeCellValue", oldValue, prototypeCellValue);
 661     }
 662 
 663 
 664     /**
 665      * Returns the value of the {@code fixedCellWidth} property.
 666      *
 667      * @return the fixed cell width
 668      * @see #setFixedCellWidth
 669      */
 670     public int getFixedCellWidth() {
 671         return fixedCellWidth;
 672     }
 673 
 674     /**
 675      * Sets a fixed value to be used for the width of every cell in the list.
 676      * If {@code width} is -1, cell widths are computed in the {@code ListUI}
 677      * by applying <code>getPreferredSize</code> to the cell renderer component
 678      * for each list element.
 679      * <p>
 680      * The default value of this property is {@code -1}.
 681      * <p>
 682      * This is a JavaBeans bound property.
 683      *
 684      * @param width the width to be used for all cells in the list
 685      * @see #setPrototypeCellValue
 686      * @see #setFixedCellWidth
 687      * @see JComponent#addPropertyChangeListener
 688      * @beaninfo
 689      *       bound: true
 690      *   attribute: visualUpdate true
 691      * description: Defines a fixed cell width when greater than zero.
 692      */


 693     public void setFixedCellWidth(int width) {
 694         int oldValue = fixedCellWidth;
 695         fixedCellWidth = width;
 696         firePropertyChange("fixedCellWidth", oldValue, fixedCellWidth);
 697     }
 698 
 699 
 700     /**
 701      * Returns the value of the {@code fixedCellHeight} property.
 702      *
 703      * @return the fixed cell height
 704      * @see #setFixedCellHeight
 705      */
 706     public int getFixedCellHeight() {
 707         return fixedCellHeight;
 708     }
 709 
 710     /**
 711      * Sets a fixed value to be used for the height of every cell in the list.
 712      * If {@code height} is -1, cell heights are computed in the {@code ListUI}
 713      * by applying <code>getPreferredSize</code> to the cell renderer component
 714      * for each list element.
 715      * <p>
 716      * The default value of this property is {@code -1}.
 717      * <p>
 718      * This is a JavaBeans bound property.
 719      *
 720      * @param height the height to be used for all cells in the list
 721      * @see #setPrototypeCellValue
 722      * @see #setFixedCellWidth
 723      * @see JComponent#addPropertyChangeListener
 724      * @beaninfo
 725      *       bound: true
 726      *   attribute: visualUpdate true
 727      * description: Defines a fixed cell height when greater than zero.
 728      */


 729     public void setFixedCellHeight(int height) {
 730         int oldValue = fixedCellHeight;
 731         fixedCellHeight = height;
 732         firePropertyChange("fixedCellHeight", oldValue, fixedCellHeight);
 733     }
 734 
 735 
 736     /**
 737      * Returns the object responsible for painting list items.
 738      *
 739      * @return the value of the {@code cellRenderer} property
 740      * @see #setCellRenderer
 741      */
 742     @Transient
 743     public ListCellRenderer<? super E> getCellRenderer() {
 744         return cellRenderer;
 745     }
 746 
 747     /**
 748      * Sets the delegate that is used to paint each cell in the list.
 749      * The job of a cell renderer is discussed in detail in the
 750      * <a href="#renderer">class level documentation</a>.
 751      * <p>
 752      * If the {@code prototypeCellValue} property is {@code non-null},
 753      * setting the cell renderer also causes the {@code fixedCellWidth} and
 754      * {@code fixedCellHeight} properties to be re-calculated. Only one
 755      * <code>PropertyChangeEvent</code> is generated however -
 756      * for the <code>cellRenderer</code> property.
 757      * <p>
 758      * The default value of this property is provided by the {@code ListUI}
 759      * delegate, i.e. by the look and feel implementation.
 760      * <p>
 761      * This is a JavaBeans bound property.
 762      *
 763      * @param cellRenderer the <code>ListCellRenderer</code>
 764      *                          that paints list cells
 765      * @see #getCellRenderer
 766      * @beaninfo
 767      *       bound: true
 768      *   attribute: visualUpdate true
 769      * description: The component used to draw the cells.
 770      */


 771     public void setCellRenderer(ListCellRenderer<? super E> cellRenderer) {
 772         ListCellRenderer<? super E> oldValue = this.cellRenderer;
 773         this.cellRenderer = cellRenderer;
 774 
 775         /* If the cellRenderer has changed and prototypeCellValue
 776          * was set, then recompute fixedCellWidth and fixedCellHeight.
 777          */
 778         if ((cellRenderer != null) && !cellRenderer.equals(oldValue)) {
 779             updateFixedCellSize();
 780         }
 781 
 782         firePropertyChange("cellRenderer", oldValue, cellRenderer);
 783     }
 784 
 785 
 786     /**
 787      * Returns the color used to draw the foreground of selected items.
 788      * {@code DefaultListCellRenderer} uses this color to draw the foreground
 789      * of items in the selected state, as do the renderers installed by most
 790      * {@code ListUI} implementations.


 801     /**
 802      * Sets the color used to draw the foreground of selected items, which
 803      * cell renderers can use to render text and graphics.
 804      * {@code DefaultListCellRenderer} uses this color to draw the foreground
 805      * of items in the selected state, as do the renderers installed by most
 806      * {@code ListUI} implementations.
 807      * <p>
 808      * The default value of this property is defined by the look and feel
 809      * implementation.
 810      * <p>
 811      * This is a JavaBeans bound property.
 812      *
 813      * @param selectionForeground  the {@code Color} to use in the foreground
 814      *                             for selected list items
 815      * @see #getSelectionForeground
 816      * @see #setSelectionBackground
 817      * @see #setForeground
 818      * @see #setBackground
 819      * @see #setFont
 820      * @see DefaultListCellRenderer
 821      * @beaninfo
 822      *       bound: true
 823      *   attribute: visualUpdate true
 824      * description: The foreground color of selected cells.
 825      */


 826     public void setSelectionForeground(Color selectionForeground) {
 827         Color oldValue = this.selectionForeground;
 828         this.selectionForeground = selectionForeground;
 829         firePropertyChange("selectionForeground", oldValue, selectionForeground);
 830     }
 831 
 832 
 833     /**
 834      * Returns the color used to draw the background of selected items.
 835      * {@code DefaultListCellRenderer} uses this color to draw the background
 836      * of items in the selected state, as do the renderers installed by most
 837      * {@code ListUI} implementations.
 838      *
 839      * @return the color to draw the background of selected items
 840      * @see #setSelectionBackground
 841      * @see DefaultListCellRenderer
 842      */
 843     public Color getSelectionBackground() {
 844         return selectionBackground;
 845     }


 848     /**
 849      * Sets the color used to draw the background of selected items, which
 850      * cell renderers can use fill selected cells.
 851      * {@code DefaultListCellRenderer} uses this color to fill the background
 852      * of items in the selected state, as do the renderers installed by most
 853      * {@code ListUI} implementations.
 854      * <p>
 855      * The default value of this property is defined by the look
 856      * and feel implementation.
 857      * <p>
 858      * This is a JavaBeans bound property.
 859      *
 860      * @param selectionBackground  the {@code Color} to use for the
 861      *                             background of selected cells
 862      * @see #getSelectionBackground
 863      * @see #setSelectionForeground
 864      * @see #setForeground
 865      * @see #setBackground
 866      * @see #setFont
 867      * @see DefaultListCellRenderer
 868      * @beaninfo
 869      *       bound: true
 870      *   attribute: visualUpdate true
 871      * description: The background color of selected cells.
 872      */


 873     public void setSelectionBackground(Color selectionBackground) {
 874         Color oldValue = this.selectionBackground;
 875         this.selectionBackground = selectionBackground;
 876         firePropertyChange("selectionBackground", oldValue, selectionBackground);
 877     }
 878 
 879 
 880     /**
 881      * Returns the value of the {@code visibleRowCount} property. See the
 882      * documentation for {@link #setVisibleRowCount} for details on how to
 883      * interpret this value.
 884      *
 885      * @return the value of the {@code visibleRowCount} property.
 886      * @see #setVisibleRowCount
 887      */
 888     public int getVisibleRowCount() {
 889         return visibleRowCount;
 890     }
 891 
 892     /**


 903      * documentation for more details.
 904      * <p>
 905      * In {@code HORIZONTAL_WRAP} and {@code VERTICAL_WRAP} orientations:<br>
 906      * This affects how cells are wrapped. See the documentation of
 907      * {@link #setLayoutOrientation} for more details.
 908      * <p>
 909      * The default value of this property is {@code 8}.
 910      * <p>
 911      * Calling this method with a negative value results in the property
 912      * being set to {@code 0}.
 913      * <p>
 914      * This is a JavaBeans bound property.
 915      *
 916      * @param visibleRowCount  an integer specifying the preferred number of
 917      *                         rows to display without requiring scrolling
 918      * @see #getVisibleRowCount
 919      * @see #getPreferredScrollableViewportSize
 920      * @see #setLayoutOrientation
 921      * @see JComponent#getVisibleRect
 922      * @see JViewport
 923      * @beaninfo
 924      *       bound: true
 925      *   attribute: visualUpdate true
 926      * description: The preferred number of rows to display without
 927      *              requiring scrolling
 928      */


 929     public void setVisibleRowCount(int visibleRowCount) {
 930         int oldValue = this.visibleRowCount;
 931         this.visibleRowCount = Math.max(0, visibleRowCount);
 932         firePropertyChange("visibleRowCount", oldValue, visibleRowCount);
 933     }
 934 
 935 
 936     /**
 937      * Returns the layout orientation property for the list: {@code VERTICAL}
 938      * if the layout is a single column of cells, {@code VERTICAL_WRAP} if the
 939      * layout is "newspaper style" with the content flowing vertically then
 940      * horizontally, or {@code HORIZONTAL_WRAP} if the layout is "newspaper
 941      * style" with the content flowing horizontally then vertically.
 942      *
 943      * @return the value of the {@code layoutOrientation} property
 944      * @see #setLayoutOrientation
 945      * @since 1.4
 946      */
 947     public int getLayoutOrientation() {
 948         return layoutOrientation;


 982      *           list; otherwise wrapping is done in such a way as to ensure
 983      *           {@code visibleRowCount} rows in the list.
 984      *   <tr><td><code>VERTICAL_WRAP</code>
 985      *       <td>Cells are layed out vertically, wrapping to a new column as
 986      *           necessary. If the {@code visibleRowCount} property is less than
 987      *           or equal to zero, wrapping is determined by the height of the
 988      *           list; otherwise wrapping is done at {@code visibleRowCount} rows.
 989      *  </table>
 990      * <p>
 991      * The default value of this property is <code>VERTICAL</code>.
 992      *
 993      * @param layoutOrientation the new layout orientation, one of:
 994      *        {@code VERTICAL}, {@code HORIZONTAL_WRAP} or {@code VERTICAL_WRAP}
 995      * @see #getLayoutOrientation
 996      * @see #setVisibleRowCount
 997      * @see #getScrollableTracksViewportHeight
 998      * @see #getScrollableTracksViewportWidth
 999      * @throws IllegalArgumentException if {@code layoutOrientation} isn't one of the
1000      *         allowable values
1001      * @since 1.4
1002      * @beaninfo
1003      *       bound: true
1004      *   attribute: visualUpdate true
1005      * description: Defines the way list cells are layed out.
1006      *        enum: VERTICAL JList.VERTICAL
1007      *              HORIZONTAL_WRAP JList.HORIZONTAL_WRAP
1008      *              VERTICAL_WRAP JList.VERTICAL_WRAP
1009      */





1010     public void setLayoutOrientation(int layoutOrientation) {
1011         int oldValue = this.layoutOrientation;
1012         switch (layoutOrientation) {
1013         case VERTICAL:
1014         case VERTICAL_WRAP:
1015         case HORIZONTAL_WRAP:
1016             this.layoutOrientation = layoutOrientation;
1017             firePropertyChange("layoutOrientation", oldValue, layoutOrientation);
1018             break;
1019         default:
1020             throw new IllegalArgumentException("layoutOrientation must be one of: VERTICAL, HORIZONTAL_WRAP or VERTICAL_WRAP");
1021         }
1022     }
1023 
1024 
1025     /**
1026      * Returns the smallest list index that is currently visible.
1027      * In a left-to-right {@code componentOrientation}, the first visible
1028      * cell is found closest to the list's upper-left corner. In right-to-left
1029      * orientation, it is found closest to the upper-right corner.
1030      * If nothing is visible or the list is empty, {@code -1} is returned.
1031      * Note that the returned cell may only be partially visible.
1032      *
1033      * @return the index of the first visible cell
1034      * @see #getLastVisibleIndex
1035      * @see JComponent#getVisibleRect
1036      */

1037     public int getFirstVisibleIndex() {
1038         Rectangle r = getVisibleRect();
1039         int first;
1040         if (this.getComponentOrientation().isLeftToRight()) {
1041             first = locationToIndex(r.getLocation());
1042         } else {
1043             first = locationToIndex(new Point((r.x + r.width) - 1, r.y));
1044         }
1045         if (first != -1) {
1046             Rectangle bounds = getCellBounds(first, first);
1047             if (bounds != null) {
1048                 SwingUtilities.computeIntersection(r.x, r.y, r.width, r.height, bounds);
1049                 if (bounds.width == 0 || bounds.height == 0) {
1050                     first = -1;
1051                 }
1052             }
1053         }
1054         return first;
1055     }
1056 
1057 
1058     /**
1059      * Returns the largest list index that is currently visible.
1060      * If nothing is visible or the list is empty, {@code -1} is returned.
1061      * Note that the returned cell may only be partially visible.
1062      *
1063      * @return the index of the last visible cell
1064      * @see #getFirstVisibleIndex
1065      * @see JComponent#getVisibleRect
1066      */

1067     public int getLastVisibleIndex() {
1068         boolean leftToRight = this.getComponentOrientation().isLeftToRight();
1069         Rectangle r = getVisibleRect();
1070         Point lastPoint;
1071         if (leftToRight) {
1072             lastPoint = new Point((r.x + r.width) - 1, (r.y + r.height) - 1);
1073         } else {
1074             lastPoint = new Point(r.x, (r.y + r.height) - 1);
1075         }
1076         int location = locationToIndex(lastPoint);
1077 
1078         if (location != -1) {
1079             Rectangle bounds = getCellBounds(location, location);
1080 
1081             if (bounds != null) {
1082                 SwingUtilities.computeIntersection(r.x, r.y, r.width, r.height, bounds);
1083                 if (bounds.width == 0 || bounds.height == 0) {
1084                     // Try the top left(LTR) or top right(RTL) corner, and
1085                     // then go across checking each cell for HORIZONTAL_WRAP.
1086                     // Try the lower left corner, and then go across checking


1163      * {@code ListUI}. When automatic drag handling is enabled, most look and
1164      * feels (including those that subclass {@code BasicLookAndFeel}) begin a
1165      * drag and drop operation whenever the user presses the mouse button over
1166      * an item and then moves the mouse a few pixels. Setting this property to
1167      * {@code true} can therefore have a subtle effect on how selections behave.
1168      * <p>
1169      * If a look and feel is used that ignores this property, you can still
1170      * begin a drag and drop operation by calling {@code exportAsDrag} on the
1171      * list's {@code TransferHandler}.
1172      *
1173      * @param b whether or not to enable automatic drag handling
1174      * @exception HeadlessException if
1175      *            <code>b</code> is <code>true</code> and
1176      *            <code>GraphicsEnvironment.isHeadless()</code>
1177      *            returns <code>true</code>
1178      * @see java.awt.GraphicsEnvironment#isHeadless
1179      * @see #getDragEnabled
1180      * @see #setTransferHandler
1181      * @see TransferHandler
1182      * @since 1.4
1183      *
1184      * @beaninfo
1185      *  description: determines whether automatic drag handling is enabled
1186      *        bound: false
1187      */


1188     public void setDragEnabled(boolean b) {
1189         if (b && GraphicsEnvironment.isHeadless()) {
1190             throw new HeadlessException();
1191         }
1192         dragEnabled = b;
1193     }
1194 
1195     /**
1196      * Returns whether or not automatic drag handling is enabled.
1197      *
1198      * @return the value of the {@code dragEnabled} property
1199      * @see #setDragEnabled
1200      * @since 1.4
1201      */
1202     public boolean getDragEnabled() {
1203         return dragEnabled;
1204     }
1205 
1206     /**
1207      * Sets the drop mode for this component. For backward compatibility,


1432      * This method is not meant for querying the drop location
1433      * from a {@code TransferHandler}, as the drop location is only
1434      * set after the {@code TransferHandler}'s <code>canImport</code>
1435      * has returned and has allowed for the location to be shown.
1436      * <p>
1437      * When this property changes, a property change event with
1438      * name "dropLocation" is fired by the component.
1439      * <p>
1440      * By default, responsibility for listening for changes to this property
1441      * and indicating the drop location visually lies with the list's
1442      * {@code ListUI}, which may paint it directly and/or install a cell
1443      * renderer to do so. Developers wishing to implement custom drop location
1444      * painting and/or replace the default cell renderer, may need to honor
1445      * this property.
1446      *
1447      * @return the drop location
1448      * @see #setDropMode
1449      * @see TransferHandler#canImport(TransferHandler.TransferSupport)
1450      * @since 1.6
1451      */

1452     public final DropLocation getDropLocation() {
1453         return dropLocation;
1454     }
1455 
1456     /**
1457      * Returns the next list element whose {@code toString} value
1458      * starts with the given prefix.
1459      *
1460      * @param prefix the string to test for a match
1461      * @param startIndex the index for starting the search
1462      * @param bias the search direction, either
1463      * Position.Bias.Forward or Position.Bias.Backward.
1464      * @return the index of the next list element that
1465      * starts with the prefix; otherwise {@code -1}
1466      * @exception IllegalArgumentException if prefix is {@code null}
1467      * or startIndex is out of bounds
1468      * @since 1.4
1469      */
1470     public int getNextMatch(String prefix, int startIndex, Position.Bias bias) {
1471         ListModel<E> model = getModel();


1647      *                          list of items
1648      * @see #setModel
1649      */
1650     public ListModel<E> getModel() {
1651         return dataModel;
1652     }
1653 
1654     /**
1655      * Sets the model that represents the contents or "value" of the
1656      * list, notifies property change listeners, and then clears the
1657      * list's selection.
1658      * <p>
1659      * This is a JavaBeans bound property.
1660      *
1661      * @param model  the <code>ListModel</code> that provides the
1662      *                                          list of items for display
1663      * @exception IllegalArgumentException  if <code>model</code> is
1664      *                                          <code>null</code>
1665      * @see #getModel
1666      * @see #clearSelection
1667      * @beaninfo
1668      *       bound: true
1669      *   attribute: visualUpdate true
1670      * description: The object that contains the data to be drawn by this JList.
1671      */


1672     public void setModel(ListModel<E> model) {
1673         if (model == null) {
1674             throw new IllegalArgumentException("model must be non null");
1675         }
1676         ListModel<E> oldValue = dataModel;
1677         dataModel = model;
1678         firePropertyChange("model", oldValue, dataModel);
1679         clearSelection();
1680     }
1681 
1682 
1683     /**
1684      * Constructs a read-only <code>ListModel</code> from an array of items,
1685      * and calls {@code setModel} with this model.
1686      * <p>
1687      * Attempts to pass a {@code null} value to this method results in
1688      * undefined behavior and, most likely, exceptions. The created model
1689      * references the given array directly. Attempts to modify the array
1690      * after invoking this method results in undefined behavior.
1691      *


1843      * Removes a selection listener from the list.
1844      *
1845      * @param listener the {@code ListSelectionListener} to remove
1846      * @see #addListSelectionListener
1847      * @see #getSelectionModel
1848      */
1849     public void removeListSelectionListener(ListSelectionListener listener) {
1850         listenerList.remove(ListSelectionListener.class, listener);
1851     }
1852 
1853 
1854     /**
1855      * Returns an array of all the {@code ListSelectionListener}s added
1856      * to this {@code JList} by way of {@code addListSelectionListener}.
1857      *
1858      * @return all of the {@code ListSelectionListener}s on this list, or
1859      *         an empty array if no listeners have been added
1860      * @see #addListSelectionListener
1861      * @since 1.4
1862      */

1863     public ListSelectionListener[] getListSelectionListeners() {
1864         return listenerList.getListeners(ListSelectionListener.class);
1865     }
1866 
1867 
1868     /**
1869      * Sets the <code>selectionModel</code> for the list to a
1870      * non-<code>null</code> <code>ListSelectionModel</code>
1871      * implementation. The selection model handles the task of making single
1872      * selections, selections of contiguous ranges, and non-contiguous
1873      * selections.
1874      * <p>
1875      * This is a JavaBeans bound property.
1876      *
1877      * @param selectionModel  the <code>ListSelectionModel</code> that
1878      *                          implements the selections
1879      * @exception IllegalArgumentException   if <code>selectionModel</code>
1880      *                                          is <code>null</code>
1881      * @see #getSelectionModel
1882      * @beaninfo
1883      *       bound: true
1884      * description: The selection model, recording which cells are selected.
1885      */


1886     public void setSelectionModel(ListSelectionModel selectionModel) {
1887         if (selectionModel == null) {
1888             throw new IllegalArgumentException("selectionModel must be non null");
1889         }
1890 
1891         /* Remove the forwarding ListSelectionListener from the old
1892          * selectionModel, and add it to the new one, if necessary.
1893          */
1894         if (selectionListener != null) {
1895             this.selectionModel.removeListSelectionListener(selectionListener);
1896             selectionModel.addListSelectionListener(selectionListener);
1897         }
1898 
1899         ListSelectionModel oldValue = this.selectionModel;
1900         this.selectionModel = selectionModel;
1901         firePropertyChange("selectionModel", oldValue, selectionModel);
1902     }
1903 
1904 
1905     /**


1911      * <li>{@code ListSelectionModel.SINGLE_SELECTION} -
1912      *   Only one list index can be selected at a time. In this mode,
1913      *   {@code setSelectionInterval} and {@code addSelectionInterval} are
1914      *   equivalent, both replacing the current selection with the index
1915      *   represented by the second argument (the "lead").
1916      * <li>{@code ListSelectionModel.SINGLE_INTERVAL_SELECTION} -
1917      *   Only one contiguous interval can be selected at a time.
1918      *   In this mode, {@code addSelectionInterval} behaves like
1919      *   {@code setSelectionInterval} (replacing the current selection},
1920      *   unless the given interval is immediately adjacent to or overlaps
1921      *   the existing selection, and can be used to grow the selection.
1922      * <li>{@code ListSelectionModel.MULTIPLE_INTERVAL_SELECTION} -
1923      *   In this mode, there's no restriction on what can be selected.
1924      *   This mode is the default.
1925      * </ul>
1926      *
1927      * @param selectionMode the selection mode
1928      * @see #getSelectionMode
1929      * @throws IllegalArgumentException if the selection mode isn't
1930      *         one of those allowed
1931      * @beaninfo
1932      * description: The selection mode.
1933      *        enum: SINGLE_SELECTION            ListSelectionModel.SINGLE_SELECTION
1934      *              SINGLE_INTERVAL_SELECTION   ListSelectionModel.SINGLE_INTERVAL_SELECTION
1935      *              MULTIPLE_INTERVAL_SELECTION ListSelectionModel.MULTIPLE_INTERVAL_SELECTION
1936      */





1937     public void setSelectionMode(int selectionMode) {
1938         getSelectionModel().setSelectionMode(selectionMode);
1939     }
1940 
1941     /**
1942      * Returns the current selection mode for the list. This is a cover
1943      * method that delegates to the method of the same name on the
1944      * list's selection model.
1945      *
1946      * @return the current selection mode
1947      * @see #setSelectionMode
1948      */
1949     public int getSelectionMode() {
1950         return getSelectionModel().getSelectionMode();
1951     }
1952 
1953 
1954     /**
1955      * Returns the anchor selection index. This is a cover method that
1956      * delegates to the method of the same name on the list's selection model.
1957      *
1958      * @return the anchor selection index
1959      * @see ListSelectionModel#getAnchorSelectionIndex
1960      */

1961     public int getAnchorSelectionIndex() {
1962         return getSelectionModel().getAnchorSelectionIndex();
1963     }
1964 
1965 
1966     /**
1967      * Returns the lead selection index. This is a cover method that
1968      * delegates to the method of the same name on the list's selection model.
1969      *
1970      * @return the lead selection index
1971      * @see ListSelectionModel#getLeadSelectionIndex
1972      * @beaninfo
1973      * description: The lead selection index.
1974      */


1975     public int getLeadSelectionIndex() {
1976         return getSelectionModel().getLeadSelectionIndex();
1977     }
1978 
1979 
1980     /**
1981      * Returns the smallest selected cell index, or {@code -1} if the selection
1982      * is empty. This is a cover method that delegates to the method of the same
1983      * name on the list's selection model.
1984      *
1985      * @return the smallest selected cell index, or {@code -1}
1986      * @see ListSelectionModel#getMinSelectionIndex
1987      */

1988     public int getMinSelectionIndex() {
1989         return getSelectionModel().getMinSelectionIndex();
1990     }
1991 
1992 
1993     /**
1994      * Returns the largest selected cell index, or {@code -1} if the selection
1995      * is empty. This is a cover method that delegates to the method of the same
1996      * name on the list's selection model.
1997      *
1998      * @return the largest selected cell index
1999      * @see ListSelectionModel#getMaxSelectionIndex
2000      */

2001     public int getMaxSelectionIndex() {
2002         return getSelectionModel().getMaxSelectionIndex();
2003     }
2004 
2005 
2006     /**
2007      * Returns {@code true} if the specified index is selected,
2008      * else {@code false}. This is a cover method that delegates to the method
2009      * of the same name on the list's selection model.
2010      *
2011      * @param index index to be queried for selection state
2012      * @return {@code true} if the specified index is selected,
2013      *         else {@code false}
2014      * @see ListSelectionModel#isSelectedIndex
2015      * @see #setSelectedIndex
2016      */
2017     public boolean isSelectedIndex(int index) {
2018         return getSelectionModel().isSelectedIndex(index);
2019     }
2020 
2021 
2022     /**
2023      * Returns {@code true} if nothing is selected, else {@code false}.
2024      * This is a cover method that delegates to the method of the same
2025      * name on the list's selection model.
2026      *
2027      * @return {@code true} if nothing is selected, else {@code false}
2028      * @see ListSelectionModel#isSelectionEmpty
2029      * @see #clearSelection
2030      */

2031     public boolean isSelectionEmpty() {
2032         return getSelectionModel().isSelectionEmpty();
2033     }
2034 
2035 
2036     /**
2037      * Clears the selection; after calling this method, {@code isSelectionEmpty}
2038      * will return {@code true}. This is a cover method that delegates to the
2039      * method of the same name on the list's selection model.
2040      *
2041      * @see ListSelectionModel#clearSelection
2042      * @see #isSelectionEmpty
2043      */
2044     public void clearSelection() {
2045         getSelectionModel().clearSelection();
2046     }
2047 
2048 
2049     /**
2050      * Selects the specified interval. Both {@code anchor} and {@code lead}


2185                 rvTmp[n++] = i;
2186             }
2187         }
2188         int[] rv = new int[n];
2189         System.arraycopy(rvTmp, 0, rv, 0, n);
2190         return rv;
2191     }
2192 
2193 
2194     /**
2195      * Selects a single cell. Does nothing if the given index is greater
2196      * than or equal to the model size. This is a convenience method that uses
2197      * {@code setSelectionInterval} on the selection model. Refer to the
2198      * documentation for the selection model class being used for details on
2199      * how values less than {@code 0} are handled.
2200      *
2201      * @param index the index of the cell to select
2202      * @see ListSelectionModel#setSelectionInterval
2203      * @see #isSelectedIndex
2204      * @see #addListSelectionListener
2205      * @beaninfo
2206      * description: The index of the selected cell.
2207      */


2208     public void setSelectedIndex(int index) {
2209         if (index >= getModel().getSize()) {
2210             return;
2211         }
2212         getSelectionModel().setSelectionInterval(index, index);
2213     }
2214 
2215 
2216     /**
2217      * Changes the selection to be the set of indices specified by the given
2218      * array. Indices greater than or equal to the model size are ignored.
2219      * This is a convenience method that clears the selection and then uses
2220      * {@code addSelectionInterval} on the selection model to add the indices.
2221      * Refer to the documentation of the selection model class being used for
2222      * details on how values less than {@code 0} are handled.
2223      *
2224      * @param indices an array of the indices of the cells to select,
2225      *                {@code non-null}
2226      * @see ListSelectionModel#addSelectionInterval
2227      * @see #isSelectedIndex


2235         for (int i : indices) {
2236             if (i < size) {
2237                 sm.addSelectionInterval(i, i);
2238             }
2239         }
2240     }
2241 
2242 
2243     /**
2244      * Returns an array of all the selected values, in increasing order based
2245      * on their indices in the list.
2246      *
2247      * @return the selected values, or an empty array if nothing is selected
2248      * @see #isSelectedIndex
2249      * @see #getModel
2250      * @see #addListSelectionListener
2251      *
2252      * @deprecated As of JDK 1.7, replaced by {@link #getSelectedValuesList()}
2253      */
2254     @Deprecated

2255     public Object[] getSelectedValues() {
2256         ListSelectionModel sm = getSelectionModel();
2257         ListModel<E> dm = getModel();
2258 
2259         int iMin = sm.getMinSelectionIndex();
2260         int iMax = sm.getMaxSelectionIndex();
2261 
2262         if ((iMin < 0) || (iMax < 0)) {
2263             return new Object[0];
2264         }
2265 
2266         Object[] rvTmp = new Object[1+ (iMax - iMin)];
2267         int n = 0;
2268         for(int i = iMin; i <= iMax; i++) {
2269             if (sm.isSelectedIndex(i)) {
2270                 rvTmp[n++] = dm.getElementAt(i);
2271             }
2272         }
2273         Object[] rv = new Object[n];
2274         System.arraycopy(rvTmp, 0, rv, 0, n);
2275         return rv;
2276     }
2277 
2278     /**
2279      * Returns a list of all the selected items, in increasing order based
2280      * on their indices in the list.
2281      *
2282      * @return the selected items, or an empty list if nothing is selected
2283      * @see #isSelectedIndex
2284      * @see #getModel
2285      * @see #addListSelectionListener
2286      *
2287      * @since 1.7
2288      */

2289     public List<E> getSelectedValuesList() {
2290         ListSelectionModel sm = getSelectionModel();
2291         ListModel<E> dm = getModel();
2292 
2293         int iMin = sm.getMinSelectionIndex();
2294         int iMax = sm.getMaxSelectionIndex();
2295 
2296         if ((iMin < 0) || (iMax < 0)) {
2297             return Collections.emptyList();
2298         }
2299 
2300         List<E> selectedItems = new ArrayList<E>();
2301         for(int i = iMin; i <= iMax; i++) {
2302             if (sm.isSelectedIndex(i)) {
2303                 selectedItems.add(dm.getElementAt(i));
2304             }
2305         }
2306         return selectedItems;
2307     }
2308 


2321      */
2322     public int getSelectedIndex() {
2323         return getMinSelectionIndex();
2324     }
2325 
2326 
2327     /**
2328      * Returns the value for the smallest selected cell index;
2329      * <i>the selected value</i> when only a single item is selected in the
2330      * list. When multiple items are selected, it is simply the value for the
2331      * smallest selected index. Returns {@code null} if there is no selection.
2332      * <p>
2333      * This is a convenience method that simply returns the model value for
2334      * {@code getMinSelectionIndex}.
2335      *
2336      * @return the first selected value
2337      * @see #getMinSelectionIndex
2338      * @see #getModel
2339      * @see #addListSelectionListener
2340      */

2341     public E getSelectedValue() {
2342         int i = getMinSelectionIndex();
2343         return (i == -1) ? null : getModel().getElementAt(i);
2344     }
2345 
2346 
2347     /**
2348      * Selects the specified object from the list.
2349      *
2350      * @param anObject      the object to select
2351      * @param shouldScroll  {@code true} if the list should scroll to display
2352      *                      the selected object, if one exists; otherwise {@code false}
2353      */
2354     public void setSelectedValue(Object anObject,boolean shouldScroll) {
2355         if(anObject == null)
2356             setSelectedIndex(-1);
2357         else if(!anObject.equals(getSelectedValue())) {
2358             int i,c;
2359             ListModel<E> dm = getModel();
2360             for(i=0,c=dm.getSize();i<c;i++)


2410      * by {@code visibleRowCount}, if {@code fixedCellHeight} is greater than
2411      * {@code 0}, otherwise it is a hard-coded value of {@code 16} multiplied by
2412      * {@code visibleRowCount}.
2413      * <p>
2414      * If the model isn't empty, the width is the preferred size's width,
2415      * typically the width of the widest list element. The height is the
2416      * {@code fixedCellHeight} multiplied by the {@code visibleRowCount},
2417      * plus the list's vertical insets.
2418      * <p>
2419      * <b>{@code VERTICAL_WRAP} or {@code HORIZONTAL_WRAP}:</b>
2420      * <br>
2421      * This method simply returns the value from {@code getPreferredSize}.
2422      * The list's {@code ListUI} is expected to override {@code getPreferredSize}
2423      * to return an appropriate value.
2424      *
2425      * @return a dimension containing the size of the viewport needed
2426      *          to display {@code visibleRowCount} rows
2427      * @see #getPreferredScrollableViewportSize
2428      * @see #setPrototypeCellValue
2429      */

2430     public Dimension getPreferredScrollableViewportSize()
2431     {
2432         if (getLayoutOrientation() != VERTICAL) {
2433             return getPreferredSize();
2434         }
2435         Insets insets = getInsets();
2436         int dx = insets.left + insets.right;
2437         int dy = insets.top + insets.bottom;
2438 
2439         int visibleRowCount = getVisibleRowCount();
2440         int fixedCellWidth = getFixedCellWidth();
2441         int fixedCellHeight = getFixedCellHeight();
2442 
2443         if ((fixedCellWidth > 0) && (fixedCellHeight > 0)) {
2444             int width = fixedCellWidth + dx;
2445             int height = (visibleRowCount * fixedCellHeight) + dy;
2446             return new Dimension(width, height);
2447         }
2448         else if (getModel().getSize() > 0) {
2449             int width = getPreferredSize().width;


2747             return inc;
2748         }
2749         return visibleRect.width;
2750     }
2751 
2752 
2753     /**
2754      * Returns {@code true} if this {@code JList} is displayed in a
2755      * {@code JViewport} and the viewport is wider than the list's
2756      * preferred width, or if the layout orientation is {@code HORIZONTAL_WRAP}
2757      * and {@code visibleRowCount <= 0}; otherwise returns {@code false}.
2758      * <p>
2759      * If {@code false}, then don't track the viewport's width. This allows
2760      * horizontal scrolling if the {@code JViewport} is itself embedded in a
2761      * {@code JScrollPane}.
2762      *
2763      * @return whether or not an enclosing viewport should force the list's
2764      *         width to match its own
2765      * @see Scrollable#getScrollableTracksViewportWidth
2766      */

2767     public boolean getScrollableTracksViewportWidth() {
2768         if (getLayoutOrientation() == HORIZONTAL_WRAP &&
2769                                       getVisibleRowCount() <= 0) {
2770             return true;
2771         }
2772         Container parent = SwingUtilities.getUnwrappedParent(this);
2773         if (parent instanceof JViewport) {
2774             return parent.getWidth() > getPreferredSize().width;
2775         }
2776         return false;
2777     }
2778 
2779     /**
2780      * Returns {@code true} if this {@code JList} is displayed in a
2781      * {@code JViewport} and the viewport is taller than the list's
2782      * preferred height, or if the layout orientation is {@code VERTICAL_WRAP}
2783      * and {@code visibleRowCount <= 0}; otherwise returns {@code false}.
2784      * <p>
2785      * If {@code false}, then don't track the viewport's height. This allows
2786      * vertical scrolling if the {@code JViewport} is itself embedded in a
2787      * {@code JScrollPane}.
2788      *
2789      * @return whether or not an enclosing viewport should force the list's
2790      *         height to match its own
2791      * @see Scrollable#getScrollableTracksViewportHeight
2792      */

2793     public boolean getScrollableTracksViewportHeight() {
2794         if (getLayoutOrientation() == VERTICAL_WRAP &&
2795                      getVisibleRowCount() <= 0) {
2796             return true;
2797         }
2798         Container parent = SwingUtilities.getUnwrappedParent(this);
2799         if (parent instanceof JViewport) {
2800             return parent.getHeight() > getPreferredSize().height;
2801         }
2802         return false;
2803     }
2804 
2805 
2806     /*
2807      * See {@code readObject} and {@code writeObject} in {@code JComponent}
2808      * for more information about serialization in Swing.
2809      */
2810     private void writeObject(ObjectOutputStream s) throws IOException {
2811         s.defaultWriteObject();
2812         if (getUIClassID().equals(uiClassID)) {


2844         ",selectionForeground=" + selectionForegroundString +
2845         ",visibleRowCount=" + visibleRowCount +
2846         ",layoutOrientation=" + layoutOrientation;
2847     }
2848 
2849 
2850     /**
2851      * --- Accessibility Support ---
2852      */
2853 
2854     /**
2855      * Gets the {@code AccessibleContext} associated with this {@code JList}.
2856      * For {@code JList}, the {@code AccessibleContext} takes the form of an
2857      * {@code AccessibleJList}.
2858      * <p>
2859      * A new {@code AccessibleJList} instance is created if necessary.
2860      *
2861      * @return an {@code AccessibleJList} that serves as the
2862      *         {@code AccessibleContext} of this {@code JList}
2863      */

2864     public AccessibleContext getAccessibleContext() {
2865         if (accessibleContext == null) {
2866             accessibleContext = new AccessibleJList();
2867         }
2868         return accessibleContext;
2869     }
2870 
2871     /**
2872      * This class implements accessibility support for the
2873      * {@code JList} class. It provides an implementation of the
2874      * Java Accessibility API appropriate to list user-interface
2875      * elements.
2876      * <p>
2877      * <strong>Warning:</strong>
2878      * Serialized objects of this class will not be compatible with
2879      * future Swing releases. The current serialization support is
2880      * appropriate for short term storage or RMI between applications running
2881      * the same version of Swing.  As of 1.4, support for long term storage
2882      * of all JavaBeans&trade;
2883      * has been added to the <code>java.beans</code> package.




   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */

  25 package javax.swing;
  26 
  27 import java.awt.*;
  28 import java.awt.event.*;
  29 
  30 import java.util.Vector;
  31 import java.util.Locale;
  32 import java.util.ArrayList;
  33 import java.util.Collections;
  34 import java.util.List;
  35 
  36 import java.beans.JavaBean;
  37 import java.beans.BeanProperty;
  38 import java.beans.PropertyChangeEvent;
  39 import java.beans.PropertyChangeListener;
  40 import java.beans.Transient;
  41 
  42 import javax.swing.event.*;
  43 import javax.accessibility.*;
  44 import javax.swing.plaf.*;
  45 import javax.swing.text.Position;
  46 
  47 import java.io.ObjectOutputStream;

  48 import java.io.IOException;
  49 import java.io.Serializable;
  50 
  51 import sun.swing.SwingUtilities2;
  52 import sun.swing.SwingUtilities2.Section;
  53 import static sun.swing.SwingUtilities2.Section.*;
  54 

  55 /**
  56  * A component that displays a list of objects and allows the user to select
  57  * one or more items. A separate model, {@code ListModel}, maintains the
  58  * contents of the list.
  59  * <p>
  60  * It's easy to display an array or Vector of objects, using the {@code JList}
  61  * constructor that automatically builds a read-only {@code ListModel} instance
  62  * for you:
  63  * <pre>
  64  * {@code
  65  * // Create a JList that displays strings from an array
  66  *
  67  * String[] data = {"one", "two", "three", "four"};
  68  * JList<String> myList = new JList<String>(data);
  69  *
  70  * // Create a JList that displays the superclasses of JList.class, by
  71  * // creating it with a Vector populated with this data
  72  *
  73  * Vector<Class<?>> superClasses = new Vector<Class<?>>();
  74  * Class<JList> rootClass = javax.swing.JList.class;


 253  * appropriate for short term storage or RMI between applications running
 254  * the same version of Swing.  As of 1.4, support for long term storage
 255  * of all JavaBeans&trade;
 256  * has been added to the <code>java.beans</code> package.
 257  * Please see {@link java.beans.XMLEncoder}.
 258  * <p>
 259  * See <a href="http://docs.oracle.com/javase/tutorial/uiswing/components/list.html">How to Use Lists</a>
 260  * in <a href="http://docs.oracle.com/javase/tutorial/"><em>The Java Tutorial</em></a>
 261  * for further documentation.
 262  *
 263  * @see ListModel
 264  * @see AbstractListModel
 265  * @see DefaultListModel
 266  * @see ListSelectionModel
 267  * @see DefaultListSelectionModel
 268  * @see ListCellRenderer
 269  * @see DefaultListCellRenderer
 270  *
 271  * @param <E> the type of the elements of this list
 272  *




 273  * @author Hans Muller
 274  * @since 1.2
 275  */
 276 @JavaBean(defaultProperty = "UI", description = "A component which allows for the selection of one or more objects from a list.")
 277 @SwingContainer(false)
 278 @SuppressWarnings("serial") // Same-version serialization only
 279 public class JList<E> extends JComponent implements Scrollable, Accessible
 280 {
 281     /**
 282      * @see #getUIClassID
 283      * @see #readObject
 284      */
 285     private static final String uiClassID = "ListUI";
 286 
 287     /**
 288      * Indicates a vertical layout of cells, in a single column;
 289      * the default layout.
 290      * @see #setLayoutOrientation
 291      * @since 1.4
 292      */
 293     public static final int VERTICAL = 0;
 294 
 295     /**
 296      * Indicates a "newspaper style" layout with cells flowing vertically
 297      * then horizontally.


 495     }
 496 
 497 
 498     /**
 499      * Returns the {@code ListUI}, the look and feel object that
 500      * renders this component.
 501      *
 502      * @return the <code>ListUI</code> object that renders this component
 503      */
 504     public ListUI getUI() {
 505         return (ListUI)ui;
 506     }
 507 
 508 
 509     /**
 510      * Sets the {@code ListUI}, the look and feel object that
 511      * renders this component.
 512      *
 513      * @param ui  the <code>ListUI</code> object
 514      * @see UIDefaults#getUI





 515      */
 516     @BeanProperty(hidden = true, visualUpdate = true, description
 517             = "The UI object that implements the Component's LookAndFeel.")
 518     public void setUI(ListUI ui) {
 519         super.setUI(ui);
 520     }
 521 
 522 
 523     /**
 524      * Resets the {@code ListUI} property by setting it to the value provided
 525      * by the current look and feel. If the current cell renderer was installed
 526      * by the developer (rather than the look and feel itself), this also causes
 527      * the cell renderer and its children to be updated, by calling
 528      * {@code SwingUtilities.updateComponentTreeUI} on it.
 529      *
 530      * @see UIManager#getUI
 531      * @see SwingUtilities#updateComponentTreeUI
 532      */
 533     public void updateUI() {
 534         setUI((ListUI)UIManager.getUI(this));
 535 
 536         ListCellRenderer<? super E> renderer = getCellRenderer();
 537         if (renderer instanceof Component) {
 538             SwingUtilities.updateComponentTreeUI((Component)renderer);
 539         }
 540     }
 541 
 542 
 543     /**
 544      * Returns {@code "ListUI"}, the <code>UIDefaults</code> key used to look
 545      * up the name of the {@code javax.swing.plaf.ListUI} class that defines
 546      * the look and feel for this component.
 547      *
 548      * @return the string "ListUI"
 549      * @see JComponent#getUIClassID
 550      * @see UIDefaults#getUI
 551      */
 552     @BeanProperty(bound = false)
 553     public String getUIClassID() {
 554         return uiClassID;
 555     }
 556 
 557 
 558     /* -----private-----
 559      * This method is called by setPrototypeCellValue and setCellRenderer
 560      * to update the fixedCellWidth and fixedCellHeight properties from the
 561      * current value of prototypeCellValue (if it's non null).
 562      * <p>
 563      * This method sets fixedCellWidth and fixedCellHeight but does <b>not</b>
 564      * generate PropertyChangeEvents for them.
 565      *
 566      * @see #setPrototypeCellValue
 567      * @see #setCellRenderer
 568      */
 569     private void updateFixedCellSize()
 570     {
 571         ListCellRenderer<? super E> cr = getCellRenderer();
 572         E value = getPrototypeCellValue();


 618      * <p>
 619      * While all three of the {@code prototypeCellValue},
 620      * {@code fixedCellHeight}, and {@code fixedCellWidth} properties may be
 621      * modified by this method, {@code PropertyChangeEvent} notifications are
 622      * only sent when the {@code prototypeCellValue} property changes.
 623      * <p>
 624      * To see an example which sets this property, see the
 625      * <a href="#prototype_example">class description</a> above.
 626      * <p>
 627      * The default value of this property is <code>null</code>.
 628      * <p>
 629      * This is a JavaBeans bound property.
 630      *
 631      * @param prototypeCellValue  the value on which to base
 632      *                          <code>fixedCellWidth</code> and
 633      *                          <code>fixedCellHeight</code>
 634      * @see #getPrototypeCellValue
 635      * @see #setFixedCellWidth
 636      * @see #setFixedCellHeight
 637      * @see JComponent#addPropertyChangeListener




 638      */
 639     @BeanProperty(visualUpdate = true, description
 640             = "The cell prototype value, used to compute cell width and height.")
 641     public void setPrototypeCellValue(E prototypeCellValue) {
 642         E oldValue = this.prototypeCellValue;
 643         this.prototypeCellValue = prototypeCellValue;
 644 
 645         /* If the prototypeCellValue has changed and is non-null,
 646          * then recompute fixedCellWidth and fixedCellHeight.
 647          */
 648 
 649         if ((prototypeCellValue != null) && !prototypeCellValue.equals(oldValue)) {
 650             updateFixedCellSize();
 651         }
 652 
 653         firePropertyChange("prototypeCellValue", oldValue, prototypeCellValue);
 654     }
 655 
 656 
 657     /**
 658      * Returns the value of the {@code fixedCellWidth} property.
 659      *
 660      * @return the fixed cell width
 661      * @see #setFixedCellWidth
 662      */
 663     public int getFixedCellWidth() {
 664         return fixedCellWidth;
 665     }
 666 
 667     /**
 668      * Sets a fixed value to be used for the width of every cell in the list.
 669      * If {@code width} is -1, cell widths are computed in the {@code ListUI}
 670      * by applying <code>getPreferredSize</code> to the cell renderer component
 671      * for each list element.
 672      * <p>
 673      * The default value of this property is {@code -1}.
 674      * <p>
 675      * This is a JavaBeans bound property.
 676      *
 677      * @param width the width to be used for all cells in the list
 678      * @see #setPrototypeCellValue
 679      * @see #setFixedCellWidth
 680      * @see JComponent#addPropertyChangeListener




 681      */
 682     @BeanProperty(visualUpdate = true, description
 683             = "Defines a fixed cell width when greater than zero.")
 684     public void setFixedCellWidth(int width) {
 685         int oldValue = fixedCellWidth;
 686         fixedCellWidth = width;
 687         firePropertyChange("fixedCellWidth", oldValue, fixedCellWidth);
 688     }
 689 
 690 
 691     /**
 692      * Returns the value of the {@code fixedCellHeight} property.
 693      *
 694      * @return the fixed cell height
 695      * @see #setFixedCellHeight
 696      */
 697     public int getFixedCellHeight() {
 698         return fixedCellHeight;
 699     }
 700 
 701     /**
 702      * Sets a fixed value to be used for the height of every cell in the list.
 703      * If {@code height} is -1, cell heights are computed in the {@code ListUI}
 704      * by applying <code>getPreferredSize</code> to the cell renderer component
 705      * for each list element.
 706      * <p>
 707      * The default value of this property is {@code -1}.
 708      * <p>
 709      * This is a JavaBeans bound property.
 710      *
 711      * @param height the height to be used for all cells in the list
 712      * @see #setPrototypeCellValue
 713      * @see #setFixedCellWidth
 714      * @see JComponent#addPropertyChangeListener




 715      */
 716     @BeanProperty(visualUpdate = true, description
 717             = "Defines a fixed cell height when greater than zero.")
 718     public void setFixedCellHeight(int height) {
 719         int oldValue = fixedCellHeight;
 720         fixedCellHeight = height;
 721         firePropertyChange("fixedCellHeight", oldValue, fixedCellHeight);
 722     }
 723 
 724 
 725     /**
 726      * Returns the object responsible for painting list items.
 727      *
 728      * @return the value of the {@code cellRenderer} property
 729      * @see #setCellRenderer
 730      */
 731     @Transient
 732     public ListCellRenderer<? super E> getCellRenderer() {
 733         return cellRenderer;
 734     }
 735 
 736     /**
 737      * Sets the delegate that is used to paint each cell in the list.
 738      * The job of a cell renderer is discussed in detail in the
 739      * <a href="#renderer">class level documentation</a>.
 740      * <p>
 741      * If the {@code prototypeCellValue} property is {@code non-null},
 742      * setting the cell renderer also causes the {@code fixedCellWidth} and
 743      * {@code fixedCellHeight} properties to be re-calculated. Only one
 744      * <code>PropertyChangeEvent</code> is generated however -
 745      * for the <code>cellRenderer</code> property.
 746      * <p>
 747      * The default value of this property is provided by the {@code ListUI}
 748      * delegate, i.e. by the look and feel implementation.
 749      * <p>
 750      * This is a JavaBeans bound property.
 751      *
 752      * @param cellRenderer the <code>ListCellRenderer</code>
 753      *                          that paints list cells
 754      * @see #getCellRenderer




 755      */
 756     @BeanProperty(visualUpdate = true, description
 757             = "The component used to draw the cells.")
 758     public void setCellRenderer(ListCellRenderer<? super E> cellRenderer) {
 759         ListCellRenderer<? super E> oldValue = this.cellRenderer;
 760         this.cellRenderer = cellRenderer;
 761 
 762         /* If the cellRenderer has changed and prototypeCellValue
 763          * was set, then recompute fixedCellWidth and fixedCellHeight.
 764          */
 765         if ((cellRenderer != null) && !cellRenderer.equals(oldValue)) {
 766             updateFixedCellSize();
 767         }
 768 
 769         firePropertyChange("cellRenderer", oldValue, cellRenderer);
 770     }
 771 
 772 
 773     /**
 774      * Returns the color used to draw the foreground of selected items.
 775      * {@code DefaultListCellRenderer} uses this color to draw the foreground
 776      * of items in the selected state, as do the renderers installed by most
 777      * {@code ListUI} implementations.


 788     /**
 789      * Sets the color used to draw the foreground of selected items, which
 790      * cell renderers can use to render text and graphics.
 791      * {@code DefaultListCellRenderer} uses this color to draw the foreground
 792      * of items in the selected state, as do the renderers installed by most
 793      * {@code ListUI} implementations.
 794      * <p>
 795      * The default value of this property is defined by the look and feel
 796      * implementation.
 797      * <p>
 798      * This is a JavaBeans bound property.
 799      *
 800      * @param selectionForeground  the {@code Color} to use in the foreground
 801      *                             for selected list items
 802      * @see #getSelectionForeground
 803      * @see #setSelectionBackground
 804      * @see #setForeground
 805      * @see #setBackground
 806      * @see #setFont
 807      * @see DefaultListCellRenderer




 808      */
 809     @BeanProperty(visualUpdate = true, description
 810             = "The foreground color of selected cells.")
 811     public void setSelectionForeground(Color selectionForeground) {
 812         Color oldValue = this.selectionForeground;
 813         this.selectionForeground = selectionForeground;
 814         firePropertyChange("selectionForeground", oldValue, selectionForeground);
 815     }
 816 
 817 
 818     /**
 819      * Returns the color used to draw the background of selected items.
 820      * {@code DefaultListCellRenderer} uses this color to draw the background
 821      * of items in the selected state, as do the renderers installed by most
 822      * {@code ListUI} implementations.
 823      *
 824      * @return the color to draw the background of selected items
 825      * @see #setSelectionBackground
 826      * @see DefaultListCellRenderer
 827      */
 828     public Color getSelectionBackground() {
 829         return selectionBackground;
 830     }


 833     /**
 834      * Sets the color used to draw the background of selected items, which
 835      * cell renderers can use fill selected cells.
 836      * {@code DefaultListCellRenderer} uses this color to fill the background
 837      * of items in the selected state, as do the renderers installed by most
 838      * {@code ListUI} implementations.
 839      * <p>
 840      * The default value of this property is defined by the look
 841      * and feel implementation.
 842      * <p>
 843      * This is a JavaBeans bound property.
 844      *
 845      * @param selectionBackground  the {@code Color} to use for the
 846      *                             background of selected cells
 847      * @see #getSelectionBackground
 848      * @see #setSelectionForeground
 849      * @see #setForeground
 850      * @see #setBackground
 851      * @see #setFont
 852      * @see DefaultListCellRenderer




 853      */
 854     @BeanProperty(visualUpdate = true, description
 855             = "The background color of selected cells.")
 856     public void setSelectionBackground(Color selectionBackground) {
 857         Color oldValue = this.selectionBackground;
 858         this.selectionBackground = selectionBackground;
 859         firePropertyChange("selectionBackground", oldValue, selectionBackground);
 860     }
 861 
 862 
 863     /**
 864      * Returns the value of the {@code visibleRowCount} property. See the
 865      * documentation for {@link #setVisibleRowCount} for details on how to
 866      * interpret this value.
 867      *
 868      * @return the value of the {@code visibleRowCount} property.
 869      * @see #setVisibleRowCount
 870      */
 871     public int getVisibleRowCount() {
 872         return visibleRowCount;
 873     }
 874 
 875     /**


 886      * documentation for more details.
 887      * <p>
 888      * In {@code HORIZONTAL_WRAP} and {@code VERTICAL_WRAP} orientations:<br>
 889      * This affects how cells are wrapped. See the documentation of
 890      * {@link #setLayoutOrientation} for more details.
 891      * <p>
 892      * The default value of this property is {@code 8}.
 893      * <p>
 894      * Calling this method with a negative value results in the property
 895      * being set to {@code 0}.
 896      * <p>
 897      * This is a JavaBeans bound property.
 898      *
 899      * @param visibleRowCount  an integer specifying the preferred number of
 900      *                         rows to display without requiring scrolling
 901      * @see #getVisibleRowCount
 902      * @see #getPreferredScrollableViewportSize
 903      * @see #setLayoutOrientation
 904      * @see JComponent#getVisibleRect
 905      * @see JViewport





 906      */
 907     @BeanProperty(visualUpdate = true, description
 908             = "The preferred number of rows to display without requiring scrolling")
 909     public void setVisibleRowCount(int visibleRowCount) {
 910         int oldValue = this.visibleRowCount;
 911         this.visibleRowCount = Math.max(0, visibleRowCount);
 912         firePropertyChange("visibleRowCount", oldValue, visibleRowCount);
 913     }
 914 
 915 
 916     /**
 917      * Returns the layout orientation property for the list: {@code VERTICAL}
 918      * if the layout is a single column of cells, {@code VERTICAL_WRAP} if the
 919      * layout is "newspaper style" with the content flowing vertically then
 920      * horizontally, or {@code HORIZONTAL_WRAP} if the layout is "newspaper
 921      * style" with the content flowing horizontally then vertically.
 922      *
 923      * @return the value of the {@code layoutOrientation} property
 924      * @see #setLayoutOrientation
 925      * @since 1.4
 926      */
 927     public int getLayoutOrientation() {
 928         return layoutOrientation;


 962      *           list; otherwise wrapping is done in such a way as to ensure
 963      *           {@code visibleRowCount} rows in the list.
 964      *   <tr><td><code>VERTICAL_WRAP</code>
 965      *       <td>Cells are layed out vertically, wrapping to a new column as
 966      *           necessary. If the {@code visibleRowCount} property is less than
 967      *           or equal to zero, wrapping is determined by the height of the
 968      *           list; otherwise wrapping is done at {@code visibleRowCount} rows.
 969      *  </table>
 970      * <p>
 971      * The default value of this property is <code>VERTICAL</code>.
 972      *
 973      * @param layoutOrientation the new layout orientation, one of:
 974      *        {@code VERTICAL}, {@code HORIZONTAL_WRAP} or {@code VERTICAL_WRAP}
 975      * @see #getLayoutOrientation
 976      * @see #setVisibleRowCount
 977      * @see #getScrollableTracksViewportHeight
 978      * @see #getScrollableTracksViewportWidth
 979      * @throws IllegalArgumentException if {@code layoutOrientation} isn't one of the
 980      *         allowable values
 981      * @since 1.4







 982      */
 983     @BeanProperty(visualUpdate = true, enumerationValues = {
 984             "JList.VERTICAL",
 985             "JList.HORIZONTAL_WRAP",
 986             "JList.VERTICAL_WRAP"}, description
 987             = "Defines the way list cells are layed out.")
 988     public void setLayoutOrientation(int layoutOrientation) {
 989         int oldValue = this.layoutOrientation;
 990         switch (layoutOrientation) {
 991         case VERTICAL:
 992         case VERTICAL_WRAP:
 993         case HORIZONTAL_WRAP:
 994             this.layoutOrientation = layoutOrientation;
 995             firePropertyChange("layoutOrientation", oldValue, layoutOrientation);
 996             break;
 997         default:
 998             throw new IllegalArgumentException("layoutOrientation must be one of: VERTICAL, HORIZONTAL_WRAP or VERTICAL_WRAP");
 999         }
1000     }
1001 
1002 
1003     /**
1004      * Returns the smallest list index that is currently visible.
1005      * In a left-to-right {@code componentOrientation}, the first visible
1006      * cell is found closest to the list's upper-left corner. In right-to-left
1007      * orientation, it is found closest to the upper-right corner.
1008      * If nothing is visible or the list is empty, {@code -1} is returned.
1009      * Note that the returned cell may only be partially visible.
1010      *
1011      * @return the index of the first visible cell
1012      * @see #getLastVisibleIndex
1013      * @see JComponent#getVisibleRect
1014      */
1015     @BeanProperty(bound = false)
1016     public int getFirstVisibleIndex() {
1017         Rectangle r = getVisibleRect();
1018         int first;
1019         if (this.getComponentOrientation().isLeftToRight()) {
1020             first = locationToIndex(r.getLocation());
1021         } else {
1022             first = locationToIndex(new Point((r.x + r.width) - 1, r.y));
1023         }
1024         if (first != -1) {
1025             Rectangle bounds = getCellBounds(first, first);
1026             if (bounds != null) {
1027                 SwingUtilities.computeIntersection(r.x, r.y, r.width, r.height, bounds);
1028                 if (bounds.width == 0 || bounds.height == 0) {
1029                     first = -1;
1030                 }
1031             }
1032         }
1033         return first;
1034     }
1035 
1036 
1037     /**
1038      * Returns the largest list index that is currently visible.
1039      * If nothing is visible or the list is empty, {@code -1} is returned.
1040      * Note that the returned cell may only be partially visible.
1041      *
1042      * @return the index of the last visible cell
1043      * @see #getFirstVisibleIndex
1044      * @see JComponent#getVisibleRect
1045      */
1046     @BeanProperty(bound = false)
1047     public int getLastVisibleIndex() {
1048         boolean leftToRight = this.getComponentOrientation().isLeftToRight();
1049         Rectangle r = getVisibleRect();
1050         Point lastPoint;
1051         if (leftToRight) {
1052             lastPoint = new Point((r.x + r.width) - 1, (r.y + r.height) - 1);
1053         } else {
1054             lastPoint = new Point(r.x, (r.y + r.height) - 1);
1055         }
1056         int location = locationToIndex(lastPoint);
1057 
1058         if (location != -1) {
1059             Rectangle bounds = getCellBounds(location, location);
1060 
1061             if (bounds != null) {
1062                 SwingUtilities.computeIntersection(r.x, r.y, r.width, r.height, bounds);
1063                 if (bounds.width == 0 || bounds.height == 0) {
1064                     // Try the top left(LTR) or top right(RTL) corner, and
1065                     // then go across checking each cell for HORIZONTAL_WRAP.
1066                     // Try the lower left corner, and then go across checking


1143      * {@code ListUI}. When automatic drag handling is enabled, most look and
1144      * feels (including those that subclass {@code BasicLookAndFeel}) begin a
1145      * drag and drop operation whenever the user presses the mouse button over
1146      * an item and then moves the mouse a few pixels. Setting this property to
1147      * {@code true} can therefore have a subtle effect on how selections behave.
1148      * <p>
1149      * If a look and feel is used that ignores this property, you can still
1150      * begin a drag and drop operation by calling {@code exportAsDrag} on the
1151      * list's {@code TransferHandler}.
1152      *
1153      * @param b whether or not to enable automatic drag handling
1154      * @exception HeadlessException if
1155      *            <code>b</code> is <code>true</code> and
1156      *            <code>GraphicsEnvironment.isHeadless()</code>
1157      *            returns <code>true</code>
1158      * @see java.awt.GraphicsEnvironment#isHeadless
1159      * @see #getDragEnabled
1160      * @see #setTransferHandler
1161      * @see TransferHandler
1162      * @since 1.4




1163      */
1164     @BeanProperty(bound = false, description
1165             = "determines whether automatic drag handling is enabled")
1166     public void setDragEnabled(boolean b) {
1167         if (b && GraphicsEnvironment.isHeadless()) {
1168             throw new HeadlessException();
1169         }
1170         dragEnabled = b;
1171     }
1172 
1173     /**
1174      * Returns whether or not automatic drag handling is enabled.
1175      *
1176      * @return the value of the {@code dragEnabled} property
1177      * @see #setDragEnabled
1178      * @since 1.4
1179      */
1180     public boolean getDragEnabled() {
1181         return dragEnabled;
1182     }
1183 
1184     /**
1185      * Sets the drop mode for this component. For backward compatibility,


1410      * This method is not meant for querying the drop location
1411      * from a {@code TransferHandler}, as the drop location is only
1412      * set after the {@code TransferHandler}'s <code>canImport</code>
1413      * has returned and has allowed for the location to be shown.
1414      * <p>
1415      * When this property changes, a property change event with
1416      * name "dropLocation" is fired by the component.
1417      * <p>
1418      * By default, responsibility for listening for changes to this property
1419      * and indicating the drop location visually lies with the list's
1420      * {@code ListUI}, which may paint it directly and/or install a cell
1421      * renderer to do so. Developers wishing to implement custom drop location
1422      * painting and/or replace the default cell renderer, may need to honor
1423      * this property.
1424      *
1425      * @return the drop location
1426      * @see #setDropMode
1427      * @see TransferHandler#canImport(TransferHandler.TransferSupport)
1428      * @since 1.6
1429      */
1430     @BeanProperty(bound = false)
1431     public final DropLocation getDropLocation() {
1432         return dropLocation;
1433     }
1434 
1435     /**
1436      * Returns the next list element whose {@code toString} value
1437      * starts with the given prefix.
1438      *
1439      * @param prefix the string to test for a match
1440      * @param startIndex the index for starting the search
1441      * @param bias the search direction, either
1442      * Position.Bias.Forward or Position.Bias.Backward.
1443      * @return the index of the next list element that
1444      * starts with the prefix; otherwise {@code -1}
1445      * @exception IllegalArgumentException if prefix is {@code null}
1446      * or startIndex is out of bounds
1447      * @since 1.4
1448      */
1449     public int getNextMatch(String prefix, int startIndex, Position.Bias bias) {
1450         ListModel<E> model = getModel();


1626      *                          list of items
1627      * @see #setModel
1628      */
1629     public ListModel<E> getModel() {
1630         return dataModel;
1631     }
1632 
1633     /**
1634      * Sets the model that represents the contents or "value" of the
1635      * list, notifies property change listeners, and then clears the
1636      * list's selection.
1637      * <p>
1638      * This is a JavaBeans bound property.
1639      *
1640      * @param model  the <code>ListModel</code> that provides the
1641      *                                          list of items for display
1642      * @exception IllegalArgumentException  if <code>model</code> is
1643      *                                          <code>null</code>
1644      * @see #getModel
1645      * @see #clearSelection




1646      */
1647     @BeanProperty(visualUpdate = true, description
1648             = "The object that contains the data to be drawn by this JList.")
1649     public void setModel(ListModel<E> model) {
1650         if (model == null) {
1651             throw new IllegalArgumentException("model must be non null");
1652         }
1653         ListModel<E> oldValue = dataModel;
1654         dataModel = model;
1655         firePropertyChange("model", oldValue, dataModel);
1656         clearSelection();
1657     }
1658 
1659 
1660     /**
1661      * Constructs a read-only <code>ListModel</code> from an array of items,
1662      * and calls {@code setModel} with this model.
1663      * <p>
1664      * Attempts to pass a {@code null} value to this method results in
1665      * undefined behavior and, most likely, exceptions. The created model
1666      * references the given array directly. Attempts to modify the array
1667      * after invoking this method results in undefined behavior.
1668      *


1820      * Removes a selection listener from the list.
1821      *
1822      * @param listener the {@code ListSelectionListener} to remove
1823      * @see #addListSelectionListener
1824      * @see #getSelectionModel
1825      */
1826     public void removeListSelectionListener(ListSelectionListener listener) {
1827         listenerList.remove(ListSelectionListener.class, listener);
1828     }
1829 
1830 
1831     /**
1832      * Returns an array of all the {@code ListSelectionListener}s added
1833      * to this {@code JList} by way of {@code addListSelectionListener}.
1834      *
1835      * @return all of the {@code ListSelectionListener}s on this list, or
1836      *         an empty array if no listeners have been added
1837      * @see #addListSelectionListener
1838      * @since 1.4
1839      */
1840     @BeanProperty(bound = false)
1841     public ListSelectionListener[] getListSelectionListeners() {
1842         return listenerList.getListeners(ListSelectionListener.class);
1843     }
1844 
1845 
1846     /**
1847      * Sets the <code>selectionModel</code> for the list to a
1848      * non-<code>null</code> <code>ListSelectionModel</code>
1849      * implementation. The selection model handles the task of making single
1850      * selections, selections of contiguous ranges, and non-contiguous
1851      * selections.
1852      * <p>
1853      * This is a JavaBeans bound property.
1854      *
1855      * @param selectionModel  the <code>ListSelectionModel</code> that
1856      *                          implements the selections
1857      * @exception IllegalArgumentException   if <code>selectionModel</code>
1858      *                                          is <code>null</code>
1859      * @see #getSelectionModel



1860      */
1861     @BeanProperty(description
1862             = "The selection model, recording which cells are selected.")
1863     public void setSelectionModel(ListSelectionModel selectionModel) {
1864         if (selectionModel == null) {
1865             throw new IllegalArgumentException("selectionModel must be non null");
1866         }
1867 
1868         /* Remove the forwarding ListSelectionListener from the old
1869          * selectionModel, and add it to the new one, if necessary.
1870          */
1871         if (selectionListener != null) {
1872             this.selectionModel.removeListSelectionListener(selectionListener);
1873             selectionModel.addListSelectionListener(selectionListener);
1874         }
1875 
1876         ListSelectionModel oldValue = this.selectionModel;
1877         this.selectionModel = selectionModel;
1878         firePropertyChange("selectionModel", oldValue, selectionModel);
1879     }
1880 
1881 
1882     /**


1888      * <li>{@code ListSelectionModel.SINGLE_SELECTION} -
1889      *   Only one list index can be selected at a time. In this mode,
1890      *   {@code setSelectionInterval} and {@code addSelectionInterval} are
1891      *   equivalent, both replacing the current selection with the index
1892      *   represented by the second argument (the "lead").
1893      * <li>{@code ListSelectionModel.SINGLE_INTERVAL_SELECTION} -
1894      *   Only one contiguous interval can be selected at a time.
1895      *   In this mode, {@code addSelectionInterval} behaves like
1896      *   {@code setSelectionInterval} (replacing the current selection},
1897      *   unless the given interval is immediately adjacent to or overlaps
1898      *   the existing selection, and can be used to grow the selection.
1899      * <li>{@code ListSelectionModel.MULTIPLE_INTERVAL_SELECTION} -
1900      *   In this mode, there's no restriction on what can be selected.
1901      *   This mode is the default.
1902      * </ul>
1903      *
1904      * @param selectionMode the selection mode
1905      * @see #getSelectionMode
1906      * @throws IllegalArgumentException if the selection mode isn't
1907      *         one of those allowed





1908      */
1909     @BeanProperty(bound = false, enumerationValues = {
1910             "ListSelectionModel.SINGLE_SELECTION",
1911             "ListSelectionModel.SINGLE_INTERVAL_SELECTION",
1912             "ListSelectionModel.MULTIPLE_INTERVAL_SELECTION"}, description
1913             = "The selection mode.")
1914     public void setSelectionMode(int selectionMode) {
1915         getSelectionModel().setSelectionMode(selectionMode);
1916     }
1917 
1918     /**
1919      * Returns the current selection mode for the list. This is a cover
1920      * method that delegates to the method of the same name on the
1921      * list's selection model.
1922      *
1923      * @return the current selection mode
1924      * @see #setSelectionMode
1925      */
1926     public int getSelectionMode() {
1927         return getSelectionModel().getSelectionMode();
1928     }
1929 
1930 
1931     /**
1932      * Returns the anchor selection index. This is a cover method that
1933      * delegates to the method of the same name on the list's selection model.
1934      *
1935      * @return the anchor selection index
1936      * @see ListSelectionModel#getAnchorSelectionIndex
1937      */
1938     @BeanProperty(bound = false)
1939     public int getAnchorSelectionIndex() {
1940         return getSelectionModel().getAnchorSelectionIndex();
1941     }
1942 
1943 
1944     /**
1945      * Returns the lead selection index. This is a cover method that
1946      * delegates to the method of the same name on the list's selection model.
1947      *
1948      * @return the lead selection index
1949      * @see ListSelectionModel#getLeadSelectionIndex


1950      */
1951     @BeanProperty(bound = false, description
1952             = "The lead selection index.")
1953     public int getLeadSelectionIndex() {
1954         return getSelectionModel().getLeadSelectionIndex();
1955     }
1956 
1957 
1958     /**
1959      * Returns the smallest selected cell index, or {@code -1} if the selection
1960      * is empty. This is a cover method that delegates to the method of the same
1961      * name on the list's selection model.
1962      *
1963      * @return the smallest selected cell index, or {@code -1}
1964      * @see ListSelectionModel#getMinSelectionIndex
1965      */
1966     @BeanProperty(bound = false)
1967     public int getMinSelectionIndex() {
1968         return getSelectionModel().getMinSelectionIndex();
1969     }
1970 
1971 
1972     /**
1973      * Returns the largest selected cell index, or {@code -1} if the selection
1974      * is empty. This is a cover method that delegates to the method of the same
1975      * name on the list's selection model.
1976      *
1977      * @return the largest selected cell index
1978      * @see ListSelectionModel#getMaxSelectionIndex
1979      */
1980     @BeanProperty(bound = false)
1981     public int getMaxSelectionIndex() {
1982         return getSelectionModel().getMaxSelectionIndex();
1983     }
1984 
1985 
1986     /**
1987      * Returns {@code true} if the specified index is selected,
1988      * else {@code false}. This is a cover method that delegates to the method
1989      * of the same name on the list's selection model.
1990      *
1991      * @param index index to be queried for selection state
1992      * @return {@code true} if the specified index is selected,
1993      *         else {@code false}
1994      * @see ListSelectionModel#isSelectedIndex
1995      * @see #setSelectedIndex
1996      */
1997     public boolean isSelectedIndex(int index) {
1998         return getSelectionModel().isSelectedIndex(index);
1999     }
2000 
2001 
2002     /**
2003      * Returns {@code true} if nothing is selected, else {@code false}.
2004      * This is a cover method that delegates to the method of the same
2005      * name on the list's selection model.
2006      *
2007      * @return {@code true} if nothing is selected, else {@code false}
2008      * @see ListSelectionModel#isSelectionEmpty
2009      * @see #clearSelection
2010      */
2011     @BeanProperty(bound = false)
2012     public boolean isSelectionEmpty() {
2013         return getSelectionModel().isSelectionEmpty();
2014     }
2015 
2016 
2017     /**
2018      * Clears the selection; after calling this method, {@code isSelectionEmpty}
2019      * will return {@code true}. This is a cover method that delegates to the
2020      * method of the same name on the list's selection model.
2021      *
2022      * @see ListSelectionModel#clearSelection
2023      * @see #isSelectionEmpty
2024      */
2025     public void clearSelection() {
2026         getSelectionModel().clearSelection();
2027     }
2028 
2029 
2030     /**
2031      * Selects the specified interval. Both {@code anchor} and {@code lead}


2166                 rvTmp[n++] = i;
2167             }
2168         }
2169         int[] rv = new int[n];
2170         System.arraycopy(rvTmp, 0, rv, 0, n);
2171         return rv;
2172     }
2173 
2174 
2175     /**
2176      * Selects a single cell. Does nothing if the given index is greater
2177      * than or equal to the model size. This is a convenience method that uses
2178      * {@code setSelectionInterval} on the selection model. Refer to the
2179      * documentation for the selection model class being used for details on
2180      * how values less than {@code 0} are handled.
2181      *
2182      * @param index the index of the cell to select
2183      * @see ListSelectionModel#setSelectionInterval
2184      * @see #isSelectedIndex
2185      * @see #addListSelectionListener


2186      */
2187     @BeanProperty(bound = false, description
2188             = "The index of the selected cell.")
2189     public void setSelectedIndex(int index) {
2190         if (index >= getModel().getSize()) {
2191             return;
2192         }
2193         getSelectionModel().setSelectionInterval(index, index);
2194     }
2195 
2196 
2197     /**
2198      * Changes the selection to be the set of indices specified by the given
2199      * array. Indices greater than or equal to the model size are ignored.
2200      * This is a convenience method that clears the selection and then uses
2201      * {@code addSelectionInterval} on the selection model to add the indices.
2202      * Refer to the documentation of the selection model class being used for
2203      * details on how values less than {@code 0} are handled.
2204      *
2205      * @param indices an array of the indices of the cells to select,
2206      *                {@code non-null}
2207      * @see ListSelectionModel#addSelectionInterval
2208      * @see #isSelectedIndex


2216         for (int i : indices) {
2217             if (i < size) {
2218                 sm.addSelectionInterval(i, i);
2219             }
2220         }
2221     }
2222 
2223 
2224     /**
2225      * Returns an array of all the selected values, in increasing order based
2226      * on their indices in the list.
2227      *
2228      * @return the selected values, or an empty array if nothing is selected
2229      * @see #isSelectedIndex
2230      * @see #getModel
2231      * @see #addListSelectionListener
2232      *
2233      * @deprecated As of JDK 1.7, replaced by {@link #getSelectedValuesList()}
2234      */
2235     @Deprecated
2236     @BeanProperty(bound = false)
2237     public Object[] getSelectedValues() {
2238         ListSelectionModel sm = getSelectionModel();
2239         ListModel<E> dm = getModel();
2240 
2241         int iMin = sm.getMinSelectionIndex();
2242         int iMax = sm.getMaxSelectionIndex();
2243 
2244         if ((iMin < 0) || (iMax < 0)) {
2245             return new Object[0];
2246         }
2247 
2248         Object[] rvTmp = new Object[1+ (iMax - iMin)];
2249         int n = 0;
2250         for(int i = iMin; i <= iMax; i++) {
2251             if (sm.isSelectedIndex(i)) {
2252                 rvTmp[n++] = dm.getElementAt(i);
2253             }
2254         }
2255         Object[] rv = new Object[n];
2256         System.arraycopy(rvTmp, 0, rv, 0, n);
2257         return rv;
2258     }
2259 
2260     /**
2261      * Returns a list of all the selected items, in increasing order based
2262      * on their indices in the list.
2263      *
2264      * @return the selected items, or an empty list if nothing is selected
2265      * @see #isSelectedIndex
2266      * @see #getModel
2267      * @see #addListSelectionListener
2268      *
2269      * @since 1.7
2270      */
2271     @BeanProperty(bound = false)
2272     public List<E> getSelectedValuesList() {
2273         ListSelectionModel sm = getSelectionModel();
2274         ListModel<E> dm = getModel();
2275 
2276         int iMin = sm.getMinSelectionIndex();
2277         int iMax = sm.getMaxSelectionIndex();
2278 
2279         if ((iMin < 0) || (iMax < 0)) {
2280             return Collections.emptyList();
2281         }
2282 
2283         List<E> selectedItems = new ArrayList<E>();
2284         for(int i = iMin; i <= iMax; i++) {
2285             if (sm.isSelectedIndex(i)) {
2286                 selectedItems.add(dm.getElementAt(i));
2287             }
2288         }
2289         return selectedItems;
2290     }
2291 


2304      */
2305     public int getSelectedIndex() {
2306         return getMinSelectionIndex();
2307     }
2308 
2309 
2310     /**
2311      * Returns the value for the smallest selected cell index;
2312      * <i>the selected value</i> when only a single item is selected in the
2313      * list. When multiple items are selected, it is simply the value for the
2314      * smallest selected index. Returns {@code null} if there is no selection.
2315      * <p>
2316      * This is a convenience method that simply returns the model value for
2317      * {@code getMinSelectionIndex}.
2318      *
2319      * @return the first selected value
2320      * @see #getMinSelectionIndex
2321      * @see #getModel
2322      * @see #addListSelectionListener
2323      */
2324     @BeanProperty(bound = false)
2325     public E getSelectedValue() {
2326         int i = getMinSelectionIndex();
2327         return (i == -1) ? null : getModel().getElementAt(i);
2328     }
2329 
2330 
2331     /**
2332      * Selects the specified object from the list.
2333      *
2334      * @param anObject      the object to select
2335      * @param shouldScroll  {@code true} if the list should scroll to display
2336      *                      the selected object, if one exists; otherwise {@code false}
2337      */
2338     public void setSelectedValue(Object anObject,boolean shouldScroll) {
2339         if(anObject == null)
2340             setSelectedIndex(-1);
2341         else if(!anObject.equals(getSelectedValue())) {
2342             int i,c;
2343             ListModel<E> dm = getModel();
2344             for(i=0,c=dm.getSize();i<c;i++)


2394      * by {@code visibleRowCount}, if {@code fixedCellHeight} is greater than
2395      * {@code 0}, otherwise it is a hard-coded value of {@code 16} multiplied by
2396      * {@code visibleRowCount}.
2397      * <p>
2398      * If the model isn't empty, the width is the preferred size's width,
2399      * typically the width of the widest list element. The height is the
2400      * {@code fixedCellHeight} multiplied by the {@code visibleRowCount},
2401      * plus the list's vertical insets.
2402      * <p>
2403      * <b>{@code VERTICAL_WRAP} or {@code HORIZONTAL_WRAP}:</b>
2404      * <br>
2405      * This method simply returns the value from {@code getPreferredSize}.
2406      * The list's {@code ListUI} is expected to override {@code getPreferredSize}
2407      * to return an appropriate value.
2408      *
2409      * @return a dimension containing the size of the viewport needed
2410      *          to display {@code visibleRowCount} rows
2411      * @see #getPreferredScrollableViewportSize
2412      * @see #setPrototypeCellValue
2413      */
2414     @BeanProperty(bound = false)
2415     public Dimension getPreferredScrollableViewportSize()
2416     {
2417         if (getLayoutOrientation() != VERTICAL) {
2418             return getPreferredSize();
2419         }
2420         Insets insets = getInsets();
2421         int dx = insets.left + insets.right;
2422         int dy = insets.top + insets.bottom;
2423 
2424         int visibleRowCount = getVisibleRowCount();
2425         int fixedCellWidth = getFixedCellWidth();
2426         int fixedCellHeight = getFixedCellHeight();
2427 
2428         if ((fixedCellWidth > 0) && (fixedCellHeight > 0)) {
2429             int width = fixedCellWidth + dx;
2430             int height = (visibleRowCount * fixedCellHeight) + dy;
2431             return new Dimension(width, height);
2432         }
2433         else if (getModel().getSize() > 0) {
2434             int width = getPreferredSize().width;


2732             return inc;
2733         }
2734         return visibleRect.width;
2735     }
2736 
2737 
2738     /**
2739      * Returns {@code true} if this {@code JList} is displayed in a
2740      * {@code JViewport} and the viewport is wider than the list's
2741      * preferred width, or if the layout orientation is {@code HORIZONTAL_WRAP}
2742      * and {@code visibleRowCount <= 0}; otherwise returns {@code false}.
2743      * <p>
2744      * If {@code false}, then don't track the viewport's width. This allows
2745      * horizontal scrolling if the {@code JViewport} is itself embedded in a
2746      * {@code JScrollPane}.
2747      *
2748      * @return whether or not an enclosing viewport should force the list's
2749      *         width to match its own
2750      * @see Scrollable#getScrollableTracksViewportWidth
2751      */
2752     @BeanProperty(bound = false)
2753     public boolean getScrollableTracksViewportWidth() {
2754         if (getLayoutOrientation() == HORIZONTAL_WRAP &&
2755                                       getVisibleRowCount() <= 0) {
2756             return true;
2757         }
2758         Container parent = SwingUtilities.getUnwrappedParent(this);
2759         if (parent instanceof JViewport) {
2760             return parent.getWidth() > getPreferredSize().width;
2761         }
2762         return false;
2763     }
2764 
2765     /**
2766      * Returns {@code true} if this {@code JList} is displayed in a
2767      * {@code JViewport} and the viewport is taller than the list's
2768      * preferred height, or if the layout orientation is {@code VERTICAL_WRAP}
2769      * and {@code visibleRowCount <= 0}; otherwise returns {@code false}.
2770      * <p>
2771      * If {@code false}, then don't track the viewport's height. This allows
2772      * vertical scrolling if the {@code JViewport} is itself embedded in a
2773      * {@code JScrollPane}.
2774      *
2775      * @return whether or not an enclosing viewport should force the list's
2776      *         height to match its own
2777      * @see Scrollable#getScrollableTracksViewportHeight
2778      */
2779     @BeanProperty(bound = false)
2780     public boolean getScrollableTracksViewportHeight() {
2781         if (getLayoutOrientation() == VERTICAL_WRAP &&
2782                      getVisibleRowCount() <= 0) {
2783             return true;
2784         }
2785         Container parent = SwingUtilities.getUnwrappedParent(this);
2786         if (parent instanceof JViewport) {
2787             return parent.getHeight() > getPreferredSize().height;
2788         }
2789         return false;
2790     }
2791 
2792 
2793     /*
2794      * See {@code readObject} and {@code writeObject} in {@code JComponent}
2795      * for more information about serialization in Swing.
2796      */
2797     private void writeObject(ObjectOutputStream s) throws IOException {
2798         s.defaultWriteObject();
2799         if (getUIClassID().equals(uiClassID)) {


2831         ",selectionForeground=" + selectionForegroundString +
2832         ",visibleRowCount=" + visibleRowCount +
2833         ",layoutOrientation=" + layoutOrientation;
2834     }
2835 
2836 
2837     /**
2838      * --- Accessibility Support ---
2839      */
2840 
2841     /**
2842      * Gets the {@code AccessibleContext} associated with this {@code JList}.
2843      * For {@code JList}, the {@code AccessibleContext} takes the form of an
2844      * {@code AccessibleJList}.
2845      * <p>
2846      * A new {@code AccessibleJList} instance is created if necessary.
2847      *
2848      * @return an {@code AccessibleJList} that serves as the
2849      *         {@code AccessibleContext} of this {@code JList}
2850      */
2851     @BeanProperty(bound = false)
2852     public AccessibleContext getAccessibleContext() {
2853         if (accessibleContext == null) {
2854             accessibleContext = new AccessibleJList();
2855         }
2856         return accessibleContext;
2857     }
2858 
2859     /**
2860      * This class implements accessibility support for the
2861      * {@code JList} class. It provides an implementation of the
2862      * Java Accessibility API appropriate to list user-interface
2863      * elements.
2864      * <p>
2865      * <strong>Warning:</strong>
2866      * Serialized objects of this class will not be compatible with
2867      * future Swing releases. The current serialization support is
2868      * appropriate for short term storage or RMI between applications running
2869      * the same version of Swing.  As of 1.4, support for long term storage
2870      * of all JavaBeans&trade;
2871      * has been added to the <code>java.beans</code> package.