mirror of git://gcc.gnu.org/git/gcc.git
				
				
				
			
		
			
				
	
	
		
			592 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			Java
		
	
	
	
			
		
		
	
	
			592 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			Java
		
	
	
	
| /* DefaultListSelectionModel.java --
 | |
|    Copyright (C) 2002, 2004 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., 59 Temple Place, Suite 330, Boston, MA
 | |
| 02111-1307 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 java.io.Serializable;
 | |
| import java.util.BitSet;
 | |
| import java.util.EventListener;
 | |
| 
 | |
| import javax.swing.event.EventListenerList;
 | |
| import javax.swing.event.ListSelectionEvent;
 | |
| import javax.swing.event.ListSelectionListener;
 | |
| 
 | |
| /**
 | |
|  * <p>This class provides a default implementation of {@link
 | |
|  * ListSelectioModel}, which is used by {@link javax.swing.JList} and
 | |
|  * similar classes to manage the selection status of a number of data
 | |
|  * elements. </p>
 | |
|  *
 | |
|  * <p>The class is organized <em>abstractly</em> as a set of intervals of
 | |
|  * integers. Each interval indicates an inclusive range of indices in a
 | |
|  * list -- held by some other object and unknown to this class -- which is
 | |
|  * considered "selected". There are various accessors for querying and
 | |
|  * modifying the set of intervals, with simplified forms accepting a single
 | |
|  * index, representing an interval with only one element. </p>
 | |
|  */
 | |
| public class DefaultListSelectionModel implements Cloneable,
 | |
|                                                   ListSelectionModel,
 | |
|                                                   Serializable
 | |
| {
 | |
|   private static final long serialVersionUID = -5718799865110415860L;
 | |
| 
 | |
|   /** The list of ListSelectionListeners subscribed to this selection model. */
 | |
|   protected EventListenerList listenerList = new EventListenerList();
 | |
| 
 | |
| 
 | |
|   /** 
 | |
|    * The current list selection mode. Must be one of the numeric constants
 | |
|    * <code>SINGLE_SELECTION</code>, <code>SINGLE_INTERVAL_SELECTION</code>
 | |
|    * or <code>MULTIPLE_INTERVAL_SELECTION</code> from {@link
 | |
|    * ListSelectionModel}. The default value is
 | |
|    * <code>MULTIPLE_INTERVAL_SELECTION</code>.
 | |
|    */
 | |
|   int selectionMode = MULTIPLE_INTERVAL_SELECTION;
 | |
| 
 | |
| 
 | |
|   /**
 | |
|    * The index of the "lead" of the most recent selection. The lead is the
 | |
|    * second argument in any call to {@link #setSelectionInterval}, {@link
 | |
|    * #addSelectionInterval} or {@link #removeSelectionInterval}. Generally
 | |
|    * the lead refers to the most recent position a user dragged their mouse
 | |
|    * over.
 | |
|    */
 | |
|   int leadSelectionIndex = -1;
 | |
| 
 | |
| 
 | |
|   /**
 | |
|    * The index of the "anchor" of the most recent selection. The anchor is
 | |
|    * the first argument in any call to {@link #setSelectionInterval},
 | |
|    * {@link #addSelectionInterval} or {@link
 | |
|    * #removeSelectionInterval}. Generally the anchor refers to the first
 | |
|    * recent position a user clicks when they begin to drag their mouse over
 | |
|    * a list.
 | |
|    *
 | |
|    * @see #getAnchorSelectionIndex
 | |
|    * @see #setAnchorSelectionIndex
 | |
|    */
 | |
|   int anchorSelectionIndex = -1;
 | |
| 
 | |
| 
 | |
|   /**
 | |
|    * controls the range of indices provided in any {@link
 | |
|    * ListSelectionEvent} fired by the selectionModel. Let
 | |
|    * <code>[A,L]</code> be the range of indices between {@link
 | |
|    * anchorSelectionIndex} and {@link leadSelectionIndex} inclusive, and
 | |
|    * let <code>[i0,i1]</code> be the range of indices changed in a given
 | |
|    * call which generates a {@link ListSelectionEvent}. Then when this
 | |
|    * property is <code>true</code>, the {@link ListSelectionEvent} contains
 | |
|    * the range <code>[A,L] union [i0,i1]</code>; when <code>false</code> it
 | |
|    * will contain only <code>[i0,i1]</code>. The default is
 | |
|    * <code>true</code>.
 | |
|    *
 | |
|    * @see #isLeadAnchorNotificationEnabled
 | |
|    * @see #setLeadAnchorNotificationEnabled
 | |
|    */
 | |
|   boolean leadAnchorNotificationEnabled = true;
 | |
| 
 | |
| 
 | |
|   /**
 | |
|    * Whether the selection is currently "adjusting". Any {@link
 | |
|    * ListSelectionEvent} events constructed in response to changes in this
 | |
|    * list selection model will have their {@link
 | |
|    * ListSelectionEvent#isAdjusting} field set to this value.
 | |
|    *
 | |
|    * @see #getValueIsAdjusting
 | |
|    * @see #setValueIsAdjusting
 | |
|    */
 | |
|   boolean valueIsAdjusting = false;
 | |
| 
 | |
| 
 | |
|   /** 
 | |
|    * The current set of "intervals", represented simply by a {@link
 | |
|    * java.util.BitSet}. A set bit indicates a selected index, whereas a
 | |
|    * cleared bit indicates a non-selected index.
 | |
|    */
 | |
|   BitSet sel = new BitSet();
 | |
| 
 | |
| 
 | |
|   /**
 | |
|    * Gets the value of the {@link #selectionMode} property.
 | |
|    *
 | |
|    * @return The current value of the property
 | |
|    */
 | |
|   public int getSelectionMode()
 | |
|   {
 | |
|     return selectionMode;
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * Sets the value of the {@link #selectionMode} property.
 | |
|    *
 | |
|    * @param a The new value of the property
 | |
|    */
 | |
|   public void setSelectionMode(int a)
 | |
|   {
 | |
|     selectionMode = a;
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * Gets the value of the {@link #anchorSelectionIndex} property.
 | |
|    * 
 | |
|    * @return The current property value
 | |
|    *
 | |
|    * @see #setAnchorSelectionIndex
 | |
|    */
 | |
|   public int getAnchorSelectionIndex()
 | |
|   {
 | |
|     return anchorSelectionIndex;
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * Sets the value of the {@link #anchorSelectionIndex} property.
 | |
|    * 
 | |
|    * @param anchorIndex The new property value
 | |
|    *
 | |
|    * @see #getAnchorSelectionIndex
 | |
|    */
 | |
|   public void setAnchorSelectionIndex(int anchorIndex)
 | |
|   {
 | |
|     anchorSelectionIndex = anchorIndex;
 | |
|   }
 | |
|   
 | |
|   /**
 | |
|    * Gets the value of the {@link #leadSelectionIndex} property.
 | |
|    * 
 | |
|    * @return The current property value
 | |
|    *
 | |
|    * @see #setLeadSelectionIndex
 | |
|    */
 | |
|   public int getLeadSelectionIndex()
 | |
|   {
 | |
|     return leadSelectionIndex;
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * <p>Sets the value of the {@link #anchorSelectionIndex} property. As a
 | |
|    * side effect, alters the selection status of two ranges of indices. Let
 | |
|    * <code>OL</code> be the old lead selection index, <code>NL</code> be
 | |
|    * the new lead selection index, and <code>A</code> be the anchor
 | |
|    * selection index. Then if <code>A</code> is a valid selection index,
 | |
|    * one of two things happens depending on the seleciton status of
 | |
|    * <code>A</code>:</p>
 | |
|    *
 | |
|    * <ul>
 | |
|    *
 | |
|    * <li><code>isSelectedIndex(A) == true</code>: set <code>[A,OL]</code>
 | |
|    * to <em>deselected</em>, then set <code>[A,NL]</code> to
 | |
|    * <em>selected</em>.</li>
 | |
|    *
 | |
|    * <li><code>isSelectedIndex(A) == false</code>: set <code>[A,OL]</code>
 | |
|    * to <em>selected</em>, then set <code>[A,NL]</code> to
 | |
|    * <em>deselected</em>.</li>
 | |
|    *
 | |
|    * </ul>
 | |
|    *
 | |
|    * <p>This method generates at most a single {@link ListSelectionEvent}
 | |
|    * despite changing multiple ranges. The range of values provided to the
 | |
|    * {@link ListSelectionEvent} includes only the minimum range of values
 | |
|    * which changed selection status between the beginning and end of the
 | |
|    * method.</p>
 | |
|    * 
 | |
|    * @param anchorIndex The new property value
 | |
|    *
 | |
|    * @see #getAnchorSelectionIndex
 | |
|    */
 | |
|   public void setLeadSelectionIndex(int leadIndex)
 | |
|   {
 | |
|     int oldLeadIndex = leadSelectionIndex;
 | |
|     leadSelectionIndex = leadIndex;
 | |
| 
 | |
|     if (anchorSelectionIndex == -1)
 | |
|       return;
 | |
| 
 | |
|     int R1 = Math.min(anchorSelectionIndex, oldLeadIndex);
 | |
|     int R2 = Math.max(anchorSelectionIndex, oldLeadIndex);
 | |
|     int S1 = Math.min(anchorSelectionIndex, leadIndex);
 | |
|     int S2 = Math.max(anchorSelectionIndex, leadIndex);
 | |
|     
 | |
|     int lo = Math.min(R1, S1);
 | |
|     int hi = Math.max(R2, S2);
 | |
| 
 | |
|     BitSet oldRange = sel.get(lo, hi+1);
 | |
| 
 | |
|     if (isSelectedIndex(anchorSelectionIndex))
 | |
|       {
 | |
|         sel.clear(R1, R2+1);
 | |
|         sel.set(S1, S2+1);
 | |
|       }
 | |
|     else
 | |
|       {
 | |
|         sel.set(R1, R2+1);
 | |
|         sel.clear(S1, S2+1);
 | |
|       }
 | |
|     
 | |
|     BitSet newRange = sel.get(lo, hi+1);
 | |
|     newRange.xor(oldRange);
 | |
| 
 | |
|     int beg = sel.nextSetBit(0), end = -1;
 | |
|     for(int i=beg; i >= 0; i=sel.nextSetBit(i+1)) 
 | |
|       { 
 | |
|         end = i;
 | |
|       }
 | |
|     fireValueChanged(beg, end, valueIsAdjusting);    
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * Gets the value of the {@link #leadAnchorNotificationEnabled} property.
 | |
|    * 
 | |
|    * @return The current property value
 | |
|    *
 | |
|    * @see #setLeadAnchorNotificationEnabled
 | |
|    */
 | |
|   public boolean isLeadAnchorNotificationEnabled()
 | |
|   {
 | |
|     return leadAnchorNotificationEnabled;
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * Sets the value of the {@link #leadAnchorNotificationEnabled} property.
 | |
|    * 
 | |
|    * @param flag The new property value
 | |
|    *
 | |
|    * @see #getLeadAnchorNotificationEnabled
 | |
|    */
 | |
|   public void setLeadAnchorNotificationEnabled(boolean l)
 | |
|   {
 | |
|     leadAnchorNotificationEnabled = l;
 | |
|   }
 | |
| 
 | |
| 
 | |
|   /**
 | |
|    * Gets the value of the {@link #valueIsAdjusting} property.
 | |
|    *
 | |
|    * @return The current property value
 | |
|    *
 | |
|    * @see #setValueIsAdjusting
 | |
|    */
 | |
|   public boolean getValueIsAdjusting()
 | |
|   {
 | |
|     return valueIsAdjusting;
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * Sets the value of the {@link #valueIsAdjusting} property.
 | |
|    *
 | |
|    * @param v The new property value
 | |
|    *
 | |
|    * @see #getValueIsAdjusting
 | |
|    */
 | |
|   public void setValueIsAdjusting(boolean v)
 | |
|   {
 | |
|     valueIsAdjusting = v;
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * Determines whether the selection is empty.
 | |
|    *
 | |
|    * @return <code>true</code> if the selection is empty, otherwise
 | |
|    * <code>false</code>
 | |
|    */
 | |
|   public boolean isSelectionEmpty()
 | |
|   {
 | |
|     return sel.isEmpty();
 | |
|   }
 | |
| 
 | |
| 
 | |
|   /**
 | |
|    * Gets the smallest index which is currently a member of a selection
 | |
|    * interval.
 | |
|    *
 | |
|    * @return The least integer <code>i</code> such that <code>i >=
 | |
|    * 0</code> and <code>i</code> is a member of a selected interval, or
 | |
|    * <code>-1</code> if there are no selected intervals
 | |
|    *
 | |
|    * @see #getMaxSelectionIndex
 | |
|    */
 | |
|   public int getMinSelectionIndex()
 | |
|   {
 | |
|     if (isSelectionEmpty())
 | |
|       return -1;
 | |
|     
 | |
|     return sel.nextSetBit(0);
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * Gets the largest index which is currently a member of a selection
 | |
|    * interval.
 | |
|    *
 | |
|    * @return The greatest integer <code>i</code> such that <code>i >=
 | |
|    * 0</code> and <code>i</code> is a member of a selected interval, or
 | |
|    * <code>-1</code> if there are no selected intervals
 | |
|    *
 | |
|    * @see #getMinSelectionIndex
 | |
|    */
 | |
|   public int getMaxSelectionIndex()
 | |
|   {
 | |
|     if (isSelectionEmpty())
 | |
|       return -1;
 | |
| 
 | |
|     int mx = -1;
 | |
|     for(int i=sel.nextSetBit(0); i >= 0; i=sel.nextSetBit(i+1)) 
 | |
|       { 
 | |
|         mx = i;
 | |
|       }
 | |
|     return mx;
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * Determines whether a particular index is a member of a selection
 | |
|    * interval.
 | |
|    *
 | |
|    * @param a The index to search for
 | |
|    *
 | |
|    * @return <code>true</code> if the index is a member of a selection interval,
 | |
|    * otherwise <code>false</code>
 | |
|    */
 | |
|   public boolean isSelectedIndex(int a)
 | |
|   {
 | |
|     return sel.get(a);
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * If the {@link #selectionMode} property is equal to
 | |
|    * <code>SINGLE_SELECTION</code> or
 | |
|    * <code>SINGLE_INTERVAL_SELECTION</code>, equivalent to calling
 | |
|    * <code>setSelectionInterval(index1, index2)</code>; otherwise adds the
 | |
|    * range <code>[index0, index1]</code> to the selection interval set.
 | |
|    *
 | |
|    * @param index0 The beginning of the range of indices to select
 | |
|    * @param index1 The end of the range of indices to select
 | |
|    *
 | |
|    * @see #setSelectionInterval
 | |
|    * @see #removeSelectionInterval
 | |
|    */
 | |
|   public void addSelectionInterval(int index0, int index1) 
 | |
|   {
 | |
|     if (selectionMode == SINGLE_SELECTION
 | |
|         || selectionMode == SINGLE_INTERVAL_SELECTION)
 | |
|       sel.clear();
 | |
|     
 | |
|     if (selectionMode == SINGLE_SELECTION)
 | |
|       index0 = index1;
 | |
| 
 | |
|     int lo = Math.min(index0, index1);
 | |
|     int hi = Math.max(index0, index1);
 | |
| 
 | |
|     sel.set(lo, hi+1);
 | |
|     fireValueChanged(lo, hi, valueIsAdjusting);
 | |
|   }
 | |
| 
 | |
| 
 | |
|   /**
 | |
|    * Deselects all indices in the inclusive range
 | |
|    * <code>[index0,index1]</code>.
 | |
|    *
 | |
|    * @param index0 The beginning of the range of indices to deselect
 | |
|    * @param index1 The end of the range of indices to deselect
 | |
|    *
 | |
|    * @see #addSelectionInterval
 | |
|    * @see #setSelectionInterval
 | |
|    */
 | |
|   public void removeSelectionInterval(int index0,
 | |
|                                       int index1)
 | |
|   {
 | |
|     int lo = Math.min(index0, index1);
 | |
|     int hi = Math.max(index0, index1);
 | |
|     sel.clear(lo, hi+1); 
 | |
|     fireValueChanged(lo, hi, valueIsAdjusting);
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * Removes all intervals in the selection set.
 | |
|    */
 | |
|   public void clearSelection()
 | |
|   {
 | |
|     int sz = sel.size();
 | |
|     sel.clear();
 | |
|     fireValueChanged(0, sz, valueIsAdjusting);
 | |
|   }
 | |
|   
 | |
|   /**
 | |
|    * Clears the current selection and marks a given interval as
 | |
|    * "selected". If the current selection mode is
 | |
|    * <code>SINGLE_SELECTION</code> only the index <code>index2</code> is
 | |
|    * selected.
 | |
|    *
 | |
|    * @param index0 The low end of the new selection 
 | |
|    * @param index1 The high end of the new selection
 | |
|    */
 | |
|   public void setSelectionInterval(int index0, int index1)
 | |
|   {
 | |
|     sel.clear();
 | |
|     if (selectionMode == SINGLE_SELECTION)
 | |
|       index0 = index1;
 | |
| 
 | |
|     int lo = Math.min(index0, index1);
 | |
|     int hi = Math.max(index0, index1);
 | |
|     sel.set(lo, hi+1);
 | |
|     fireValueChanged(lo, hi, valueIsAdjusting);
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * Inserts a number of indices either before or after a particular
 | |
|    * position in the set of indices. Renumbers all indices after the
 | |
|    * inserted range. The new indices in the inserted range are not
 | |
|    * selected. This method is typically called to synchronize the selection
 | |
|    * model with an inserted range of elements in a {@link ListModel}.
 | |
|    *
 | |
|    * @param index The position to insert indices at
 | |
|    * @param length The number of indices to insert
 | |
|    * @param before Indicates whether to insert the indices before the index
 | |
|    * or after it
 | |
|    */
 | |
|   public void insertIndexInterval(int index,
 | |
|                                   int length,
 | |
|                                   boolean before)
 | |
|   {
 | |
|     if (!before)
 | |
|       {        
 | |
|         index++;
 | |
|         length--;
 | |
|       }
 | |
|     BitSet tmp = sel.get(index, sel.size());
 | |
|     sel.clear(index, sel.size());
 | |
|     int n = tmp.size();
 | |
|     for (int i = 0; i < n; ++i)
 | |
|       sel.set(index + length + i, tmp.get(i));
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * Removes a range from the set of indices. Renumbers all indices after
 | |
|    * the removed range. This method is typically called to synchronize the
 | |
|    * selection model with a deleted range of elements in a {@link
 | |
|    * ListModel}.
 | |
|    *
 | |
|    * @param index0 The first index to remove (inclusive)
 | |
|    * @param index1 The last index to remove (inclusive)
 | |
|    */
 | |
|   public void removeIndexInterval(int index0,
 | |
|                                   int index1)
 | |
|   {
 | |
|     int lo = Math.min(index0, index1);
 | |
|     int hi = Math.max(index0, index1);
 | |
| 
 | |
|     BitSet tmp = sel.get(hi, sel.size());
 | |
|     sel.clear(lo, sel.size());
 | |
|     int n = tmp.size();
 | |
|     for (int i = 0; i < n; ++i)
 | |
|       sel.set(lo + i, tmp.get(i));
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * Fires a {@link ListSelectionEvent} to all the listeners of type {@link
 | |
|    * ListSelectionListener} registered with this selection model.
 | |
|    *
 | |
|    * @param firstIndex The low index of the changed range
 | |
|    * @param lastIndex The high index of the changed range
 | |
|    * @param isAdjusting Whether this change is part of a seqence of adjustments
 | |
|    * made to the selection, such as during interactive scrolling
 | |
|    */
 | |
|   protected void fireValueChanged(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);
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * Adds a listener.
 | |
|    *
 | |
|    * @param listener The listener to add
 | |
|    *
 | |
|    * @see removeListSelectionListener
 | |
|    * @see getListSelectionListeners
 | |
|    */
 | |
|   public void addListSelectionListener(ListSelectionListener listener)
 | |
|   {
 | |
|     listenerList.add(ListSelectionListener.class, listener);
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * Removes a registered listener.
 | |
|    *
 | |
|    * @param listener The listener to remove
 | |
|    *
 | |
|    * @see addListSelectionListener
 | |
|    * @see getListSelectionListeners
 | |
|    */
 | |
|   public void removeListSelectionListener(ListSelectionListener listener)
 | |
|   {
 | |
|     listenerList.remove(ListSelectionListener.class, listener);
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * Returns an array of all registerers listeners.
 | |
|    *
 | |
|    * @param listenerType The type of listener to retrieve
 | |
|    *
 | |
|    * @return The array
 | |
|    *
 | |
|    * @see getListSelectionListener
 | |
|    * @since 1.3
 | |
|    */
 | |
|   public EventListener[] getListeners(Class listenerType)
 | |
|   {
 | |
|     return listenerList.getListeners(listenerType);
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * Returns an array of all registerd list selection listeners.
 | |
|    *
 | |
|    * @return the array
 | |
|    *
 | |
|    * @see addListSelectionListener
 | |
|    * @see removeListSelectionListener
 | |
|    * @see getListeners
 | |
|    * @since 1.4
 | |
|    */
 | |
|   public ListSelectionListener[] getListSelectionListeners()
 | |
|   {
 | |
|     return (ListSelectionListener[]) getListeners(ListSelectionListener.class);
 | |
|   }
 | |
| }
 |