mirror of git://gcc.gnu.org/git/gcc.git
				
				
				
			
		
			
				
	
	
		
			2500 lines
		
	
	
		
			76 KiB
		
	
	
	
		
			Java
		
	
	
	
			
		
		
	
	
			2500 lines
		
	
	
		
			76 KiB
		
	
	
	
		
			Java
		
	
	
	
/* JList.java --
 | 
						|
   Copyright (C) 2002, 2003, 2004, 2005, 2006,  Free Software Foundation, Inc.
 | 
						|
 | 
						|
This file is part of GNU Classpath.
 | 
						|
 | 
						|
GNU Classpath is free software; you can redistribute it and/or modify
 | 
						|
it under the terms of the GNU General Public License as published by
 | 
						|
the Free Software Foundation; either version 2, or (at your option)
 | 
						|
any later version.
 | 
						|
 | 
						|
GNU Classpath is distributed in the hope that it will be useful, but
 | 
						|
WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
						|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
						|
General Public License for more details.
 | 
						|
 | 
						|
You should have received a copy of the GNU General Public License
 | 
						|
along with GNU Classpath; see the file COPYING.  If not, write to the
 | 
						|
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 | 
						|
02110-1301 USA.
 | 
						|
 | 
						|
Linking this library statically or dynamically with other modules is
 | 
						|
making a combined work based on this library.  Thus, the terms and
 | 
						|
conditions of the GNU General Public License cover the whole
 | 
						|
combination.
 | 
						|
 | 
						|
As a special exception, the copyright holders of this library give you
 | 
						|
permission to link this library with independent modules to produce an
 | 
						|
executable, regardless of the license terms of these independent
 | 
						|
modules, and to copy and distribute the resulting executable under
 | 
						|
terms of your choice, provided that you also meet, for each linked
 | 
						|
independent module, the terms and conditions of the license of that
 | 
						|
module.  An independent module is a module which is not derived from
 | 
						|
or based on this library.  If you modify this library, you may extend
 | 
						|
this exception to your version of the library, but you are not
 | 
						|
obligated to do so.  If you do not wish to do so, delete this
 | 
						|
exception statement from your version. */
 | 
						|
 | 
						|
 | 
						|
package javax.swing;
 | 
						|
 | 
						|
import gnu.java.lang.CPStringBuilder;
 | 
						|
 | 
						|
import java.awt.Color;
 | 
						|
import java.awt.Component;
 | 
						|
import java.awt.ComponentOrientation;
 | 
						|
import java.awt.Cursor;
 | 
						|
import java.awt.Dimension;
 | 
						|
import java.awt.Font;
 | 
						|
import java.awt.FontMetrics;
 | 
						|
import java.awt.Point;
 | 
						|
import java.awt.Rectangle;
 | 
						|
import java.awt.event.FocusListener;
 | 
						|
import java.beans.PropertyChangeEvent;
 | 
						|
import java.beans.PropertyChangeListener;
 | 
						|
import java.util.Locale;
 | 
						|
import java.util.Vector;
 | 
						|
 | 
						|
import javax.accessibility.Accessible;
 | 
						|
import javax.accessibility.AccessibleComponent;
 | 
						|
import javax.accessibility.AccessibleContext;
 | 
						|
import javax.accessibility.AccessibleRole;
 | 
						|
import javax.accessibility.AccessibleSelection;
 | 
						|
import javax.accessibility.AccessibleState;
 | 
						|
import javax.accessibility.AccessibleStateSet;
 | 
						|
import javax.swing.event.ListDataEvent;
 | 
						|
import javax.swing.event.ListDataListener;
 | 
						|
import javax.swing.event.ListSelectionEvent;
 | 
						|
import javax.swing.event.ListSelectionListener;
 | 
						|
import javax.swing.plaf.ListUI;
 | 
						|
import javax.swing.text.Position;
 | 
						|
 | 
						|
/**
 | 
						|
 * <p>This class is a facade over three separate objects: {@link
 | 
						|
 * javax.swing.ListModel}, {@link javax.swing.ListSelectionModel} and
 | 
						|
 * {@link javax.swing.plaf.ListUI}. The facade represents a unified "list"
 | 
						|
 * concept, with independently replacable (possibly client-provided) models
 | 
						|
 * for its contents and its current selection. In addition, each element in
 | 
						|
 * the list is rendered via a strategy class {@link
 | 
						|
 * javax.swing.ListCellRenderer}.</p>
 | 
						|
 *
 | 
						|
 * <p>Lists have many properties, some of which are stored in this class
 | 
						|
 * while others are delegated to the list's model or selection. The
 | 
						|
 * following properties are available:</p>
 | 
						|
 *
 | 
						|
 * <table>
 | 
						|
 * <tr><th>Property                       </th><th>Stored in</th><th>Bound?</th></tr>
 | 
						|
 * <tr><td>accessibleContext              </td><td>list     </td><td>no    </td></tr>
 | 
						|
 * <tr><td>anchorSelectionIndex           </td><td>selection</td><td>no    </td></tr>
 | 
						|
 * <tr><td>cellRenderer                   </td><td>list     </td><td>yes   </td></tr>
 | 
						|
 * <tr><td>dragEnabled                    </td><td>list     </td><td>no    </td></tr>
 | 
						|
 * <tr><td>firstVisibleIndex              </td><td>list     </td><td>no    </td></tr>
 | 
						|
 * <tr><td>fixedCellHeight                </td><td>list     </td><td>yes   </td></tr>
 | 
						|
 * <tr><td>fixedCellWidth                 </td><td>list     </td><td>yes   </td></tr>
 | 
						|
 * <tr><td>lastVisibleIndex               </td><td>list     </td><td>no    </td></tr>
 | 
						|
 * <tr><td>layoutOrientation              </td><td>list     </td><td>yes   </td></tr>
 | 
						|
 * <tr><td>leadSelectionIndex             </td><td>selection</td><td>no    </td></tr>
 | 
						|
 * <tr><td>maxSelectionIndex              </td><td>selection</td><td>no    </td></tr>
 | 
						|
 * <tr><td>minSelectionIndex              </td><td>selection</td><td>no    </td></tr>
 | 
						|
 * <tr><td>model                          </td><td>list     </td><td>yes   </td></tr>
 | 
						|
 * <tr><td>opaque                         </td><td>list     </td><td>no    </td></tr>
 | 
						|
 * <tr><td>preferredScrollableViewportSize</td><td>list     </td><td>no    </td></tr>
 | 
						|
 * <tr><td>prototypeCellValue             </td><td>list     </td><td>yes   </td></tr>
 | 
						|
 * <tr><td>scrollableTracksViewportHeight </td><td>list     </td><td>no    </td></tr>
 | 
						|
 * <tr><td>scrollableTracksViewportWidth  </td><td>list     </td><td>no    </td></tr>
 | 
						|
 * <tr><td>selectedIndex                  </td><td>selection</td><td>no    </td></tr>
 | 
						|
 * <tr><td>selectedIndices                </td><td>selection</td><td>no    </td></tr>
 | 
						|
 * <tr><td>selectedValue                  </td><td>model    </td><td>no    </td></tr>
 | 
						|
 * <tr><td>selectedValues                 </td><td>model    </td><td>no    </td></tr>
 | 
						|
 * <tr><td>selectionBackground            </td><td>list     </td><td>yes   </td></tr>
 | 
						|
 * <tr><td>selectionEmpty                 </td><td>selection</td><td>no    </td></tr>
 | 
						|
 * <tr><td>selectionForeground            </td><td>list     </td><td>yes   </td></tr>
 | 
						|
 * <tr><td>selectionMode                  </td><td>selection</td><td>no    </td></tr>
 | 
						|
 * <tr><td>selectionModel                 </td><td>list     </td><td>yes   </td></tr>
 | 
						|
 * <tr><td>UI                             </td><td>list     </td><td>yes   </td></tr>
 | 
						|
 * <tr><td>UIClassID                      </td><td>list     </td><td>no    </td></tr>
 | 
						|
 * <tr><td>valueIsAdjusting               </td><td>list     </td><td>no    </td></tr>
 | 
						|
 * <tr><td>visibleRowCount                </td><td>list     </td><td>no    </td></tr>
 | 
						|
 * </table>
 | 
						|
 *
 | 
						|
 * @author Graydon Hoare (graydon@redhat.com)
 | 
						|
 */
 | 
						|
 | 
						|
public class JList extends JComponent implements Accessible, Scrollable
 | 
						|
{
 | 
						|
 | 
						|
  /**
 | 
						|
   * Provides accessibility support for <code>JList</code>.
 | 
						|
   */
 | 
						|
  protected class AccessibleJList extends AccessibleJComponent
 | 
						|
    implements AccessibleSelection, PropertyChangeListener,
 | 
						|
               ListSelectionListener, ListDataListener
 | 
						|
  {
 | 
						|
 | 
						|
    /**
 | 
						|
     * Provides accessibility support for list elements in <code>JList</code>s.
 | 
						|
     */
 | 
						|
    protected class AccessibleJListChild extends AccessibleContext
 | 
						|
      implements Accessible, AccessibleComponent
 | 
						|
    {
 | 
						|
 | 
						|
      /**
 | 
						|
       * The parent list.
 | 
						|
       */
 | 
						|
      JList parent;
 | 
						|
 | 
						|
      /**
 | 
						|
       * The index in the list for that child.
 | 
						|
       */
 | 
						|
      int listIndex;
 | 
						|
 | 
						|
      /**
 | 
						|
       * The cursor for this list child.
 | 
						|
       */
 | 
						|
      // TODO: Testcases show that this class somehow stores state about the
 | 
						|
      // cursor. I cannot make up though how that could affect
 | 
						|
      // the actual list.
 | 
						|
      Cursor cursor = Cursor.getDefaultCursor();
 | 
						|
 | 
						|
      /**
 | 
						|
       * Creates a new instance of <code>AccessibleJListChild</code>.
 | 
						|
       *
 | 
						|
       * @param list the list of which this is an accessible child
 | 
						|
       * @param index the list index for this child
 | 
						|
       */
 | 
						|
      public AccessibleJListChild(JList list, int index)
 | 
						|
      {
 | 
						|
        parent = list;
 | 
						|
        listIndex = index;
 | 
						|
      }
 | 
						|
 | 
						|
      /**
 | 
						|
       * Returns the accessible context of this object. Returns
 | 
						|
       * <code>this</code> since <code>AccessibleJListChild</code>s are their
 | 
						|
       * own accessible contexts.
 | 
						|
       *
 | 
						|
       * @return the accessible context of this object, <code>this</code>
 | 
						|
       */
 | 
						|
      public AccessibleContext getAccessibleContext()
 | 
						|
      {
 | 
						|
        return this;
 | 
						|
      }
 | 
						|
 | 
						|
      /**
 | 
						|
       * Returns the background color for this list child. This returns the
 | 
						|
       * background of the <code>JList</code> itself since the background
 | 
						|
       * cannot be set on list children individually
 | 
						|
       *
 | 
						|
       * @return the background color for this list child
 | 
						|
       */
 | 
						|
      public Color getBackground()
 | 
						|
      {
 | 
						|
        return parent.getBackground();
 | 
						|
      }
 | 
						|
 | 
						|
      /**
 | 
						|
       * Calling this method has no effect, since the background color cannot be
 | 
						|
       * set on list children individually.
 | 
						|
       *
 | 
						|
       * @param color not used here.
 | 
						|
       */
 | 
						|
      public void setBackground(Color color)
 | 
						|
      {
 | 
						|
        // Calling this method has no effect, since the background color cannot
 | 
						|
        // be set on list children individually.
 | 
						|
      }
 | 
						|
 | 
						|
      /**
 | 
						|
       * Returns the foreground color for this list child. This returns the
 | 
						|
       * background of the <code>JList</code> itself since the foreground
 | 
						|
       * cannot be set on list children individually.
 | 
						|
       *
 | 
						|
       * @return the background color for this list child
 | 
						|
       */
 | 
						|
      public Color getForeground()
 | 
						|
      {
 | 
						|
        return parent.getForeground();
 | 
						|
      }
 | 
						|
 | 
						|
      /**
 | 
						|
       * Calling this method has no effect, since the foreground color cannot be
 | 
						|
       * set on list children individually.
 | 
						|
       *
 | 
						|
       * @param color not used here.
 | 
						|
       */
 | 
						|
      public void setForeground(Color color)
 | 
						|
      {
 | 
						|
        // Calling this method has no effect, since the foreground color cannot
 | 
						|
        // be set on list children individually.
 | 
						|
      }
 | 
						|
 | 
						|
      /**
 | 
						|
       * Returns the cursor for this list child.
 | 
						|
       *
 | 
						|
       * @return the cursor for this list child
 | 
						|
       */
 | 
						|
      public Cursor getCursor()
 | 
						|
      {
 | 
						|
        // TODO: Testcases show that this method returns the cursor that has
 | 
						|
        // been set by setCursor. I cannot make up though how that could affect
 | 
						|
        // the actual list.
 | 
						|
        return cursor;
 | 
						|
      }
 | 
						|
 | 
						|
      /**
 | 
						|
       * Sets the cursor for this list child.
 | 
						|
       */
 | 
						|
      public void setCursor(Cursor cursor)
 | 
						|
      {
 | 
						|
        this.cursor = cursor;
 | 
						|
        // TODO: Testcases show that this method returns the cursor that has
 | 
						|
        // been set by setCursor. I cannot make up though how that could affect
 | 
						|
        // the actual list.
 | 
						|
      }
 | 
						|
 | 
						|
      /**
 | 
						|
       * Returns the font of the <code>JList</code> since it is not possible to
 | 
						|
       * set fonts for list children individually.
 | 
						|
       *
 | 
						|
       * @return the font of the <code>JList</code>
 | 
						|
       */
 | 
						|
      public Font getFont()
 | 
						|
      {
 | 
						|
        return parent.getFont();
 | 
						|
      }
 | 
						|
 | 
						|
      /**
 | 
						|
       * Does nothing since it is not possible to set the font on list children
 | 
						|
       * individually.
 | 
						|
       *
 | 
						|
       * @param font not used here
 | 
						|
       */
 | 
						|
      public void setFont(Font font)
 | 
						|
      {
 | 
						|
        // Does nothing since it is not possible to set the font on list
 | 
						|
        // children individually.
 | 
						|
      }
 | 
						|
 | 
						|
      /**
 | 
						|
       * Returns the font metrics for the specified font. This method forwards
 | 
						|
       * to the parent <code>JList</code>.
 | 
						|
       *
 | 
						|
       * @param font the font for which the font metrics is queried
 | 
						|
       *
 | 
						|
       * @return the font metrics for the specified font
 | 
						|
       */
 | 
						|
      public FontMetrics getFontMetrics(Font font)
 | 
						|
      {
 | 
						|
        return parent.getFontMetrics(font);
 | 
						|
      }
 | 
						|
 | 
						|
      /**
 | 
						|
       * Returns <code>true</code> if the parent <code>JList</code> is enabled,
 | 
						|
       * <code>false</code> otherwise. The list children cannot have an enabled
 | 
						|
       * flag set individually.
 | 
						|
       *
 | 
						|
       * @return <code>true</code> if the parent <code>JList</code> is enabled,
 | 
						|
       *         <code>false</code> otherwise
 | 
						|
       */
 | 
						|
      public boolean isEnabled()
 | 
						|
      {
 | 
						|
        return parent.isEnabled();
 | 
						|
      }
 | 
						|
 | 
						|
      /**
 | 
						|
       * Does nothing since the enabled flag cannot be set for list children
 | 
						|
       * individually.
 | 
						|
       *
 | 
						|
       * @param b not used here
 | 
						|
       */
 | 
						|
      public void setEnabled(boolean b)
 | 
						|
      {
 | 
						|
        // Does nothing since the enabled flag cannot be set for list children
 | 
						|
        // individually.
 | 
						|
      }
 | 
						|
 | 
						|
      /**
 | 
						|
       * Returns <code>true</code> if this list child is visible,
 | 
						|
       * <code>false</code> otherwise. The value of this property depends
 | 
						|
       * on {@link JList#getFirstVisibleIndex()} and
 | 
						|
       * {@link JList#getLastVisibleIndex()}.
 | 
						|
       *
 | 
						|
       * @return <code>true</code> if this list child is visible,
 | 
						|
       *         <code>false</code> otherwise
 | 
						|
       */
 | 
						|
      public boolean isVisible()
 | 
						|
      {
 | 
						|
        return listIndex >= parent.getFirstVisibleIndex()
 | 
						|
               && listIndex <= parent.getLastVisibleIndex();
 | 
						|
      }
 | 
						|
 | 
						|
      /**
 | 
						|
       * The value of the visible property cannot be modified, so this method
 | 
						|
       * does nothing.
 | 
						|
       *
 | 
						|
       * @param b not used here
 | 
						|
       */
 | 
						|
      public void setVisible(boolean b)
 | 
						|
      {
 | 
						|
        // The value of the visible property cannot be modified, so this method
 | 
						|
        // does nothing.
 | 
						|
      }
 | 
						|
 | 
						|
      /**
 | 
						|
       * Returns <code>true</code> if this list child is currently showing on
 | 
						|
       * screen and <code>false</code> otherwise. The list child is showing if
 | 
						|
       * it is visible and if it's parent JList is currently showing.
 | 
						|
       *
 | 
						|
       * @return <code>true</code> if this list child is currently showing on
 | 
						|
       *         screen and <code>false</code> otherwise
 | 
						|
       */
 | 
						|
      public boolean isShowing()
 | 
						|
      {
 | 
						|
        return isVisible() && parent.isShowing();
 | 
						|
      }
 | 
						|
 | 
						|
      /**
 | 
						|
       * Returns <code>true</code> if this list child covers the screen location
 | 
						|
       * <code>point</code> (relative to the <code>JList</code> coordinate
 | 
						|
       * system, <code>false</code> otherwise.
 | 
						|
       *
 | 
						|
       * @return <code>true</code> if this list child covers the screen location
 | 
						|
       *         <code>point</code> , <code>false</code> otherwise
 | 
						|
       */
 | 
						|
      public boolean contains(Point point)
 | 
						|
      {
 | 
						|
        return getBounds().contains(point);
 | 
						|
      }
 | 
						|
 | 
						|
      /**
 | 
						|
       * Returns the absolute screen location of this list child.
 | 
						|
       *
 | 
						|
       * @return the absolute screen location of this list child
 | 
						|
       */
 | 
						|
      public Point getLocationOnScreen()
 | 
						|
      {
 | 
						|
        Point loc = getLocation();
 | 
						|
        SwingUtilities.convertPointToScreen(loc, parent);
 | 
						|
        return loc;
 | 
						|
      }
 | 
						|
 | 
						|
      /**
 | 
						|
       * Returns the screen location of this list child relative to it's parent.
 | 
						|
       *
 | 
						|
       * @return the location of this list child relative to it's parent
 | 
						|
       *
 | 
						|
       * @see JList#indexToLocation(int)
 | 
						|
       */
 | 
						|
      public Point getLocation()
 | 
						|
      {
 | 
						|
        return parent.indexToLocation(listIndex);
 | 
						|
      }
 | 
						|
 | 
						|
      /**
 | 
						|
       * Does nothing since the screen location cannot be set on list children
 | 
						|
       * explictitly.
 | 
						|
       *
 | 
						|
       * @param point not used here
 | 
						|
       */
 | 
						|
      public void setLocation(Point point)
 | 
						|
      {
 | 
						|
        // Does nothing since the screen location cannot be set on list children
 | 
						|
        // explictitly.
 | 
						|
      }
 | 
						|
 | 
						|
      /**
 | 
						|
       * Returns the bounds of this list child.
 | 
						|
       *
 | 
						|
       * @return the bounds of this list child
 | 
						|
       *
 | 
						|
       * @see JList#getCellBounds(int, int)
 | 
						|
       */
 | 
						|
      public Rectangle getBounds()
 | 
						|
      {
 | 
						|
        return parent.getCellBounds(listIndex, listIndex);
 | 
						|
      }
 | 
						|
 | 
						|
      /**
 | 
						|
       * Does nothing since the bounds cannot be set on list children
 | 
						|
       * individually.
 | 
						|
       *
 | 
						|
       * @param rectangle not used here
 | 
						|
       */
 | 
						|
      public void setBounds(Rectangle rectangle)
 | 
						|
      {
 | 
						|
        // Does nothing since the bounds cannot be set on list children
 | 
						|
        // individually.
 | 
						|
      }
 | 
						|
 | 
						|
      /**
 | 
						|
       * Returns the size of this list child.
 | 
						|
       *
 | 
						|
       * @return the size of this list child
 | 
						|
       */
 | 
						|
      public Dimension getSize()
 | 
						|
      {
 | 
						|
        Rectangle b = getBounds();
 | 
						|
        return b.getSize();
 | 
						|
      }
 | 
						|
 | 
						|
      /**
 | 
						|
       * Does nothing since the size cannot be set on list children
 | 
						|
       * individually.
 | 
						|
       *
 | 
						|
       * @param dimension not used here
 | 
						|
       */
 | 
						|
      public void setSize(Dimension dimension)
 | 
						|
      {
 | 
						|
        // Does nothing since the size cannot be set on list children
 | 
						|
        // individually.
 | 
						|
      }
 | 
						|
 | 
						|
      /**
 | 
						|
       * Returns <code>null</code> because list children do not have children
 | 
						|
       * themselves
 | 
						|
       *
 | 
						|
       * @return <code>null</code>
 | 
						|
       */
 | 
						|
      public Accessible getAccessibleAt(Point point)
 | 
						|
      {
 | 
						|
        return null;
 | 
						|
      }
 | 
						|
 | 
						|
      /**
 | 
						|
       * Returns <code>true</code> since list children are focus traversable.
 | 
						|
       *
 | 
						|
       * @return true
 | 
						|
       */
 | 
						|
      public boolean isFocusTraversable()
 | 
						|
      {
 | 
						|
        // TODO: Is this 100% ok?
 | 
						|
        return true;
 | 
						|
      }
 | 
						|
 | 
						|
      /**
 | 
						|
       * Requests focus on the parent list. List children cannot request focus
 | 
						|
       * individually.
 | 
						|
       */
 | 
						|
      public void requestFocus()
 | 
						|
      {
 | 
						|
        // TODO: Is this 100% ok?
 | 
						|
        parent.requestFocus();
 | 
						|
      }
 | 
						|
 | 
						|
      /**
 | 
						|
       * Adds a focus listener to the parent list. List children do not have
 | 
						|
       * their own focus management.
 | 
						|
       *
 | 
						|
       * @param listener the focus listener to add
 | 
						|
       */
 | 
						|
      public void addFocusListener(FocusListener listener)
 | 
						|
      {
 | 
						|
        // TODO: Is this 100% ok?
 | 
						|
        parent.addFocusListener(listener);
 | 
						|
      }
 | 
						|
 | 
						|
      /**
 | 
						|
       * Removes a focus listener from the parent list. List children do not
 | 
						|
       * have their own focus management.
 | 
						|
       *
 | 
						|
       * @param listener the focus listener to remove
 | 
						|
       */
 | 
						|
      public void removeFocusListener(FocusListener listener)
 | 
						|
      {
 | 
						|
        // TODO: Is this 100%
 | 
						|
        parent.removeFocusListener(listener);
 | 
						|
      }
 | 
						|
 | 
						|
      /**
 | 
						|
       * Returns the accessible role of this list item, which is
 | 
						|
       * {@link AccessibleRole#LABEL}.
 | 
						|
       *
 | 
						|
       * @return {@link AccessibleRole#LABEL}
 | 
						|
       */
 | 
						|
      public AccessibleRole getAccessibleRole()
 | 
						|
      {
 | 
						|
        return AccessibleRole.LABEL;
 | 
						|
      }
 | 
						|
 | 
						|
      /**
 | 
						|
       * Returns the accessible state set of this list item.
 | 
						|
       *
 | 
						|
       * @return the accessible state set of this list item
 | 
						|
       */
 | 
						|
      public AccessibleStateSet getAccessibleStateSet()
 | 
						|
      {
 | 
						|
        AccessibleStateSet states = new AccessibleStateSet();
 | 
						|
        if (isVisible())
 | 
						|
          states.add(AccessibleState.VISIBLE);
 | 
						|
        if (isShowing())
 | 
						|
          states.add(AccessibleState.SHOWING);
 | 
						|
        if (isFocusTraversable())
 | 
						|
          states.add(AccessibleState.FOCUSABLE);
 | 
						|
        // TODO: How should the active state be handled? The API docs
 | 
						|
        // suggest that this state is set on the activated list child,
 | 
						|
        // that is the one that is drawn with a box. However, I don't know how
 | 
						|
        // to implement this.
 | 
						|
 | 
						|
        // TODO: We set the selectable state here because list children are
 | 
						|
        // selectable. Is there a way to disable single children?
 | 
						|
        if (parent.isEnabled())
 | 
						|
          states.add(AccessibleState.SELECTABLE);
 | 
						|
 | 
						|
        if (parent.isSelectedIndex(listIndex))
 | 
						|
          states.add(AccessibleState.SELECTED);
 | 
						|
 | 
						|
        // TODO: Handle more states here?
 | 
						|
        return states;
 | 
						|
      }
 | 
						|
 | 
						|
      /**
 | 
						|
       * Returns the index of this list child within it's parent list.
 | 
						|
       *
 | 
						|
       * @return the index of this list child within it's parent list
 | 
						|
       */
 | 
						|
      public int getAccessibleIndexInParent()
 | 
						|
      {
 | 
						|
        return listIndex;
 | 
						|
      }
 | 
						|
 | 
						|
      /**
 | 
						|
       * Returns <code>0</code> since list children don't have children
 | 
						|
       * themselves.
 | 
						|
       *
 | 
						|
       * @return <code>0</code>
 | 
						|
       */
 | 
						|
      public int getAccessibleChildrenCount()
 | 
						|
      {
 | 
						|
        return 0;
 | 
						|
      }
 | 
						|
 | 
						|
      /**
 | 
						|
       * Returns <code>null</code> since list children don't have children
 | 
						|
       * themselves.
 | 
						|
       *
 | 
						|
       * @return <code>null</code>
 | 
						|
       */
 | 
						|
      public Accessible getAccessibleChild(int i)
 | 
						|
      {
 | 
						|
        return null;
 | 
						|
      }
 | 
						|
 | 
						|
      /**
 | 
						|
       * Returns the locale of this component. This call is forwarded to the
 | 
						|
       * parent list since list children don't have a separate locale setting.
 | 
						|
       *
 | 
						|
       * @return the locale of this component
 | 
						|
       */
 | 
						|
      public Locale getLocale()
 | 
						|
      {
 | 
						|
        return parent.getLocale();
 | 
						|
      }
 | 
						|
 | 
						|
      /**
 | 
						|
       * This method does
 | 
						|
       * nothing, list children are transient accessible objects which means
 | 
						|
       * that they don't fire property change events.
 | 
						|
       *
 | 
						|
       * @param l not used here
 | 
						|
       */
 | 
						|
      public void addPropertyChangeListener(PropertyChangeListener l)
 | 
						|
      {
 | 
						|
        // Do nothing here.
 | 
						|
      }
 | 
						|
 | 
						|
      /**
 | 
						|
       * This method does
 | 
						|
       * nothing, list children are transient accessible objects which means
 | 
						|
       * that they don't fire property change events.
 | 
						|
       *
 | 
						|
       * @param l not used here
 | 
						|
       */
 | 
						|
      public void removePropertyChangeListener(PropertyChangeListener l)
 | 
						|
      {
 | 
						|
        // Do nothing here.
 | 
						|
      }
 | 
						|
 | 
						|
      // TODO: Implement the remaining methods of this class.
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Create a new AccessibleJList.
 | 
						|
     */
 | 
						|
    public AccessibleJList()
 | 
						|
    {
 | 
						|
      // Nothing to do here.
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Returns the number of selected accessible children.
 | 
						|
     *
 | 
						|
     * @return the number of selected accessible children
 | 
						|
     */
 | 
						|
    public int getAccessibleSelectionCount()
 | 
						|
    {
 | 
						|
      return getSelectedIndices().length;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Returns the n-th selected accessible child.
 | 
						|
     *
 | 
						|
     * @param n the index of the selected child to return
 | 
						|
     *
 | 
						|
     * @return the n-th selected accessible child
 | 
						|
     */
 | 
						|
    public Accessible getAccessibleSelection(int n)
 | 
						|
    {
 | 
						|
      return new AccessibleJListChild(JList.this, getSelectedIndices()[n]);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Returns <code>true</code> if the n-th child is selected,
 | 
						|
     * <code>false</code> otherwise.
 | 
						|
     *
 | 
						|
     * @param n the index of the child of which the selected state is queried
 | 
						|
     *
 | 
						|
     * @return <code>true</code> if the n-th child is selected,
 | 
						|
     *         <code>false</code> otherwise
 | 
						|
     */
 | 
						|
    public boolean isAccessibleChildSelected(int n)
 | 
						|
    {
 | 
						|
      return isSelectedIndex(n);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Adds the accessible item with the specified index to the selected items.
 | 
						|
     * If multiple selections are supported, the item is added to the selection,
 | 
						|
     * otherwise the item replaces the current selection.
 | 
						|
     *
 | 
						|
     * @param i the index of the item to add to the selection
 | 
						|
     */
 | 
						|
    public void addAccessibleSelection(int i)
 | 
						|
    {
 | 
						|
      addSelectionInterval(i, i);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Removes the accessible item with the specified index to the selection.
 | 
						|
     *
 | 
						|
     * @param i the index of the item to be removed from the selection
 | 
						|
     */
 | 
						|
    public void removeAccessibleSelection(int i)
 | 
						|
    {
 | 
						|
      removeSelectionInterval(i, i);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Remove all selection items from the selection.
 | 
						|
     */
 | 
						|
    public void clearAccessibleSelection()
 | 
						|
    {
 | 
						|
      clearSelection();
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Selects all items if multiple selections are supported.
 | 
						|
     * Otherwise do nothing.
 | 
						|
     */
 | 
						|
    public void selectAllAccessibleSelection()
 | 
						|
    {
 | 
						|
      addSelectionInterval(0, getModel().getSize());
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Receices notification when the list selection is changed. This method
 | 
						|
     * fires two property change events, the first with
 | 
						|
     * {@link AccessibleContext#ACCESSIBLE_VISIBLE_DATA_PROPERTY} and the second
 | 
						|
     * with {@link AccessibleContext#ACCESSIBLE_SELECTION_PROPERTY}.
 | 
						|
     *
 | 
						|
     * @param event the list selection event
 | 
						|
     */
 | 
						|
    public void valueChanged(ListSelectionEvent event)
 | 
						|
    {
 | 
						|
      firePropertyChange(ACCESSIBLE_VISIBLE_DATA_PROPERTY, Boolean.FALSE,
 | 
						|
                         Boolean.TRUE);
 | 
						|
      firePropertyChange(ACCESSIBLE_SELECTION_PROPERTY, Boolean.FALSE,
 | 
						|
                         Boolean.TRUE);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Receives notification when items have changed in the
 | 
						|
     * <code>JList</code>. This method fires a property change event with
 | 
						|
     * {@link AccessibleContext#ACCESSIBLE_VISIBLE_DATA_PROPERTY}.
 | 
						|
     *
 | 
						|
     * @param event the list data event
 | 
						|
     */
 | 
						|
    public void contentsChanged(ListDataEvent event)
 | 
						|
    {
 | 
						|
      firePropertyChange(ACCESSIBLE_VISIBLE_DATA_PROPERTY, Boolean.FALSE,
 | 
						|
                         Boolean.TRUE);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Receives notification when items are inserted into the
 | 
						|
     * <code>JList</code>. This method fires a property change event with
 | 
						|
     * {@link AccessibleContext#ACCESSIBLE_VISIBLE_DATA_PROPERTY}.
 | 
						|
     *
 | 
						|
     * @param event the list data event
 | 
						|
     */
 | 
						|
    public void intervalAdded(ListDataEvent event)
 | 
						|
    {
 | 
						|
      firePropertyChange(ACCESSIBLE_VISIBLE_DATA_PROPERTY, Boolean.FALSE,
 | 
						|
                         Boolean.TRUE);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Receives notification when items are removed from the
 | 
						|
     * <code>JList</code>. This method fires a property change event with
 | 
						|
     * {@link AccessibleContext#ACCESSIBLE_VISIBLE_DATA_PROPERTY}.
 | 
						|
     *
 | 
						|
     * @param event the list data event
 | 
						|
     */
 | 
						|
    public void intervalRemoved(ListDataEvent event)
 | 
						|
    {
 | 
						|
      firePropertyChange(ACCESSIBLE_VISIBLE_DATA_PROPERTY, Boolean.FALSE,
 | 
						|
                         Boolean.TRUE);
 | 
						|
    }
 | 
						|
 | 
						|
 | 
						|
    /**
 | 
						|
     * Receives notification about changes of the <code>JList</code>'s
 | 
						|
     * properties. This is used to re-register this object as listener to
 | 
						|
     * the data model and selection model when the data model or selection model
 | 
						|
     * changes.
 | 
						|
     *
 | 
						|
     * @param e the property change event
 | 
						|
     */
 | 
						|
    public void propertyChange(PropertyChangeEvent e)
 | 
						|
    {
 | 
						|
      String propertyName = e.getPropertyName();
 | 
						|
      if (propertyName.equals("model"))
 | 
						|
        {
 | 
						|
          ListModel oldModel = (ListModel) e.getOldValue();
 | 
						|
          oldModel.removeListDataListener(this);
 | 
						|
          ListModel newModel = (ListModel) e.getNewValue();
 | 
						|
          newModel.addListDataListener(this);
 | 
						|
        }
 | 
						|
      else if (propertyName.equals("selectionModel"))
 | 
						|
        {
 | 
						|
          ListSelectionModel oldModel = (ListSelectionModel) e.getOldValue();
 | 
						|
          oldModel.removeListSelectionListener(this);
 | 
						|
          ListSelectionModel newModel = (ListSelectionModel) e.getNewValue();
 | 
						|
          oldModel.addListSelectionListener(this);
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Return the state set of the <code>JList</code>.
 | 
						|
     *
 | 
						|
     * @return the state set of the <code>JList</code>
 | 
						|
     */
 | 
						|
    public AccessibleStateSet getAccessibleStateSet()
 | 
						|
    {
 | 
						|
      // TODO: Figure out if there is possibly more state that must be
 | 
						|
      // handled here.
 | 
						|
      AccessibleStateSet s = super.getAccessibleStateSet();
 | 
						|
      if (getSelectionMode() != ListSelectionModel.SINGLE_SELECTION)
 | 
						|
        s.add(AccessibleState.MULTISELECTABLE);
 | 
						|
      return s;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Returns the accessible role for <code>JList</code>,
 | 
						|
     * {@link AccessibleRole#LIST}.
 | 
						|
     *
 | 
						|
     * @return the accessible role for <code>JList</code>
 | 
						|
     */
 | 
						|
    public AccessibleRole getAccessibleRole()
 | 
						|
    {
 | 
						|
      return AccessibleRole.LIST;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Returns the accessible child at the visual location <code>p</code>
 | 
						|
     * (relative to the upper left corner of the <code>JList</code>). If there
 | 
						|
     * is no child at that location, this returns <code>null</code>.
 | 
						|
     *
 | 
						|
     * @param p the screen location for which to return the accessible child
 | 
						|
     *
 | 
						|
     * @return the accessible child at the specified location, or
 | 
						|
     *         <code>null</code> if there is no child at that location
 | 
						|
     */
 | 
						|
    public Accessible getAccessibleAt(Point p)
 | 
						|
    {
 | 
						|
      int childIndex = locationToIndex(p);
 | 
						|
      return getAccessibleChild(childIndex);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Returns the number of accessible children in the <code>JList</code>.
 | 
						|
     *
 | 
						|
     * @return the number of accessible children in the <code>JList</code>
 | 
						|
     */
 | 
						|
    public int getAccessibleChildrenCount()
 | 
						|
    {
 | 
						|
      return getModel().getSize();
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Returns the n-th accessible child of this <code>JList</code>. This will
 | 
						|
     * be an instance of {@link AccessibleJListChild}. If there is no child
 | 
						|
     * at that index, <code>null</code> is returned.
 | 
						|
     *
 | 
						|
     * @param n the index of the child to return
 | 
						|
     *
 | 
						|
     * @return the n-th accessible child of this <code>JList</code>
 | 
						|
     */
 | 
						|
    public Accessible getAccessibleChild(int n)
 | 
						|
    {
 | 
						|
      if (getModel().getSize() <= n)
 | 
						|
        return null;
 | 
						|
      return new AccessibleJListChild(JList.this, n);
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  private static final long serialVersionUID = 4406629526391098046L;
 | 
						|
 | 
						|
  /**
 | 
						|
   * Constant value used in "layoutOrientation" property. This value means
 | 
						|
   * that cells are laid out in a single vertical column. This is the default.
 | 
						|
   */
 | 
						|
  public static final int VERTICAL = 0;
 | 
						|
 | 
						|
  /**
 | 
						|
   * Constant value used in "layoutOrientation" property. This value means
 | 
						|
   * that cells are laid out in multiple columns "newspaper style", filling
 | 
						|
   * vertically first, then horizontally.
 | 
						|
   */
 | 
						|
  public static final int VERTICAL_WRAP = 1;
 | 
						|
 | 
						|
  /**
 | 
						|
   * Constant value used in "layoutOrientation" property. This value means
 | 
						|
   * that cells are laid out in multiple columns "newspaper style",
 | 
						|
   * filling horizontally first, then vertically.
 | 
						|
   */
 | 
						|
  public static final int HORIZONTAL_WRAP = 2;
 | 
						|
 | 
						|
  /**
 | 
						|
   * This property indicates whether "drag and drop" functions are enabled
 | 
						|
   * on the list.
 | 
						|
   */
 | 
						|
  boolean dragEnabled;
 | 
						|
 | 
						|
  /** This property provides a strategy for rendering cells in the list. */
 | 
						|
  ListCellRenderer cellRenderer;
 | 
						|
 | 
						|
  /**
 | 
						|
   * This property indicates an fixed width to assign to all cells in the
 | 
						|
   * list. If its value is <code>-1</code>, no width has been
 | 
						|
   * assigned. This value can be set explicitly, or implicitly by setting
 | 
						|
   * the {@link #prototypeCellValue} property.
 | 
						|
   */
 | 
						|
  int fixedCellWidth;
 | 
						|
 | 
						|
  /**
 | 
						|
   * This property indicates an fixed height to assign to all cells in the
 | 
						|
   * list. If its value is <code>-1</code>, no height has been
 | 
						|
   * assigned. This value can be set explicitly, or implicitly by setting
 | 
						|
   * the {@link #prototypeCellValue} property.
 | 
						|
   */
 | 
						|
  int fixedCellHeight;
 | 
						|
 | 
						|
  /**
 | 
						|
   * This property holds the current layout orientation of the list, which
 | 
						|
   * is one of the integer constants {@link #VERTICAL}, {@link
 | 
						|
   * #VERTICAL_WRAP}, or {@link #HORIZONTAL_WRAP}.
 | 
						|
   */
 | 
						|
  int layoutOrientation;
 | 
						|
 | 
						|
  /** This property holds the data elements displayed by the list. */
 | 
						|
  ListModel model;
 | 
						|
 | 
						|
  /**
 | 
						|
   * <p>This property holds a reference to a "prototype" data value --
 | 
						|
   * typically a String -- which is used to calculate the {@link
 | 
						|
   * #fixedCellWidth} and {@link #fixedCellHeight} properties, using the
 | 
						|
   * {@link #cellRenderer} property to acquire a component to render the
 | 
						|
   * prototype.</p>
 | 
						|
   *
 | 
						|
   * <p>It is important that you <em>not</em> set this value to a
 | 
						|
   * component. It has to be a <em>data value</em> such as the objects you
 | 
						|
   * would find in the list's model. Setting it to a component will have
 | 
						|
   * undefined (and undesirable) affects. </p>
 | 
						|
   */
 | 
						|
  Object prototypeCellValue;
 | 
						|
 | 
						|
  /**
 | 
						|
   * This property specifies a foreground color for the selected cells in
 | 
						|
   * the list. When {@link ListCellRenderer#getListCellRendererComponent}
 | 
						|
   * is called with a selected cell object, the component returned will
 | 
						|
   * have its "foreground" set to this color.
 | 
						|
   */
 | 
						|
  Color selectionBackground;
 | 
						|
 | 
						|
  /**
 | 
						|
   * This property specifies a background color for the selected cells in
 | 
						|
   * the list. When {@link ListCellRenderer#getListCellRendererComponent}
 | 
						|
   * is called with a selected cell object, the component returned will
 | 
						|
   * have its "background" property set to this color.
 | 
						|
   */
 | 
						|
  Color selectionForeground;
 | 
						|
 | 
						|
  /**
 | 
						|
   * This property holds a description of which data elements in the {@link
 | 
						|
   * #model} property should be considered "selected", when displaying and
 | 
						|
   * interacting with the list.
 | 
						|
   */
 | 
						|
  ListSelectionModel selectionModel;
 | 
						|
 | 
						|
  /**
 | 
						|
   * This property indicates a <em>preference</em> for the number of rows
 | 
						|
   * displayed in the list, and will scale the
 | 
						|
   * {@link #getPreferredScrollableViewportSize} property accordingly. The actual
 | 
						|
   * number of displayed rows, when the list is placed in a real {@link
 | 
						|
   * JViewport} or other component, may be greater or less than this number.
 | 
						|
   */
 | 
						|
  int visibleRowCount;
 | 
						|
 | 
						|
  /**
 | 
						|
   * Fire a {@link ListSelectionEvent} to all the registered
 | 
						|
   * ListSelectionListeners.
 | 
						|
   *
 | 
						|
   * @param firstIndex  the lowest index covering the selection change.
 | 
						|
   * @param lastIndex  the highest index covering the selection change.
 | 
						|
   * @param isAdjusting  a flag indicating if this event is one in a series
 | 
						|
   *     of events updating the selection.
 | 
						|
   */
 | 
						|
  protected void fireSelectionValueChanged(int firstIndex, int lastIndex,
 | 
						|
                                           boolean isAdjusting)
 | 
						|
  {
 | 
						|
    ListSelectionEvent evt = new ListSelectionEvent(this, firstIndex,
 | 
						|
                                                    lastIndex, isAdjusting);
 | 
						|
    ListSelectionListener listeners[] = getListSelectionListeners();
 | 
						|
    for (int i = 0; i < listeners.length; ++i)
 | 
						|
      {
 | 
						|
        listeners[i].valueChanged(evt);
 | 
						|
      }
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * This private listener propagates {@link ListSelectionEvent} events
 | 
						|
   * from the list's "selectionModel" property to the list's {@link
 | 
						|
   * ListSelectionListener} listeners. It also listens to {@link
 | 
						|
   * ListDataEvent} events from the list's {@link #model} property. If this
 | 
						|
   * class receives either type of event, it triggers repainting of the
 | 
						|
   * list.
 | 
						|
   */
 | 
						|
  private class ListListener
 | 
						|
    implements ListSelectionListener, ListDataListener
 | 
						|
  {
 | 
						|
    // ListDataListener events
 | 
						|
    public void contentsChanged(ListDataEvent event)
 | 
						|
    {
 | 
						|
      JList.this.revalidate();
 | 
						|
      JList.this.repaint();
 | 
						|
    }
 | 
						|
    public void intervalAdded(ListDataEvent event)
 | 
						|
    {
 | 
						|
      JList.this.revalidate();
 | 
						|
      JList.this.repaint();
 | 
						|
    }
 | 
						|
    public void intervalRemoved(ListDataEvent event)
 | 
						|
    {
 | 
						|
      JList.this.revalidate();
 | 
						|
      JList.this.repaint();
 | 
						|
    }
 | 
						|
    // ListSelectionListener events
 | 
						|
    public void valueChanged(ListSelectionEvent event)
 | 
						|
    {
 | 
						|
      JList.this.fireSelectionValueChanged(event.getFirstIndex(),
 | 
						|
                                           event.getLastIndex(),
 | 
						|
                                           event.getValueIsAdjusting());
 | 
						|
      JList.this.repaint();
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Shared ListListener instance, subscribed to both the current {@link
 | 
						|
   * #model} and {@link #selectionModel} properties of the list.
 | 
						|
   */
 | 
						|
  ListListener listListener;
 | 
						|
 | 
						|
 | 
						|
  /**
 | 
						|
   * Creates a new <code>JList</code> object.
 | 
						|
   */
 | 
						|
  public JList()
 | 
						|
  {
 | 
						|
    init(new DefaultListModel());
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Creates a new <code>JList</code> object.
 | 
						|
   *
 | 
						|
   * @param items  the initial list items.
 | 
						|
   */
 | 
						|
  public JList(Object[] items)
 | 
						|
  {
 | 
						|
    init(createListModel(items));
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Creates a new <code>JList</code> object.
 | 
						|
   *
 | 
						|
   * @param items  the initial list items.
 | 
						|
   */
 | 
						|
  public JList(Vector<?> items)
 | 
						|
  {
 | 
						|
    init(createListModel(items));
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Creates a new <code>JList</code> object.
 | 
						|
   *
 | 
						|
   * @param model  a model containing the list items (<code>null</code> not
 | 
						|
   *     permitted).
 | 
						|
   *
 | 
						|
   * @throws IllegalArgumentException if <code>model</code> is
 | 
						|
   *     <code>null</code>.
 | 
						|
   */
 | 
						|
  public JList(ListModel model)
 | 
						|
  {
 | 
						|
    init(model);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Initializes the list.
 | 
						|
   *
 | 
						|
   * @param m  the list model (<code>null</code> not permitted).
 | 
						|
   */
 | 
						|
  private void init(ListModel m)
 | 
						|
  {
 | 
						|
    if (m == null)
 | 
						|
      throw new IllegalArgumentException("Null model not permitted.");
 | 
						|
    dragEnabled = false;
 | 
						|
    fixedCellHeight = -1;
 | 
						|
    fixedCellWidth = -1;
 | 
						|
    layoutOrientation = VERTICAL;
 | 
						|
    opaque = true;
 | 
						|
    visibleRowCount = 8;
 | 
						|
 | 
						|
    cellRenderer = new DefaultListCellRenderer();
 | 
						|
    listListener = new ListListener();
 | 
						|
 | 
						|
    model = m;
 | 
						|
    if (model != null)
 | 
						|
      model.addListDataListener(listListener);
 | 
						|
 | 
						|
    selectionModel = createSelectionModel();
 | 
						|
    if (selectionModel != null)
 | 
						|
      {
 | 
						|
        selectionModel.addListSelectionListener(listListener);
 | 
						|
        selectionModel.setSelectionMode
 | 
						|
                              (ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
 | 
						|
      }
 | 
						|
    setLayout(null);
 | 
						|
 | 
						|
    updateUI();
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Creates the default <code>ListSelectionModel</code>.
 | 
						|
   *
 | 
						|
   * @return the <code>ListSelectionModel</code>
 | 
						|
   */
 | 
						|
  protected ListSelectionModel createSelectionModel()
 | 
						|
  {
 | 
						|
    return new DefaultListSelectionModel();
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Gets the value of the {@link #fixedCellHeight} property. This property
 | 
						|
   * may be <code>-1</code> to indicate that no cell height has been
 | 
						|
   * set. This property is also set implicitly when the
 | 
						|
   * {@link #prototypeCellValue} property is set.
 | 
						|
   *
 | 
						|
   * @return The current value of the property
 | 
						|
   *
 | 
						|
   * @see #fixedCellHeight
 | 
						|
   * @see #setFixedCellHeight
 | 
						|
   * @see #setPrototypeCellValue
 | 
						|
   */
 | 
						|
  public int getFixedCellHeight()
 | 
						|
  {
 | 
						|
    return fixedCellHeight;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Sets the value of the {@link #fixedCellHeight} property. This property
 | 
						|
   * may be <code>-1</code> to indicate that no cell height has been
 | 
						|
   * set. This property is also set implicitly when the {@link
 | 
						|
   * #prototypeCellValue} property is set, but setting it explicitly
 | 
						|
   * overrides the height computed from {@link #prototypeCellValue}.
 | 
						|
   *
 | 
						|
   * @param h  the height.
 | 
						|
   *
 | 
						|
   * @see #getFixedCellHeight
 | 
						|
   * @see #getPrototypeCellValue
 | 
						|
   */
 | 
						|
  public void setFixedCellHeight(int h)
 | 
						|
  {
 | 
						|
    if (fixedCellHeight == h)
 | 
						|
      return;
 | 
						|
 | 
						|
    int old = fixedCellHeight;
 | 
						|
    fixedCellHeight = h;
 | 
						|
    firePropertyChange("fixedCellHeight", old, h);
 | 
						|
  }
 | 
						|
 | 
						|
 | 
						|
  /**
 | 
						|
   * Gets the value of the {@link #fixedCellWidth} property. This property
 | 
						|
   * may be <code>-1</code> to indicate that no cell width has been
 | 
						|
   * set. This property is also set implicitly when the {@link
 | 
						|
   * #prototypeCellValue} property is set.
 | 
						|
   *
 | 
						|
   * @return The current value of the property
 | 
						|
   *
 | 
						|
   * @see #setFixedCellWidth
 | 
						|
   * @see #setPrototypeCellValue
 | 
						|
   */
 | 
						|
  public int getFixedCellWidth()
 | 
						|
  {
 | 
						|
    return fixedCellWidth;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Sets the value of the {@link #fixedCellWidth} property. This property
 | 
						|
   * may be <code>-1</code> to indicate that no cell width has been
 | 
						|
   * set. This property is also set implicitly when the {@link
 | 
						|
   * #prototypeCellValue} property is set, but setting it explicitly
 | 
						|
   * overrides the width computed from {@link #prototypeCellValue}.
 | 
						|
   *
 | 
						|
   * @param w  the width.
 | 
						|
   *
 | 
						|
   * @see #getFixedCellHeight
 | 
						|
   * @see #getPrototypeCellValue
 | 
						|
   */
 | 
						|
  public void setFixedCellWidth(int w)
 | 
						|
  {
 | 
						|
    if (fixedCellWidth == w)
 | 
						|
      return;
 | 
						|
 | 
						|
    int old = fixedCellWidth;
 | 
						|
    fixedCellWidth = w;
 | 
						|
    firePropertyChange("fixedCellWidth", old, w);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Gets the value of the {@link #visibleRowCount} property.  The default
 | 
						|
   * value is 8.
 | 
						|
   *
 | 
						|
   * @return the current value of the property.
 | 
						|
   *
 | 
						|
   * @see #setVisibleRowCount(int)
 | 
						|
   */
 | 
						|
  public int getVisibleRowCount()
 | 
						|
  {
 | 
						|
    return visibleRowCount;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Sets the value of the {@link #visibleRowCount} property.
 | 
						|
   *
 | 
						|
   * @param vc The new property value
 | 
						|
   *
 | 
						|
   * @see #getVisibleRowCount()
 | 
						|
   */
 | 
						|
  public void setVisibleRowCount(int vc)
 | 
						|
  {
 | 
						|
    if (visibleRowCount != vc)
 | 
						|
      {
 | 
						|
        int oldValue = visibleRowCount;
 | 
						|
        visibleRowCount = Math.max(vc, 0);
 | 
						|
        firePropertyChange("visibleRowCount", oldValue, vc);
 | 
						|
        revalidate();
 | 
						|
        repaint();
 | 
						|
      }
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Adds a {@link ListSelectionListener} to the listener list for this
 | 
						|
   * list. The listener will be called back with a {@link
 | 
						|
   * ListSelectionEvent} any time the list's {@link #selectionModel}
 | 
						|
   * property changes. The source of such events will be the JList,
 | 
						|
   * not the selection model.
 | 
						|
   *
 | 
						|
   * @param listener The new listener to add
 | 
						|
   */
 | 
						|
  public void addListSelectionListener(ListSelectionListener listener)
 | 
						|
  {
 | 
						|
    listenerList.add (ListSelectionListener.class, listener);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Removes a {@link ListSelectionListener} from the listener list for
 | 
						|
   * this list. The listener will no longer be called when the list's
 | 
						|
   * {@link #selectionModel} changes.
 | 
						|
   *
 | 
						|
   * @param listener The listener to remove
 | 
						|
   */
 | 
						|
  public void removeListSelectionListener(ListSelectionListener listener)
 | 
						|
  {
 | 
						|
    listenerList.remove(ListSelectionListener.class, listener);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Returns an array of all ListSelectionListeners subscribed to this
 | 
						|
   * list.
 | 
						|
   *
 | 
						|
   * @return The current subscribed listeners
 | 
						|
   *
 | 
						|
   * @since 1.4
 | 
						|
   */
 | 
						|
  public ListSelectionListener[] getListSelectionListeners()
 | 
						|
  {
 | 
						|
    return (ListSelectionListener[]) getListeners(ListSelectionListener.class);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Returns the selection mode for the list (one of:
 | 
						|
   * {@link ListSelectionModel#SINGLE_SELECTION},
 | 
						|
   * {@link ListSelectionModel#SINGLE_INTERVAL_SELECTION} and
 | 
						|
   * {@link ListSelectionModel#MULTIPLE_INTERVAL_SELECTION}).
 | 
						|
   *
 | 
						|
   * @return The selection mode.
 | 
						|
   *
 | 
						|
   * @see #setSelectionMode(int)
 | 
						|
   */
 | 
						|
  public int getSelectionMode()
 | 
						|
  {
 | 
						|
    return selectionModel.getSelectionMode();
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Sets the list's "selectionMode" property, which simply mirrors the
 | 
						|
   * same property on the list's {@link #selectionModel} property. This
 | 
						|
   * property should be one of the integer constants
 | 
						|
   * <code>SINGLE_SELECTION</code>, <code>SINGLE_INTERVAL_SELECTION</code>,
 | 
						|
   * or <code>MULTIPLE_INTERVAL_SELECTION</code> from the {@link
 | 
						|
   * ListSelectionModel} interface.
 | 
						|
   *
 | 
						|
   * @param a The new selection mode
 | 
						|
   */
 | 
						|
  public void setSelectionMode(int a)
 | 
						|
  {
 | 
						|
    selectionModel.setSelectionMode(a);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Adds the interval <code>[a,a]</code> to the set of selections managed
 | 
						|
   * by this list's {@link #selectionModel} property. Depending on the
 | 
						|
   * selection mode, this may cause existing selections to become invalid,
 | 
						|
   * or may simply expand the set of selections.
 | 
						|
   *
 | 
						|
   * @param a A number in the half-open range <code>[0, x)</code> where
 | 
						|
   * <code>x = getModel.getSize()</code>, indicating the index of an
 | 
						|
   * element in the list to select. When < 0 the selection is cleared.
 | 
						|
   *
 | 
						|
   * @see #setSelectionMode
 | 
						|
   * @see #selectionModel
 | 
						|
   */
 | 
						|
  public void setSelectedIndex(int a)
 | 
						|
  {
 | 
						|
    if (a < 0)
 | 
						|
      selectionModel.clearSelection();
 | 
						|
    else
 | 
						|
      selectionModel.setSelectionInterval(a, a);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * For each element <code>a[i]</code> of the provided array
 | 
						|
   * <code>a</code>, calls {@link #setSelectedIndex} on <code>a[i]</code>.
 | 
						|
   *
 | 
						|
   * @param a  an array of selected indices (<code>null</code> not permitted).
 | 
						|
   *
 | 
						|
   * @throws NullPointerException if <code>a</code> is <code>null</code>.
 | 
						|
   * @see #setSelectionMode
 | 
						|
   * @see #selectionModel
 | 
						|
   */
 | 
						|
  public void setSelectedIndices(int [] a)
 | 
						|
  {
 | 
						|
    for (int i = 0; i < a.length; ++i)
 | 
						|
      setSelectedIndex(a[i]);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Returns the minimum index of an element in the list which is currently
 | 
						|
   * selected.
 | 
						|
   *
 | 
						|
   * @return A number in the half-open range <code>[0, x)</code> where
 | 
						|
   * <code>x = getModel.getSize()</code>, indicating the minimum index of
 | 
						|
   * an element in the list for which the element is selected, or
 | 
						|
   * <code>-1</code> if no elements are selected
 | 
						|
   */
 | 
						|
  public int getSelectedIndex()
 | 
						|
  {
 | 
						|
    return selectionModel.getMinSelectionIndex();
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Returns <code>true</code> if the model's selection is empty, otherwise
 | 
						|
   * <code>false</code>.
 | 
						|
   *
 | 
						|
   * @return The return value of {@link ListSelectionModel#isSelectionEmpty}
 | 
						|
   */
 | 
						|
  public boolean isSelectionEmpty()
 | 
						|
  {
 | 
						|
    return selectionModel.isSelectionEmpty();
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Returns the list index of the upper left or upper right corner of the
 | 
						|
   * visible rectangle of this list, depending on the {@link
 | 
						|
   * Component#getComponentOrientation} property.
 | 
						|
   *
 | 
						|
   * @return The index of the first visible list cell, or <code>-1</code>
 | 
						|
   * if none is visible.
 | 
						|
   */
 | 
						|
  public int getFirstVisibleIndex()
 | 
						|
  {
 | 
						|
    ComponentOrientation or = getComponentOrientation();
 | 
						|
    Rectangle r = getVisibleRect();
 | 
						|
    if (or == ComponentOrientation.RIGHT_TO_LEFT)
 | 
						|
      r.translate((int) r.getWidth() - 1, 0);
 | 
						|
    return getUI().locationToIndex(this, r.getLocation());
 | 
						|
  }
 | 
						|
 | 
						|
 | 
						|
  /**
 | 
						|
   * Returns index of the cell to which specified location is closest to. If
 | 
						|
   * the location is outside the bounds of the list, then the greatest index
 | 
						|
   * in the list model is returned. If the list model is empty, then
 | 
						|
   * <code>-1</code> is returned.
 | 
						|
   *
 | 
						|
   * @param location for which to look for in the list
 | 
						|
   *
 | 
						|
   * @return index of the cell to which specified location is closest to.
 | 
						|
   */
 | 
						|
   public int locationToIndex(Point location)
 | 
						|
   {
 | 
						|
     return getUI().locationToIndex(this, location);
 | 
						|
   }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Returns location of the cell located at the specified index in the list.
 | 
						|
   * @param index of the cell for which location will be determined
 | 
						|
   *
 | 
						|
   * @return location of the cell located at the specified index in the list.
 | 
						|
   */
 | 
						|
   public Point indexToLocation(int index)
 | 
						|
   {
 | 
						|
     return getUI().indexToLocation(this, index);
 | 
						|
   }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Returns the list index of the lower right or lower left corner of the
 | 
						|
   * visible rectangle of this list, depending on the {@link
 | 
						|
   * Component#getComponentOrientation} property.
 | 
						|
   *
 | 
						|
   * @return The index of the last visible list cell, or <code>-1</code>
 | 
						|
   * if none is visible.
 | 
						|
   */
 | 
						|
  public int getLastVisibleIndex()
 | 
						|
  {
 | 
						|
    ComponentOrientation or = getComponentOrientation();
 | 
						|
    Rectangle r = getVisibleRect();
 | 
						|
    r.translate(0, (int) r.getHeight() - 1);
 | 
						|
    if (or == ComponentOrientation.LEFT_TO_RIGHT)
 | 
						|
      r.translate((int) r.getWidth() - 1, 0);
 | 
						|
    if (getUI().locationToIndex(this, r.getLocation()) == -1
 | 
						|
        && indexToLocation(getModel().getSize() - 1).y < r.y)
 | 
						|
      return getModel().getSize() - 1;
 | 
						|
    return getUI().locationToIndex(this, r.getLocation());
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Returns the indices of values in the {@link #model} property which are
 | 
						|
   * selected.
 | 
						|
   *
 | 
						|
   * @return An array of model indices, each of which is selected according
 | 
						|
   *         to the {@link #getSelectedValues} property
 | 
						|
   */
 | 
						|
  public int[] getSelectedIndices()
 | 
						|
  {
 | 
						|
    int lo, hi, n, i, j;
 | 
						|
    if (selectionModel.isSelectionEmpty())
 | 
						|
      return new int[0];
 | 
						|
    lo = selectionModel.getMinSelectionIndex();
 | 
						|
    hi = selectionModel.getMaxSelectionIndex();
 | 
						|
    n = 0;
 | 
						|
    for (i = lo; i <= hi; ++i)
 | 
						|
      if (selectionModel.isSelectedIndex(i))
 | 
						|
        n++;
 | 
						|
    int [] v = new int[n];
 | 
						|
    j = 0;
 | 
						|
    for (i = lo; i <= hi; ++i)
 | 
						|
      if (selectionModel.isSelectedIndex(i))
 | 
						|
        v[j++] = i;
 | 
						|
    return v;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Indicates whether the list element at a given index value is
 | 
						|
   * currently selected.
 | 
						|
   *
 | 
						|
   * @param a The index to check
 | 
						|
   * @return <code>true</code> if <code>a</code> is the index of a selected
 | 
						|
   * list element
 | 
						|
   */
 | 
						|
  public boolean isSelectedIndex(int a)
 | 
						|
  {
 | 
						|
    return selectionModel.isSelectedIndex(a);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Returns the first value in the list's {@link #model} property which is
 | 
						|
   * selected, according to the list's {@link #selectionModel} property.
 | 
						|
   * This is equivalent to calling
 | 
						|
   * <code>getModel()getElementAt(getSelectedIndex())</code>, with a check
 | 
						|
   * for the special index value of <code>-1</code> which returns null
 | 
						|
   * <code>null</code>.
 | 
						|
   *
 | 
						|
   * @return The first selected element, or <code>null</code> if no element
 | 
						|
   * is selected.
 | 
						|
   *
 | 
						|
   * @see #getSelectedValues
 | 
						|
   */
 | 
						|
  public Object getSelectedValue()
 | 
						|
  {
 | 
						|
    int index = getSelectedIndex();
 | 
						|
    if (index == -1)
 | 
						|
      return null;
 | 
						|
    return getModel().getElementAt(index);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Returns all the values in the list's {@link #model} property which are
 | 
						|
   * selected, according to the list's {@link #selectionModel} property.
 | 
						|
   *
 | 
						|
   * @return An array containing all the selected values
 | 
						|
   * @see #setSelectedValue
 | 
						|
   */
 | 
						|
  public Object[] getSelectedValues()
 | 
						|
  {
 | 
						|
    int[] idx = getSelectedIndices();
 | 
						|
    Object[] v = new Object[idx.length];
 | 
						|
    for (int i = 0; i < idx.length; ++i)
 | 
						|
      v[i] = getModel().getElementAt(idx[i]);
 | 
						|
    return v;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Gets the value of the {@link #selectionBackground} property.
 | 
						|
   *
 | 
						|
   * @return The current value of the property
 | 
						|
   */
 | 
						|
  public Color getSelectionBackground()
 | 
						|
  {
 | 
						|
    return selectionBackground;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Sets the value of the {@link #selectionBackground} property.
 | 
						|
   *
 | 
						|
   * @param c The new value of the property
 | 
						|
   */
 | 
						|
  public void setSelectionBackground(Color c)
 | 
						|
  {
 | 
						|
    if (selectionBackground == c)
 | 
						|
      return;
 | 
						|
 | 
						|
    Color old = selectionBackground;
 | 
						|
    selectionBackground = c;
 | 
						|
    firePropertyChange("selectionBackground", old, c);
 | 
						|
    repaint();
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Gets the value of the {@link #selectionForeground} property.
 | 
						|
   *
 | 
						|
   * @return The current value of the property
 | 
						|
   */
 | 
						|
  public Color getSelectionForeground()
 | 
						|
  {
 | 
						|
    return selectionForeground;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Sets the value of the {@link #selectionForeground} property.
 | 
						|
   *
 | 
						|
   * @param c The new value of the property
 | 
						|
   */
 | 
						|
  public void setSelectionForeground(Color c)
 | 
						|
  {
 | 
						|
    if (selectionForeground == c)
 | 
						|
      return;
 | 
						|
 | 
						|
    Color old = selectionForeground;
 | 
						|
    selectionForeground = c;
 | 
						|
    firePropertyChange("selectionForeground", old, c);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Sets the selection to cover only the specified value, if it
 | 
						|
   * exists in the model.
 | 
						|
   *
 | 
						|
   * @param obj The object to select
 | 
						|
   * @param scroll Whether to scroll the list to make the newly selected
 | 
						|
   * value visible
 | 
						|
   *
 | 
						|
   * @see #ensureIndexIsVisible
 | 
						|
   */
 | 
						|
 | 
						|
  public void setSelectedValue(Object obj, boolean scroll)
 | 
						|
  {
 | 
						|
    for (int i = 0; i < model.getSize(); ++i)
 | 
						|
      {
 | 
						|
        if (model.getElementAt(i).equals(obj))
 | 
						|
          {
 | 
						|
            setSelectedIndex(i);
 | 
						|
            if (scroll)
 | 
						|
              ensureIndexIsVisible(i);
 | 
						|
            break;
 | 
						|
          }
 | 
						|
      }
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Scrolls this list to make the specified cell visible. This
 | 
						|
   * only works if the list is contained within a viewport.
 | 
						|
   *
 | 
						|
   * @param i The list index to make visible
 | 
						|
   *
 | 
						|
   * @see JComponent#scrollRectToVisible
 | 
						|
   */
 | 
						|
  public void ensureIndexIsVisible(int i)
 | 
						|
  {
 | 
						|
    Rectangle r = getUI().getCellBounds(this, i, i);
 | 
						|
    if (r != null)
 | 
						|
      scrollRectToVisible(r);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Sets the {@link #model} property of the list to a new anonymous
 | 
						|
   * {@link AbstractListModel} subclass which accesses the provided Object
 | 
						|
   * array directly.
 | 
						|
   *
 | 
						|
   * @param listData The object array to build a new list model on
 | 
						|
   * @see #setModel
 | 
						|
   */
 | 
						|
  public void setListData(Object[] listData)
 | 
						|
  {
 | 
						|
    setModel(createListModel(listData));
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Returns a {@link ListModel} backed by the specified array.
 | 
						|
   *
 | 
						|
   * @param items  the list items (don't use <code>null</code>).
 | 
						|
   *
 | 
						|
   * @return A list model containing the specified items.
 | 
						|
   */
 | 
						|
  private ListModel createListModel(final Object[] items)
 | 
						|
  {
 | 
						|
    return new AbstractListModel()
 | 
						|
      {
 | 
						|
        public int getSize()
 | 
						|
        {
 | 
						|
          return items.length;
 | 
						|
        }
 | 
						|
        public Object getElementAt(int i)
 | 
						|
        {
 | 
						|
          return items[i];
 | 
						|
        }
 | 
						|
      };
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Returns a {@link ListModel} backed by the specified vector.
 | 
						|
   *
 | 
						|
   * @param items  the list items (don't use <code>null</code>).
 | 
						|
   *
 | 
						|
   * @return A list model containing the specified items.
 | 
						|
   */
 | 
						|
  private ListModel createListModel(final Vector items)
 | 
						|
  {
 | 
						|
    return new AbstractListModel()
 | 
						|
      {
 | 
						|
        public int getSize()
 | 
						|
        {
 | 
						|
          return items.size();
 | 
						|
        }
 | 
						|
        public Object getElementAt(int i)
 | 
						|
        {
 | 
						|
          return items.get(i);
 | 
						|
        }
 | 
						|
      };
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Sets the {@link #model} property of the list to a new anonymous {@link
 | 
						|
   * AbstractListModel} subclass which accesses the provided vector
 | 
						|
   * directly.
 | 
						|
   *
 | 
						|
   * @param listData The object array to build a new list model on
 | 
						|
   * @see #setModel
 | 
						|
   */
 | 
						|
  public void setListData(final Vector<?> listData)
 | 
						|
  {
 | 
						|
    setModel(new AbstractListModel()
 | 
						|
      {
 | 
						|
        public int getSize()
 | 
						|
        {
 | 
						|
          return listData.size();
 | 
						|
        }
 | 
						|
 | 
						|
        public Object getElementAt(int i)
 | 
						|
        {
 | 
						|
          return listData.elementAt(i);
 | 
						|
        }
 | 
						|
      });
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Gets the value of the {@link #cellRenderer} property.
 | 
						|
   *
 | 
						|
   * @return The current value of the property
 | 
						|
   */
 | 
						|
  public ListCellRenderer getCellRenderer()
 | 
						|
  {
 | 
						|
    return cellRenderer;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Sets the value of the {@link #getCellRenderer} property.
 | 
						|
   *
 | 
						|
   * @param renderer The new property value
 | 
						|
   */
 | 
						|
  public void setCellRenderer(ListCellRenderer renderer)
 | 
						|
  {
 | 
						|
    if (cellRenderer == renderer)
 | 
						|
      return;
 | 
						|
 | 
						|
    ListCellRenderer old = cellRenderer;
 | 
						|
    cellRenderer = renderer;
 | 
						|
    firePropertyChange("cellRenderer", old, renderer);
 | 
						|
    revalidate();
 | 
						|
    repaint();
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Gets the value of the {@link #model} property.
 | 
						|
   *
 | 
						|
   * @return The current value of the property
 | 
						|
   */
 | 
						|
  public ListModel getModel()
 | 
						|
  {
 | 
						|
    return model;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Sets the value of the {@link #model} property. The list's {@link
 | 
						|
   * #listListener} is unsubscribed from the existing model, if it exists,
 | 
						|
   * and re-subscribed to the new model.
 | 
						|
   *
 | 
						|
   * @param model  the new model (<code>null</code> not permitted).
 | 
						|
   *
 | 
						|
   * @throws IllegalArgumentException if <code>model</code> is
 | 
						|
   *         <code>null</code>.
 | 
						|
   */
 | 
						|
  public void setModel(ListModel model)
 | 
						|
  {
 | 
						|
    if (model == null)
 | 
						|
      throw new IllegalArgumentException("Null 'model' argument.");
 | 
						|
    if (this.model == model)
 | 
						|
      return;
 | 
						|
 | 
						|
    if (this.model != null)
 | 
						|
      this.model.removeListDataListener(listListener);
 | 
						|
 | 
						|
    ListModel old = this.model;
 | 
						|
    this.model = model;
 | 
						|
 | 
						|
    if (this.model != null)
 | 
						|
      this.model.addListDataListener(listListener);
 | 
						|
 | 
						|
    firePropertyChange("model", old, model);
 | 
						|
    revalidate();
 | 
						|
    repaint();
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Returns the selection model for the {@link JList} component.  Note that
 | 
						|
   * this class contains a range of convenience methods for configuring the
 | 
						|
   * selection model:<br>
 | 
						|
   * <ul>
 | 
						|
   *   <li>{@link #clearSelection()};</li>
 | 
						|
   *   <li>{@link #setSelectionMode(int)};</li>
 | 
						|
   *   <li>{@link #addSelectionInterval(int, int)};</li>
 | 
						|
   *   <li>{@link #setSelectedIndex(int)};</li>
 | 
						|
   *   <li>{@link #setSelectedIndices(int[])};</li>
 | 
						|
   *   <li>{@link #setSelectionInterval(int, int)}.</li>
 | 
						|
   * </ul>
 | 
						|
   *
 | 
						|
   * @return The selection model.
 | 
						|
   */
 | 
						|
  public ListSelectionModel getSelectionModel()
 | 
						|
  {
 | 
						|
    return selectionModel;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Sets the value of the {@link #selectionModel} property. The list's
 | 
						|
   * {@link #listListener} is unsubscribed from the existing selection
 | 
						|
   * model, if it exists, and re-subscribed to the new selection model.
 | 
						|
   *
 | 
						|
   * @param model The new property value
 | 
						|
   */
 | 
						|
  public void setSelectionModel(ListSelectionModel model)
 | 
						|
  {
 | 
						|
    if (selectionModel == model)
 | 
						|
      return;
 | 
						|
 | 
						|
    if (selectionModel != null)
 | 
						|
      selectionModel.removeListSelectionListener(listListener);
 | 
						|
 | 
						|
    ListSelectionModel old = selectionModel;
 | 
						|
    selectionModel = model;
 | 
						|
 | 
						|
    if (selectionModel != null)
 | 
						|
      selectionModel.addListSelectionListener(listListener);
 | 
						|
 | 
						|
    firePropertyChange("selectionModel", old, model);
 | 
						|
    revalidate();
 | 
						|
    repaint();
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Gets the value of the UI property.
 | 
						|
   *
 | 
						|
   * @return The current property value
 | 
						|
   */
 | 
						|
  public ListUI getUI()
 | 
						|
  {
 | 
						|
    return (ListUI) ui;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Sets the value of the UI property.
 | 
						|
   *
 | 
						|
   * @param ui The new property value
 | 
						|
   */
 | 
						|
  public void setUI(ListUI ui)
 | 
						|
  {
 | 
						|
    super.setUI(ui);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Calls {@link #setUI} with the {@link ListUI} subclass
 | 
						|
   * returned from calling {@link UIManager#getUI}.
 | 
						|
   */
 | 
						|
  public void updateUI()
 | 
						|
  {
 | 
						|
    setUI((ListUI) UIManager.getUI(this));
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Return the class identifier for the list's UI property.  This should
 | 
						|
   * be the constant string <code>"ListUI"</code>, and map to an
 | 
						|
   * appropriate UI class in the {@link UIManager}.
 | 
						|
   *
 | 
						|
   * @return The class identifier
 | 
						|
   */
 | 
						|
  public String getUIClassID()
 | 
						|
  {
 | 
						|
    return "ListUI";
 | 
						|
  }
 | 
						|
 | 
						|
 | 
						|
  /**
 | 
						|
   * Returns the current value of the {@link #prototypeCellValue}
 | 
						|
   * property. This property holds a reference to a "prototype" data value
 | 
						|
   * -- typically a String -- which is used to calculate the {@link
 | 
						|
   * #fixedCellWidth} and {@link #fixedCellHeight} properties, using the
 | 
						|
   * {@link #cellRenderer} property to acquire a component to render the
 | 
						|
   * prototype.
 | 
						|
   *
 | 
						|
   * @return The current prototype cell value
 | 
						|
   * @see #setPrototypeCellValue
 | 
						|
   */
 | 
						|
  public Object getPrototypeCellValue()
 | 
						|
  {
 | 
						|
    return prototypeCellValue;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * <p>Set the {@link #prototypeCellValue} property. This property holds a
 | 
						|
   * reference to a "prototype" data value -- typically a String -- which
 | 
						|
   * is used to calculate the {@link #fixedCellWidth} and {@link
 | 
						|
   * #fixedCellHeight} properties, using the {@link #cellRenderer} property
 | 
						|
   * to acquire a component to render the prototype.</p>
 | 
						|
   *
 | 
						|
   * <p>It is important that you <em>not</em> set this value to a
 | 
						|
   * component. It has to be a <em>data value</em> such as the objects you
 | 
						|
   * would find in the list's model. Setting it to a component will have
 | 
						|
   * undefined (and undesirable) affects. </p>
 | 
						|
   *
 | 
						|
   * @param obj The new prototype cell value
 | 
						|
   * @see #getPrototypeCellValue
 | 
						|
   */
 | 
						|
  public void setPrototypeCellValue(Object obj)
 | 
						|
  {
 | 
						|
    if (prototypeCellValue == obj)
 | 
						|
      return;
 | 
						|
 | 
						|
    Object old = prototypeCellValue;
 | 
						|
    Component comp = getCellRenderer()
 | 
						|
      .getListCellRendererComponent(this, obj, 0, false, false);
 | 
						|
    Dimension d = comp.getPreferredSize();
 | 
						|
    fixedCellWidth = d.width;
 | 
						|
    fixedCellHeight = d.height;
 | 
						|
    prototypeCellValue = obj;
 | 
						|
    firePropertyChange("prototypeCellValue", old, obj);
 | 
						|
  }
 | 
						|
 | 
						|
  public AccessibleContext getAccessibleContext()
 | 
						|
  {
 | 
						|
    return new AccessibleJList();
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Returns a size indicating how much space this list would like to
 | 
						|
   * consume, when contained in a scrollable viewport. This is part of the
 | 
						|
   * {@link Scrollable} interface, which interacts with {@link
 | 
						|
   * ScrollPaneLayout} and {@link JViewport} to define scrollable objects.
 | 
						|
   *
 | 
						|
   * @return The preferred size
 | 
						|
   */
 | 
						|
  public Dimension getPreferredScrollableViewportSize()
 | 
						|
  {
 | 
						|
    //If the layout orientation is not VERTICAL, then this will
 | 
						|
    //return the value from getPreferredSize. The current ListUI is
 | 
						|
    //expected to override getPreferredSize to return an appropriate value.
 | 
						|
    if (getLayoutOrientation() != VERTICAL)
 | 
						|
      return getPreferredSize();
 | 
						|
 | 
						|
    int size = getModel().getSize();
 | 
						|
 | 
						|
    // Trivial case: if fixedCellWidth and fixedCellHeight were set
 | 
						|
    // just use them
 | 
						|
    if (fixedCellHeight != -1 && fixedCellWidth != -1)
 | 
						|
      return new Dimension(fixedCellWidth, size * fixedCellHeight);
 | 
						|
 | 
						|
    // If the model is empty we use 16 * the number of visible rows
 | 
						|
    // for the height and either fixedCellWidth (if set) or 256
 | 
						|
    // for the width
 | 
						|
    if (size == 0)
 | 
						|
      {
 | 
						|
        if (fixedCellWidth == -1)
 | 
						|
          return new Dimension(256, 16 * getVisibleRowCount());
 | 
						|
        else
 | 
						|
          return new Dimension(fixedCellWidth, 16 * getVisibleRowCount());
 | 
						|
      }
 | 
						|
 | 
						|
    // Calculate the width: if fixedCellWidth was set use that, otherwise
 | 
						|
    // use the preferredWidth
 | 
						|
    int prefWidth;
 | 
						|
    if (fixedCellWidth != -1)
 | 
						|
      prefWidth = fixedCellWidth;
 | 
						|
    else
 | 
						|
      prefWidth = getPreferredSize().width;
 | 
						|
 | 
						|
    // Calculate the height: if fixedCellHeight was set use that, otherwise
 | 
						|
    // use the height of the first row multiplied by the number of visible
 | 
						|
    // rows
 | 
						|
    int prefHeight;
 | 
						|
    if (fixedCellHeight != -1)
 | 
						|
      prefHeight = fixedCellHeight;
 | 
						|
    else
 | 
						|
      prefHeight = getVisibleRowCount() * getCellBounds(0, 0).height;
 | 
						|
 | 
						|
    return new Dimension (prefWidth, prefHeight);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * <p>Return the number of pixels the list must scroll in order to move a
 | 
						|
   * "unit" of the list into the provided visible rectangle. When the
 | 
						|
   * provided direction is positive, the call describes a "downwards"
 | 
						|
   * scroll, which will be exposing a cell at a <em>greater</em> index in
 | 
						|
   * the list than those elements currently showing. Then the provided
 | 
						|
   * direction is negative, the call describes an "upwards" scroll, which
 | 
						|
   * will be exposing a cell at a <em>lesser</em> index in the list than
 | 
						|
   * those elements currently showing.</p>
 | 
						|
   *
 | 
						|
   * <p>If the provided orientation is <code>HORIZONTAL</code>, the above
 | 
						|
   * comments refer to "rightwards" for positive direction, and "leftwards"
 | 
						|
   * for negative.</p>
 | 
						|
   *
 | 
						|
   *
 | 
						|
   * @param visibleRect The rectangle to scroll an element into
 | 
						|
   * @param orientation One of the numeric consants <code>VERTICAL</code>
 | 
						|
   * or <code>HORIZONTAL</code>
 | 
						|
   * @param direction An integer indicating the scroll direction: positive means
 | 
						|
   * forwards (down, right), negative means backwards (up, left)
 | 
						|
   *
 | 
						|
   * @return The scrollable unit increment, in pixels
 | 
						|
   */
 | 
						|
  public int getScrollableUnitIncrement(Rectangle visibleRect,
 | 
						|
                                        int orientation, int direction)
 | 
						|
  {
 | 
						|
    int unit = -1;
 | 
						|
    if (orientation == SwingConstants.VERTICAL)
 | 
						|
      {
 | 
						|
        int row = getFirstVisibleIndex();
 | 
						|
        if (row == -1)
 | 
						|
          unit = 0;
 | 
						|
        else if (direction > 0)
 | 
						|
          {
 | 
						|
            // Scrolling down.
 | 
						|
            Rectangle bounds = getCellBounds(row, row);
 | 
						|
            if (bounds != null)
 | 
						|
              unit = bounds.height - (visibleRect.y - bounds.y);
 | 
						|
            else
 | 
						|
              unit = 0;
 | 
						|
          }
 | 
						|
        else
 | 
						|
          {
 | 
						|
            // Scrolling up.
 | 
						|
            Rectangle bounds = getCellBounds(row, row);
 | 
						|
            // First row.
 | 
						|
            if (row == 0 && bounds.y == visibleRect.y)
 | 
						|
              unit = 0; // No need to scroll.
 | 
						|
            else if (bounds.y == visibleRect.y)
 | 
						|
              {
 | 
						|
                // Scroll to previous row.
 | 
						|
                Point loc = bounds.getLocation();
 | 
						|
                loc.y--;
 | 
						|
                int prev = locationToIndex(loc);
 | 
						|
                Rectangle prevR = getCellBounds(prev, prev);
 | 
						|
                if (prevR == null || prevR.y >= bounds.y)
 | 
						|
                  unit = 0; // For multicolumn lists.
 | 
						|
                else
 | 
						|
                  unit = prevR.height;
 | 
						|
              }
 | 
						|
            else
 | 
						|
              unit = visibleRect.y - bounds.y;
 | 
						|
          }
 | 
						|
      }
 | 
						|
    else if (orientation == SwingConstants.HORIZONTAL && getLayoutOrientation() != VERTICAL)
 | 
						|
      {
 | 
						|
        // Horizontal scrolling.
 | 
						|
        int i = locationToIndex(visibleRect.getLocation());
 | 
						|
        if (i != -1)
 | 
						|
          {
 | 
						|
            Rectangle b = getCellBounds(i, i);
 | 
						|
            if (b != null)
 | 
						|
              {
 | 
						|
                if (b.x != visibleRect.x)
 | 
						|
                  {
 | 
						|
                    if (direction < 0)
 | 
						|
                      unit = Math.abs(b.x - visibleRect.x);
 | 
						|
                    else
 | 
						|
                      unit = b.width + b.x - visibleRect.x;
 | 
						|
                  }
 | 
						|
                else
 | 
						|
                  unit = b.width;
 | 
						|
              }
 | 
						|
          }
 | 
						|
      }
 | 
						|
 | 
						|
    if (unit == -1)
 | 
						|
      {
 | 
						|
        // This fallback seems to be used by the RI for the degenerate cases
 | 
						|
        // not covered above.
 | 
						|
        Font f = getFont();
 | 
						|
        unit = f != null ? f.getSize() : 1;
 | 
						|
      }
 | 
						|
    return unit;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * <p>Return the number of pixels the list must scroll in order to move a
 | 
						|
   * "block" of the list into the provided visible rectangle. When the
 | 
						|
   * provided direction is positive, the call describes a "downwards"
 | 
						|
   * scroll, which will be exposing a cell at a <em>greater</em> index in
 | 
						|
   * the list than those elements currently showing. Then the provided
 | 
						|
   * direction is negative, the call describes an "upwards" scroll, which
 | 
						|
   * will be exposing a cell at a <em>lesser</em> index in the list than
 | 
						|
   * those elements currently showing.</p>
 | 
						|
   *
 | 
						|
   * <p>If the provided orientation is <code>HORIZONTAL</code>, the above
 | 
						|
   * comments refer to "rightwards" for positive direction, and "leftwards"
 | 
						|
   * for negative.</p>
 | 
						|
   *
 | 
						|
   *
 | 
						|
   * @param visibleRect The rectangle to scroll an element into
 | 
						|
   * @param orientation One of the numeric consants <code>VERTICAL</code>
 | 
						|
   * or <code>HORIZONTAL</code>
 | 
						|
   * @param direction An integer indicating the scroll direction: positive means
 | 
						|
   * forwards (down, right), negative means backwards (up, left)
 | 
						|
   *
 | 
						|
   * @return The scrollable unit increment, in pixels
 | 
						|
   */
 | 
						|
  public int getScrollableBlockIncrement(Rectangle visibleRect,
 | 
						|
                                         int orientation, int direction)
 | 
						|
  {
 | 
						|
    int block = -1;
 | 
						|
    if (orientation == SwingConstants.VERTICAL)
 | 
						|
      {
 | 
						|
        // Default block scroll. Special cases are handled below for
 | 
						|
        // better usability.
 | 
						|
        block = visibleRect.height;
 | 
						|
        if (direction > 0)
 | 
						|
          {
 | 
						|
            // Scroll down.
 | 
						|
            // Scroll so that after scrolling the last line aligns with
 | 
						|
            // the lower boundary of the visible area.
 | 
						|
            Point p = new Point(visibleRect.x,
 | 
						|
                                visibleRect.y + visibleRect.height - 1);
 | 
						|
            int last = locationToIndex(p);
 | 
						|
            if (last != -1)
 | 
						|
              {
 | 
						|
                Rectangle lastR = getCellBounds(last, last);
 | 
						|
                if (lastR != null)
 | 
						|
                  {
 | 
						|
                    block = lastR.y - visibleRect.y;
 | 
						|
                    if (block == 0&& last < getModel().getSize() - 1)
 | 
						|
                      block = lastR.height;
 | 
						|
                  }
 | 
						|
              }
 | 
						|
          }
 | 
						|
        else
 | 
						|
          {
 | 
						|
            // Scroll up.
 | 
						|
            // Scroll so that after scrolling the first line aligns with
 | 
						|
            // the upper boundary of the visible area.
 | 
						|
            Point p = new Point(visibleRect.x,
 | 
						|
                                visibleRect.y - visibleRect.height);
 | 
						|
            int newFirst = locationToIndex(p);
 | 
						|
            if (newFirst != -1)
 | 
						|
              {
 | 
						|
                int first = getFirstVisibleIndex();
 | 
						|
                if (first == -1)
 | 
						|
                  first = locationToIndex(visibleRect.getLocation());
 | 
						|
                Rectangle newFirstR = getCellBounds(newFirst, newFirst);
 | 
						|
                Rectangle firstR = getCellBounds(first, first);
 | 
						|
                if (newFirstR != null && firstR != null)
 | 
						|
                  {
 | 
						|
                    // Search first item that would left the current first
 | 
						|
                    // item visible when scrolled to.
 | 
						|
                    while (newFirstR.y + visibleRect.height
 | 
						|
                           < firstR.y + firstR.height
 | 
						|
                           && newFirstR.y < firstR.y)
 | 
						|
                      {
 | 
						|
                        newFirst++;
 | 
						|
                        newFirstR = getCellBounds(newFirst, newFirst);
 | 
						|
                      }
 | 
						|
                    block = visibleRect.y - newFirstR.y;
 | 
						|
                    if (block <= 0 && newFirstR.y > 0)
 | 
						|
                      {
 | 
						|
                        newFirst--;
 | 
						|
                        newFirstR = getCellBounds(newFirst, newFirst);
 | 
						|
                        if (newFirstR != null)
 | 
						|
                          block = visibleRect.y - newFirstR.y;
 | 
						|
                      }
 | 
						|
                  }
 | 
						|
              }
 | 
						|
          }
 | 
						|
      }
 | 
						|
    else if (orientation == SwingConstants.HORIZONTAL
 | 
						|
             && getLayoutOrientation() != VERTICAL)
 | 
						|
      {
 | 
						|
        // Default block increment. Special cases are handled below for
 | 
						|
        // better usability.
 | 
						|
        block = visibleRect.width;
 | 
						|
        if (direction > 0)
 | 
						|
          {
 | 
						|
            // Scroll right.
 | 
						|
            Point p = new Point(visibleRect.x + visibleRect.width + 1,
 | 
						|
                                visibleRect.y);
 | 
						|
            int last = locationToIndex(p);
 | 
						|
            if (last != -1)
 | 
						|
              {
 | 
						|
                Rectangle lastR = getCellBounds(last, last);
 | 
						|
                if (lastR != null)
 | 
						|
                  {
 | 
						|
                    block = lastR.x  - visibleRect.x;
 | 
						|
                    if (block < 0)
 | 
						|
                      block += lastR.width;
 | 
						|
                    else if (block == 0 && last < getModel().getSize() - 1)
 | 
						|
                      block = lastR.width;
 | 
						|
                  }
 | 
						|
              }
 | 
						|
          }
 | 
						|
        else
 | 
						|
          {
 | 
						|
            // Scroll left.
 | 
						|
            Point p = new Point(visibleRect.x - visibleRect.width,
 | 
						|
                                visibleRect.y);
 | 
						|
            int first = locationToIndex(p);
 | 
						|
            if (first != -1)
 | 
						|
              {
 | 
						|
                Rectangle firstR = getCellBounds(first, first);
 | 
						|
                if (firstR != null)
 | 
						|
                  {
 | 
						|
                    if (firstR.x < visibleRect.x - visibleRect.width)
 | 
						|
                      {
 | 
						|
                        if (firstR.x + firstR.width > visibleRect.x)
 | 
						|
                          block = visibleRect.x - firstR.x;
 | 
						|
                        else
 | 
						|
                          block = visibleRect.x - firstR.x - firstR.width;
 | 
						|
                      }
 | 
						|
                    else
 | 
						|
                      block = visibleRect.x - firstR.x;
 | 
						|
                  }
 | 
						|
              }
 | 
						|
          }
 | 
						|
      }
 | 
						|
 | 
						|
    return block;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Gets the value of the <code>scrollableTracksViewportWidth</code> property.
 | 
						|
   *
 | 
						|
   * @return <code>true</code> if the viewport is larger (horizontally)
 | 
						|
   * than the list and the list should be expanded to fit the viewport;
 | 
						|
   * <code>false</code> if the viewport is smaller than the list and the
 | 
						|
   * list should scroll (horizontally) within the viewport
 | 
						|
   */
 | 
						|
  public boolean getScrollableTracksViewportWidth()
 | 
						|
  {
 | 
						|
    Component parent = getParent();
 | 
						|
    boolean retVal = false;
 | 
						|
    if (parent instanceof JViewport)
 | 
						|
      {
 | 
						|
        JViewport viewport = (JViewport) parent;
 | 
						|
        Dimension pref = getPreferredSize();
 | 
						|
        if (viewport.getSize().width > pref.width)
 | 
						|
          retVal = true;
 | 
						|
        if ((getLayoutOrientation() == HORIZONTAL_WRAP)
 | 
						|
            && (getVisibleRowCount() <= 0))
 | 
						|
          retVal = true;
 | 
						|
      }
 | 
						|
    return retVal;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Gets the value of the </code>scrollableTracksViewportWidth</code> property.
 | 
						|
   *
 | 
						|
   * @return <code>true</code> if the viewport is larger (vertically)
 | 
						|
   * than the list and the list should be expanded to fit the viewport;
 | 
						|
   * <code>false</code> if the viewport is smaller than the list and the
 | 
						|
   * list should scroll (vertically) within the viewport
 | 
						|
   */
 | 
						|
  public boolean getScrollableTracksViewportHeight()
 | 
						|
  {
 | 
						|
    Component parent = getParent();
 | 
						|
    boolean retVal = false;
 | 
						|
    if (parent instanceof JViewport)
 | 
						|
      {
 | 
						|
        JViewport viewport = (JViewport) parent;
 | 
						|
        Dimension pref = getPreferredSize();
 | 
						|
        if (viewport.getSize().height > pref.height)
 | 
						|
          retVal = true;
 | 
						|
        if ((getLayoutOrientation() == VERTICAL_WRAP)
 | 
						|
            && (getVisibleRowCount() <= 0))
 | 
						|
          retVal = true;
 | 
						|
      }
 | 
						|
    return retVal;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Returns the index of the anchor item in the current selection, or
 | 
						|
   * <code>-1</code> if there is no anchor item.
 | 
						|
   *
 | 
						|
   * @return The item index.
 | 
						|
   */
 | 
						|
  public int getAnchorSelectionIndex()
 | 
						|
  {
 | 
						|
    return selectionModel.getAnchorSelectionIndex();
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Returns the index of the lead item in the current selection, or
 | 
						|
   * <code>-1</code> if there is no lead item.
 | 
						|
   *
 | 
						|
   * @return The item index.
 | 
						|
   */
 | 
						|
  public int getLeadSelectionIndex()
 | 
						|
  {
 | 
						|
    return selectionModel.getLeadSelectionIndex();
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Returns the lowest item index in the current selection, or <code>-1</code>
 | 
						|
   * if there is no selection.
 | 
						|
   *
 | 
						|
   * @return The index.
 | 
						|
   *
 | 
						|
   * @see #getMaxSelectionIndex()
 | 
						|
   */
 | 
						|
  public int getMinSelectionIndex()
 | 
						|
  {
 | 
						|
    return selectionModel.getMinSelectionIndex();
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Returns the highest item index in the current selection, or
 | 
						|
   * <code>-1</code> if there is no selection.
 | 
						|
   *
 | 
						|
   * @return The index.
 | 
						|
   *
 | 
						|
   * @see #getMinSelectionIndex()
 | 
						|
   */
 | 
						|
  public int getMaxSelectionIndex()
 | 
						|
  {
 | 
						|
    return selectionModel.getMaxSelectionIndex();
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Clears the current selection.
 | 
						|
   */
 | 
						|
  public void clearSelection()
 | 
						|
  {
 | 
						|
    selectionModel.clearSelection();
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Sets the current selection to the items in the specified range (inclusive).
 | 
						|
   * Note that <code>anchor</code> can be less than, equal to, or greater than
 | 
						|
   * <code>lead</code>.
 | 
						|
   *
 | 
						|
   * @param anchor  the index of the anchor item.
 | 
						|
   * @param lead  the index of the anchor item.
 | 
						|
   */
 | 
						|
  public void setSelectionInterval(int anchor, int lead)
 | 
						|
  {
 | 
						|
    selectionModel.setSelectionInterval(anchor, lead);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Adds the specified interval to the current selection.  Note that
 | 
						|
   * <code>anchor</code> can be less than, equal to, or greater than
 | 
						|
   * <code>lead</code>.
 | 
						|
   *
 | 
						|
   * @param anchor  the index of the anchor item.
 | 
						|
   * @param lead  the index of the lead item.
 | 
						|
   */
 | 
						|
  public void addSelectionInterval(int anchor, int lead)
 | 
						|
  {
 | 
						|
    selectionModel.addSelectionInterval(anchor, lead);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Removes the specified interval from the current selection.  Note that
 | 
						|
   * <code>index0</code> can be less than, equal to, or greater than
 | 
						|
   * <code>index1</code>.
 | 
						|
   *
 | 
						|
   * @param index0  an index for one end of the range.
 | 
						|
   * @param index1  an index for the other end of the range.
 | 
						|
   */
 | 
						|
  public void removeSelectionInterval(int index0, int index1)
 | 
						|
  {
 | 
						|
    selectionModel.removeSelectionInterval(index0, index1);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Returns the <code>valueIsAdjusting</code> flag from the list's selection
 | 
						|
   * model.
 | 
						|
   *
 | 
						|
   * @return the value
 | 
						|
   */
 | 
						|
  public boolean getValueIsAdjusting()
 | 
						|
  {
 | 
						|
    return selectionModel.getValueIsAdjusting();
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Sets the <code>valueIsAdjusting</code> flag in the list's selection
 | 
						|
   * model.
 | 
						|
   *
 | 
						|
   * @param isAdjusting the new value
 | 
						|
   */
 | 
						|
  public void setValueIsAdjusting(boolean isAdjusting)
 | 
						|
  {
 | 
						|
    selectionModel.setValueIsAdjusting(isAdjusting);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Return the value of the <code>dragEnabled</code> property.
 | 
						|
   *
 | 
						|
   * @return the value
 | 
						|
   *
 | 
						|
   * @since 1.4
 | 
						|
   */
 | 
						|
  public boolean getDragEnabled()
 | 
						|
  {
 | 
						|
    return dragEnabled;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Set the <code>dragEnabled</code> property.
 | 
						|
   *
 | 
						|
   * @param enabled new value
 | 
						|
   *
 | 
						|
   * @since 1.4
 | 
						|
   */
 | 
						|
  public void setDragEnabled(boolean enabled)
 | 
						|
  {
 | 
						|
    dragEnabled = enabled;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Returns the layout orientation, which will be one of {@link #VERTICAL},
 | 
						|
   * {@link #VERTICAL_WRAP} and {@link #HORIZONTAL_WRAP}.  The default value
 | 
						|
   * is {@link #VERTICAL}.
 | 
						|
   *
 | 
						|
   * @return the orientation.
 | 
						|
   *
 | 
						|
   * @see #setLayoutOrientation(int)
 | 
						|
   * @since 1.4
 | 
						|
   */
 | 
						|
  public int getLayoutOrientation()
 | 
						|
  {
 | 
						|
    return layoutOrientation;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Sets the layout orientation (this is a bound property with the name
 | 
						|
   * 'layoutOrientation').  Valid orientations are {@link #VERTICAL},
 | 
						|
   * {@link #VERTICAL_WRAP} and {@link #HORIZONTAL_WRAP}.
 | 
						|
   *
 | 
						|
   * @param orientation the orientation.
 | 
						|
   *
 | 
						|
   * @throws IllegalArgumentException if <code>orientation</code> is not one
 | 
						|
   *     of the specified values.
 | 
						|
   * @since 1.4
 | 
						|
   * @see #getLayoutOrientation()
 | 
						|
   */
 | 
						|
  public void setLayoutOrientation(int orientation)
 | 
						|
  {
 | 
						|
    if (orientation < JList.VERTICAL || orientation > JList.HORIZONTAL_WRAP)
 | 
						|
      throw new IllegalArgumentException();
 | 
						|
    if (layoutOrientation == orientation)
 | 
						|
      return;
 | 
						|
 | 
						|
    int old = layoutOrientation;
 | 
						|
    layoutOrientation = orientation;
 | 
						|
    firePropertyChange("layoutOrientation", old, orientation);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Returns the bounds of the rectangle that encloses both list cells
 | 
						|
   * with index0 and index1.
 | 
						|
   *
 | 
						|
   * @param index0 the index of the first cell
 | 
						|
   * @param index1 the index of the second cell
 | 
						|
   *
 | 
						|
   * @return  the bounds of the rectangle that encloses both list cells
 | 
						|
   *     with index0 and index1, <code>null</code> if one of the indices is
 | 
						|
   *     not valid
 | 
						|
   */
 | 
						|
  public Rectangle getCellBounds(int index0, int index1)
 | 
						|
  {
 | 
						|
    ListUI ui = getUI();
 | 
						|
    Rectangle bounds = null;
 | 
						|
    if (ui != null)
 | 
						|
      {
 | 
						|
        bounds = ui.getCellBounds(this, index0, index1);
 | 
						|
      }
 | 
						|
    // When the UI is null, this method also returns null in the RI.
 | 
						|
    return bounds;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Returns the index of the next list element (beginning at
 | 
						|
   * <code>startIndex</code> and moving in the specified direction through the
 | 
						|
   * list, looping around if necessary) that starts with <code>prefix</code>
 | 
						|
   * (ignoring case).
 | 
						|
   *
 | 
						|
   * @param prefix the prefix to search for in the cell values
 | 
						|
   * @param startIndex the index where to start searching from
 | 
						|
   * @param direction the search direction, either {@link Position.Bias#Forward}
 | 
						|
   *     or {@link Position.Bias#Backward} (<code>null</code> is interpreted
 | 
						|
   *     as {@link Position.Bias#Backward}.
 | 
						|
   *
 | 
						|
   * @return the index of the found element or -1 if no such element has
 | 
						|
   *     been found
 | 
						|
   *
 | 
						|
   * @throws IllegalArgumentException if prefix is <code>null</code> or
 | 
						|
   *     startIndex is not valid
 | 
						|
   *
 | 
						|
   * @since 1.4
 | 
						|
   */
 | 
						|
  public int getNextMatch(String prefix, int startIndex,
 | 
						|
                          Position.Bias direction)
 | 
						|
  {
 | 
						|
    if (prefix == null)
 | 
						|
      throw new IllegalArgumentException("The argument 'prefix' must not be"
 | 
						|
                                         + " null.");
 | 
						|
    if (startIndex < 0)
 | 
						|
      throw new IllegalArgumentException("The argument 'startIndex' must not"
 | 
						|
                                         + " be less than zero.");
 | 
						|
 | 
						|
    int size = model.getSize();
 | 
						|
    if (startIndex >= model.getSize())
 | 
						|
      throw new IllegalArgumentException("The argument 'startIndex' must not"
 | 
						|
                                         + " be greater than the number of"
 | 
						|
                                         + " elements in the ListModel.");
 | 
						|
 | 
						|
    int result = -1;
 | 
						|
    int current = startIndex;
 | 
						|
    int delta = -1;
 | 
						|
    int itemCount = model.getSize();
 | 
						|
    boolean finished = false;
 | 
						|
    prefix = prefix.toUpperCase();
 | 
						|
 | 
						|
    if (direction == Position.Bias.Forward)
 | 
						|
      delta = 1;
 | 
						|
    while (!finished)
 | 
						|
      {
 | 
						|
        String itemStr = model.getElementAt(current).toString().toUpperCase();
 | 
						|
        if (itemStr.startsWith(prefix))
 | 
						|
          return current;
 | 
						|
        current = (current + delta);
 | 
						|
        if (current == -1)
 | 
						|
          current += itemCount;
 | 
						|
        else
 | 
						|
          current = current % itemCount;
 | 
						|
        finished = current == startIndex;
 | 
						|
      }
 | 
						|
    return result;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Returns a string describing the attributes for the <code>JList</code>
 | 
						|
   * component, for use in debugging.  The return value is guaranteed to be
 | 
						|
   * non-<code>null</code>, but the format of the string may vary between
 | 
						|
   * implementations.
 | 
						|
   *
 | 
						|
   * @return A string describing the attributes of the <code>JList</code>.
 | 
						|
   */
 | 
						|
  protected String paramString()
 | 
						|
  {
 | 
						|
    CPStringBuilder sb = new CPStringBuilder(super.paramString());
 | 
						|
    sb.append(",fixedCellHeight=").append(getFixedCellHeight());
 | 
						|
    sb.append(",fixedCellWidth=").append(getFixedCellWidth());
 | 
						|
    sb.append(",selectionBackground=");
 | 
						|
    if (getSelectionBackground() != null)
 | 
						|
      sb.append(getSelectionBackground());
 | 
						|
    sb.append(",selectionForeground=");
 | 
						|
    if (getSelectionForeground() != null)
 | 
						|
      sb.append(getSelectionForeground());
 | 
						|
    sb.append(",visibleRowCount=").append(getVisibleRowCount());
 | 
						|
    sb.append(",layoutOrientation=").append(getLayoutOrientation());
 | 
						|
    return sb.toString();
 | 
						|
  }
 | 
						|
}
 |