2362N/A * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved. 0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 0N/A * This code is free software; you can redistribute it and/or modify it 0N/A * under the terms of the GNU General Public License version 2 only, as 2362N/A * published by the Free Software Foundation. Oracle designates this 0N/A * particular file as subject to the "Classpath" exception as provided 2362N/A * by Oracle in the LICENSE file that accompanied this code. 0N/A * This code is distributed in the hope that it will be useful, but WITHOUT 0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 0N/A * version 2 for more details (a copy is included in the LICENSE file that 0N/A * accompanied this code). 0N/A * You should have received a copy of the GNU General Public License version 0N/A * 2 along with this work; if not, write to the Free Software Foundation, 0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2362N/A * or visit www.oracle.com if you need additional information or have any 0N/A * Default data model for list selections. 0N/A * <strong>Warning:</strong> 0N/A * Serialized objects of this class will not be compatible with 0N/A * future Swing releases. The current serialization support is 0N/A * appropriate for short term storage or RMI between applications running 0N/A * the same version of Swing. As of 1.4, support for long term storage 0N/A * of all JavaBeans<sup><font size="-2">TM</font></sup> 0N/A * has been added to the <code>java.beans</code> package. 0N/A * @author Philip Milne 0N/A * @author Hans Muller 0N/A * @see ListSelectionModel 0N/A private static final int MIN = -
1;
0N/A /** {@inheritDoc} */ 0N/A /** {@inheritDoc} */ 0N/A /** {@inheritDoc} */ 0N/A /** {@inheritDoc} */ 0N/A * @throws IllegalArgumentException {@inheritDoc} 0N/A /** {@inheritDoc} */ 0N/A /** {@inheritDoc} */ 0N/A /** {@inheritDoc} */ 0N/A /** {@inheritDoc} */ 0N/A * Returns an array of all the list selection listeners 0N/A * registered on this <code>DefaultListSelectionModel</code>. 0N/A * @return all of this model's <code>ListSelectionListener</code>s 0N/A * array if no list selection listeners are currently registered 0N/A * @see #addListSelectionListener 0N/A * @see #removeListSelectionListener 0N/A * Notifies listeners that we have ended a series of adjustments. 0N/A /* Change the values before sending the event to the 0N/A * listeners in case the event causes a listener to make 0N/A * another change to the selection. 0N/A * Notifies <code>ListSelectionListeners</code> that the value 0N/A * of the selection, in the closed interval <code>firstIndex</code>, 0N/A * <code>lastIndex</code>, has changed. 0N/A * @param firstIndex the first index in the interval 0N/A * @param lastIndex the last index in the interval 0N/A * @param isAdjusting true if this is the final change in a series of 0N/A * @see EventListenerList 0N/A /* If getValueAdjusting() is true, (eg. during a drag opereration) 0N/A * record the bounds of the changes so that, when the drag finishes (and 0N/A * setValueAdjusting(false) is called) we can post a single event 0N/A * with bounds covering all of these individual adjustments. 0N/A /* Change the values before sending the event to the 0N/A * listeners in case the event causes a listener to make 0N/A * another change to the selection. 0N/A * Returns an array of all the objects currently registered as 0N/A * <code><em>Foo</em>Listener</code>s 0N/A * <code><em>Foo</em>Listener</code>s 0N/A * are registered using the <code>add<em>Foo</em>Listener</code> method. 0N/A * You can specify the <code>listenerType</code> argument 0N/A * with a class literal, such as <code><em>Foo</em>Listener.class</code>. 0N/A * For example, you can query a <code>DefaultListSelectionModel</code> 0N/A * instance <code>m</code> 0N/A * for its list selection listeners 0N/A * with the following code: 0N/A * <pre>ListSelectionListener[] lsls = (ListSelectionListener[])(m.getListeners(ListSelectionListener.class));</pre> 0N/A * If no such listeners exist, 0N/A * this method returns an empty array. 0N/A * @param listenerType the type of listeners requested; 0N/A * this parameter should specify an interface 0N/A * that descends from <code>java.util.EventListener</code> 0N/A * @return an array of all objects registered as 0N/A * <code><em>Foo</em>Listener</code>s 0N/A * or an empty array if no such 0N/A * listeners have been added 0N/A * @exception ClassCastException if <code>listenerType</code> doesn't 0N/A * specify a class or interface that implements 0N/A * <code>java.util.EventListener</code> 0N/A * @see #getListSelectionListeners 0N/A // Updates first and last change indices 0N/A // Sets the state at this index and update all relevant state. 0N/A // Update minimum and maximum indices 0N/A // Clears the state at this index and update all relevant state. 0N/A // Update minimum and maximum indices 0N/A If (r > minIndex) the minimum has not changed. 0N/A The case (r < minIndex) is not possible because r'th value was set. 0N/A We only need to check for the case when lowest entry has been cleared, 0N/A and in this case we need to search for the first value set above it. 0N/A If (r < maxIndex) the maximum has not changed. 0N/A The case (r > maxIndex) is not possible because r'th value was set. 0N/A We only need to check for the case when highest entry has been cleared, 0N/A and in this case we need to search for the first value set below it. 0N/A /* Performance note: This method is called from inside a loop in 0N/A changeSelection() but we will only iterate in the loops 0N/A above on the basis of one iteration per deselected cell - in total. 0N/A Ie. the next time this method is called the work of the previous 0N/A deselection will not be repeated. 0N/A We also don't need to worry about the case when the min and max 0N/A values are in their unassigned states. This cannot happen because 0N/A this method's initial check ensures that the selection was not empty 0N/A and therefore that the minIndex and maxIndex had 'real' values. 0N/A If we have cleared the whole selection, set the minIndex and maxIndex 0N/A to their cannonical values so that the next set command always works 0N/A just by using Math.min and Math.max. 0N/A * Sets the value of the leadAnchorNotificationEnabled flag. 0N/A * @see #isLeadAnchorNotificationEnabled() 0N/A * Returns the value of the <code>leadAnchorNotificationEnabled</code> flag. 0N/A * When <code>leadAnchorNotificationEnabled</code> is true the model 0N/A * generates notification events with bounds that cover all the changes to 0N/A * the selection plus the changes to the lead and anchor indices. 0N/A * Setting the flag to false causes a narrowing of the event's bounds to 0N/A * include only the elements that have been selected or deselected since 0N/A * the last change. Either way, the model continues to maintain the lead 0N/A * and anchor variables internally. The default is true. 0N/A * Note: It is possible for the lead or anchor to be changed without a 0N/A * change to the selection. Notification of these changes is often 0N/A * important, such as when the new lead or anchor needs to be updated in 0N/A * the view. Therefore, caution is urged when changing the default value. 0N/A * @return the value of the <code>leadAnchorNotificationEnabled</code> flag 0N/A * @see #setLeadAnchorNotificationEnabled(boolean) 0N/A return (i >= a) && (i <= b);
0N/A * Change the selection with the effect of first clearing the values 0N/A * in the inclusive range [clearMin, clearMax] then setting the values 0N/A * in the inclusive range [setMin, setMax]. Do this in one pass so 0N/A * that no values are cleared if they would later be set. 0N/A /** {@inheritDoc} */ 0N/A * Changes the selection to be between {@code index0} and {@code index1} 0N/A * inclusive. {@code index0} doesn't have to be less than or equal to 0N/A * In {@code SINGLE_SELECTION} selection mode, only the second index 0N/A * If this represents a change to the current selection, then each 0N/A * {@code ListSelectionListener} is notified of the change. 0N/A * If either index is {@code -1}, this method does nothing and returns 0N/A * without exception. Otherwise, if either index is less than {@code -1}, 0N/A * an {@code IndexOutOfBoundsException} is thrown. 0N/A * @param index0 one end of the interval. 0N/A * @param index1 other end of the interval 0N/A * @throws IndexOutOfBoundsException if either index is less than {@code -1} 0N/A * (and neither index is {@code -1}) 0N/A * @see #addListSelectionListener 0N/A * Changes the selection to be the set union of the current selection 0N/A * and the indices between {@code index0} and {@code index1} inclusive. 0N/A * In {@code SINGLE_SELECTION} selection mode, this is equivalent 0N/A * to calling {@code setSelectionInterval}, and only the second index 0N/A * is used. In {@code SINGLE_INTERVAL_SELECTION} selection mode, this 0N/A * method behaves like {@code setSelectionInterval}, unless the given 0N/A * interval is immediately adjacent to or overlaps the existing selection, 0N/A * and can therefore be used to grow it. 0N/A * If this represents a change to the current selection, then each 0N/A * {@code ListSelectionListener} is notified of the change. Note that 0N/A * {@code index0} doesn't have to be less than or equal to {@code index1}. 0N/A * If either index is {@code -1}, this method does nothing and returns 0N/A * without exception. Otherwise, if either index is less than {@code -1}, 0N/A * an {@code IndexOutOfBoundsException} is thrown. 0N/A * @param index0 one end of the interval. 0N/A * @param index1 other end of the interval 0N/A * @throws IndexOutOfBoundsException if either index is less than {@code -1} 0N/A * (and neither index is {@code -1}) 0N/A * @see #addListSelectionListener 0N/A * @see #setSelectionInterval 0N/A // If we only allow a single selection, channel through 0N/A // setSelectionInterval() to enforce the rule. 0N/A // If we only allow a single interval and this would result 0N/A // in multiple intervals, then set the selection to be just 0N/A * Changes the selection to be the set difference of the current selection 0N/A * and the indices between {@code index0} and {@code index1} inclusive. 0N/A * {@code index0} doesn't have to be less than or equal to {@code index1}. 0N/A * In {@code SINGLE_INTERVAL_SELECTION} selection mode, if the removal 0N/A * would produce two disjoint selections, the removal is extended through 0N/A * the greater end of the selection. For example, if the selection is 0N/A * {@code 0-10} and you supply indices {@code 5,6} (in any order) the 0N/A * resulting selection is {@code 0-4}. 0N/A * If this represents a change to the current selection, then each 0N/A * {@code ListSelectionListener} is notified of the change. 0N/A * If either index is {@code -1}, this method does nothing and returns 0N/A * without exception. Otherwise, if either index is less than {@code -1}, 0N/A * an {@code IndexOutOfBoundsException} is thrown. 0N/A * @param index0 one end of the interval 0N/A * @param index1 other end of the interval 0N/A * @throws IndexOutOfBoundsException if either index is less than {@code -1} 0N/A * (and neither index is {@code -1}) 0N/A * @see #addListSelectionListener 0N/A // private implementation allowing the selection interval 0N/A // to be removed without affecting the lead and anchor 0N/A // If the removal would produce to two disjoint selections in a mode 0N/A // that only allows one, extend the removal to the end of the selection. 0N/A * at index is itself selected and the selection mode is not 0N/A * SINGLE_SELECTION, set all of the newly inserted items as selected. 0N/A * Otherwise leave them unselected. This method is typically 0N/A * called to sync the selection model with a corresponding change 0N/A * in the data model. 0N/A /* The first new index will appear at insMinIndex and the last 0N/A * one will appear at insMaxIndex 0N/A /* Right shift the entire bitset by length, beginning with 0N/A * index-1 if before is true, index+1 if it's false (i.e. with 0N/A /* Initialize the newly inserted indices. 0N/A * Remove the indices in the interval index0,index1 (inclusive) from 0N/A * the selection model. This is typically called to sync the selection 0N/A * model width a corresponding change in the data model. Note 0N/A * that (as always) index0 need not be <= index1. 0N/A /* Shift the entire bitset to the left to close the index0, index1 0N/A /** {@inheritDoc} */ 0N/A * Returns a string that displays and identifies this 0N/A * object's properties. 0N/A * @return a <code>String</code> representation of this object 0N/A * Returns a clone of this selection model with the same selection. 0N/A * <code>listenerLists</code> are not duplicated. 0N/A * @exception CloneNotSupportedException if the selection model does not 0N/A * both (a) implement the Cloneable interface and (b) define a 0N/A * <code>clone</code> method. 0N/A /** {@inheritDoc} */ 0N/A /** {@inheritDoc} */ 0N/A * Set the anchor selection index, leaving all selection values unchanged. 0N/A * If leadAnchorNotificationEnabled is true, send a notification covering 0N/A * the old and new anchor cells. 0N/A * @see #getAnchorSelectionIndex 0N/A * @see #setLeadSelectionIndex 0N/A * Set the lead selection index, leaving all selection values unchanged. 0N/A * If leadAnchorNotificationEnabled is true, send a notification covering 0N/A * the old and new lead cells. 0N/A * @param leadIndex the new lead selection index 0N/A * @see #setAnchorSelectionIndex 0N/A * @see #setLeadSelectionIndex 0N/A * @see #getLeadSelectionIndex 0N/A // disallow a -1 lead unless the anchor is already -1 0N/A/* PENDING(shannonh) - The following check is nice, to be consistent with 0N/A setLeadSelectionIndex. However, it is not absolutely 0N/A necessary: One could work around it by setting the anchor 0N/A to something valid, modifying the lead, and then moving 0N/A the anchor back to -1. For this reason, there's no sense 0N/A in adding it at this time, as that would require 0N/A updating the spec and officially committing to it. 0N/A // otherwise, don't do anything if the anchor is -1 0N/A } else if (this.anchorIndex == -1) { 0N/A * Sets the lead selection index, ensuring that values between the 0N/A * anchor and the new lead are either all selected or all deselected. 0N/A * If the value at the anchor index is selected, first clear all the 0N/A * values in the range [anchor, oldLeadIndex], then select all the values 0N/A * values in the range [anchor, newLeadIndex], where oldLeadIndex is the old 0N/A * leadIndex and newLeadIndex is the new one. 0N/A * If the value at the anchor index is not selected, do the same thing in 0N/A * reverse selecting values in the old range and deslecting values in the 0N/A * Generate a single event for this change and notify all listeners. 0N/A * For the purposes of generating minimal bounds in this event, do the 0N/A * operation in a single pass; that way the first and last index inside the 0N/A * ListSelectionEvent that is broadcast will refer to cells that actually 0N/A * changed value because of this method. If, instead, this operation were 0N/A * done in two steps the effect on the selection state would be the same 0N/A * but two events would be generated and the bounds around the changed 0N/A * values would be wider, including cells that had been first cleared only 0N/A * This method can be used in the <code>mouseDragged</code> method 0N/A * of a UI class to extend a selection. 0N/A * @see #getLeadSelectionIndex 0N/A * @see #setAnchorSelectionIndex 0N/A // only allow a -1 lead if the anchor is already -1 0N/A // otherwise, don't do anything if the anchor is -1