jdk/src/java.desktop/share/classes/javax/swing/DefaultListSelectionModel.java
author aghaisas
Mon, 10 Jul 2017 14:55:29 +0530
changeset 47151 362dcbee0613
parent 30464 929bafd0db6f
permissions -rw-r--r--
6919529: NPE from MultiUIDefaults.getUIError Reviewed-by: aghaisas, psadhukhan, serb Contributed-by: shashidhara.veerabhadraiah@oracle.com
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
30464
929bafd0db6f 8075082: Fix missing doclint warnings in the javax.swing package
darcy
parents: 25859
diff changeset
     2
 * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     4
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
90ce3da70b43 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 1301
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 1301
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    10
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
90ce3da70b43 Initial load
duke
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
90ce3da70b43 Initial load
duke
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    15
 * accompanied this code).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    16
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
90ce3da70b43 Initial load
duke
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    20
 *
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 1301
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 1301
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 1301
diff changeset
    23
 * questions.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    24
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    25
90ce3da70b43 Initial load
duke
parents:
diff changeset
    26
package javax.swing;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    27
90ce3da70b43 Initial load
duke
parents:
diff changeset
    28
import java.util.EventListener;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    29
import java.util.BitSet;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    30
import java.io.Serializable;
466
6acd5ec503a8 4935607: RFE: LTP: Should be possible to set the TRANSIENT attribute of propertiies to FALSE
malenkov
parents: 2
diff changeset
    31
import java.beans.Transient;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    32
90ce3da70b43 Initial load
duke
parents:
diff changeset
    33
import javax.swing.event.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    34
90ce3da70b43 Initial load
duke
parents:
diff changeset
    35
90ce3da70b43 Initial load
duke
parents:
diff changeset
    36
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    37
 * Default data model for list selections.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    38
 * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    39
 * <strong>Warning:</strong>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    40
 * Serialized objects of this class will not be compatible with
90ce3da70b43 Initial load
duke
parents:
diff changeset
    41
 * future Swing releases. The current serialization support is
90ce3da70b43 Initial load
duke
parents:
diff changeset
    42
 * appropriate for short term storage or RMI between applications running
90ce3da70b43 Initial load
duke
parents:
diff changeset
    43
 * the same version of Swing.  As of 1.4, support for long term storage
20458
f2423fb3fd19 8025840: Fix all the doclint warnings about trademark
cl
parents: 12173
diff changeset
    44
 * of all JavaBeans&trade;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
 * has been added to the <code>java.beans</code> package.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
 * Please see {@link java.beans.XMLEncoder}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    47
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    48
 * @author Philip Milne
90ce3da70b43 Initial load
duke
parents:
diff changeset
    49
 * @author Hans Muller
90ce3da70b43 Initial load
duke
parents:
diff changeset
    50
 * @see ListSelectionModel
25201
4adc75e0c4e5 8046485: Add missing @since tag under javax.swing.*
henryjen
parents: 22574
diff changeset
    51
 * @since 1.2
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
 */
22574
7f8ce0c8c20a 8032627: Add @SuppressWarnings("serial") to appropriate javax.swing classes
darcy
parents: 21592
diff changeset
    53
@SuppressWarnings("serial") // Same-version serialization only
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
public class DefaultListSelectionModel implements ListSelectionModel, Cloneable, Serializable
90ce3da70b43 Initial load
duke
parents:
diff changeset
    55
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
    56
    private static final int MIN = -1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    57
    private static final int MAX = Integer.MAX_VALUE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    58
    private int selectionMode = MULTIPLE_INTERVAL_SELECTION;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    59
    private int minIndex = MAX;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    60
    private int maxIndex = MIN;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    61
    private int anchorIndex = -1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
    private int leadIndex = -1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    63
    private int firstAdjustedIndex = MAX;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    64
    private int lastAdjustedIndex = MIN;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    65
    private boolean isAdjusting = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
90ce3da70b43 Initial load
duke
parents:
diff changeset
    67
    private int firstChangedIndex = MAX;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    68
    private int lastChangedIndex = MIN;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    69
90ce3da70b43 Initial load
duke
parents:
diff changeset
    70
    private BitSet value = new BitSet(32);
30464
929bafd0db6f 8075082: Fix missing doclint warnings in the javax.swing package
darcy
parents: 25859
diff changeset
    71
    /**
929bafd0db6f 8075082: Fix missing doclint warnings in the javax.swing package
darcy
parents: 25859
diff changeset
    72
     * The list of listeners.
929bafd0db6f 8075082: Fix missing doclint warnings in the javax.swing package
darcy
parents: 25859
diff changeset
    73
     */
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    74
    protected EventListenerList listenerList = new EventListenerList();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
30464
929bafd0db6f 8075082: Fix missing doclint warnings in the javax.swing package
darcy
parents: 25859
diff changeset
    76
    /**
929bafd0db6f 8075082: Fix missing doclint warnings in the javax.swing package
darcy
parents: 25859
diff changeset
    77
     * Whether or not the lead anchor notification is enabled.
929bafd0db6f 8075082: Fix missing doclint warnings in the javax.swing package
darcy
parents: 25859
diff changeset
    78
     */
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    79
    protected boolean leadAnchorNotificationEnabled = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
90ce3da70b43 Initial load
duke
parents:
diff changeset
    81
    /** {@inheritDoc} */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    82
    public int getMinSelectionIndex() { return isSelectionEmpty() ? -1 : minIndex; }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    83
90ce3da70b43 Initial load
duke
parents:
diff changeset
    84
    /** {@inheritDoc} */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    85
    public int getMaxSelectionIndex() { return maxIndex; }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    86
90ce3da70b43 Initial load
duke
parents:
diff changeset
    87
    /** {@inheritDoc} */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    88
    public boolean getValueIsAdjusting() { return isAdjusting; }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    89
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
    /** {@inheritDoc} */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    91
    public int getSelectionMode() { return selectionMode; }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    92
90ce3da70b43 Initial load
duke
parents:
diff changeset
    93
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    94
     * {@inheritDoc}
90ce3da70b43 Initial load
duke
parents:
diff changeset
    95
     * @throws IllegalArgumentException {@inheritDoc}
90ce3da70b43 Initial load
duke
parents:
diff changeset
    96
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    97
    public void setSelectionMode(int selectionMode) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
        switch (selectionMode) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
        case SINGLE_SELECTION:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   100
        case SINGLE_INTERVAL_SELECTION:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   101
        case MULTIPLE_INTERVAL_SELECTION:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   102
            this.selectionMode = selectionMode;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   103
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
        default:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
            throw new IllegalArgumentException("invalid selectionMode");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
    /** {@inheritDoc} */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
    public boolean isSelectedIndex(int index) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
        return ((index < minIndex) || (index > maxIndex)) ? false : value.get(index);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
    /** {@inheritDoc} */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
    public boolean isSelectionEmpty() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
        return (minIndex > maxIndex);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
    /** {@inheritDoc} */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
    public void addListSelectionListener(ListSelectionListener l) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
        listenerList.add(ListSelectionListener.class, l);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
    /** {@inheritDoc} */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
    public void removeListSelectionListener(ListSelectionListener l) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
        listenerList.remove(ListSelectionListener.class, l);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
     * Returns an array of all the list selection listeners
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
     * registered on this <code>DefaultListSelectionModel</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
     * @return all of this model's <code>ListSelectionListener</code>s
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
     *         or an empty
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
     *         array if no list selection listeners are currently registered
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
     * @see #addListSelectionListener
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
     * @see #removeListSelectionListener
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
     * @since 1.4
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
    public ListSelectionListener[] getListSelectionListeners() {
1301
15e81207e1f2 6727662: Code improvement and warnings removing from swing packages
rupashka
parents: 466
diff changeset
   143
        return listenerList.getListeners(ListSelectionListener.class);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
     * Notifies listeners that we have ended a series of adjustments.
30464
929bafd0db6f 8075082: Fix missing doclint warnings in the javax.swing package
darcy
parents: 25859
diff changeset
   148
     * @param isAdjusting true if this is the final change in a series of
929bafd0db6f 8075082: Fix missing doclint warnings in the javax.swing package
darcy
parents: 25859
diff changeset
   149
     *          adjustments
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
    protected void fireValueChanged(boolean isAdjusting) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
        if (lastChangedIndex == MIN) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
        /* Change the values before sending the event to the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
         * listeners in case the event causes a listener to make
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
         * another change to the selection.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
        int oldFirstChangedIndex = firstChangedIndex;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
        int oldLastChangedIndex = lastChangedIndex;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
        firstChangedIndex = MAX;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
        lastChangedIndex = MIN;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
        fireValueChanged(oldFirstChangedIndex, oldLastChangedIndex, isAdjusting);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
     * Notifies <code>ListSelectionListeners</code> that the value
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
     * of the selection, in the closed interval <code>firstIndex</code>,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   170
     * <code>lastIndex</code>, has changed.
25386
9ef80c24fd74 8046590: fix doclint issues in swing classes, part 1 of 4
yan
parents: 25201
diff changeset
   171
     *
9ef80c24fd74 8046590: fix doclint issues in swing classes, part 1 of 4
yan
parents: 25201
diff changeset
   172
     * @param firstIndex the first index in the interval
9ef80c24fd74 8046590: fix doclint issues in swing classes, part 1 of 4
yan
parents: 25201
diff changeset
   173
     * @param lastIndex the last index in the interval
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
    protected void fireValueChanged(int firstIndex, int lastIndex) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
        fireValueChanged(firstIndex, lastIndex, getValueIsAdjusting());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   178
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
     * @param firstIndex the first index in the interval
90ce3da70b43 Initial load
duke
parents:
diff changeset
   181
     * @param lastIndex the last index in the interval
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
     * @param isAdjusting true if this is the final change in a series of
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
     *          adjustments
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
     * @see EventListenerList
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
    protected void fireValueChanged(int firstIndex, int lastIndex, boolean isAdjusting)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   187
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
        Object[] listeners = listenerList.getListenerList();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
        ListSelectionEvent e = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
        for (int i = listeners.length - 2; i >= 0; i -= 2) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   192
            if (listeners[i] == ListSelectionListener.class) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   193
                if (e == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
                    e = new ListSelectionEvent(this, firstIndex, lastIndex, isAdjusting);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
                ((ListSelectionListener)listeners[i+1]).valueChanged(e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   198
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   199
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   200
90ce3da70b43 Initial load
duke
parents:
diff changeset
   201
    private void fireValueChanged() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   202
        if (lastAdjustedIndex == MIN) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
        /* If getValueAdjusting() is true, (eg. during a drag opereration)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
         * record the bounds of the changes so that, when the drag finishes (and
90ce3da70b43 Initial load
duke
parents:
diff changeset
   207
         * setValueAdjusting(false) is called) we can post a single event
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
         * with bounds covering all of these individual adjustments.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
        if (getValueIsAdjusting()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
            firstChangedIndex = Math.min(firstChangedIndex, firstAdjustedIndex);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   212
            lastChangedIndex = Math.max(lastChangedIndex, lastAdjustedIndex);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   213
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   214
        /* Change the values before sending the event to the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   215
         * listeners in case the event causes a listener to make
90ce3da70b43 Initial load
duke
parents:
diff changeset
   216
         * another change to the selection.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   217
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   218
        int oldFirstAdjustedIndex = firstAdjustedIndex;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   219
        int oldLastAdjustedIndex = lastAdjustedIndex;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   220
        firstAdjustedIndex = MAX;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   221
        lastAdjustedIndex = MIN;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   222
90ce3da70b43 Initial load
duke
parents:
diff changeset
   223
        fireValueChanged(oldFirstAdjustedIndex, oldLastAdjustedIndex);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   224
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   225
90ce3da70b43 Initial load
duke
parents:
diff changeset
   226
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   227
     * Returns an array of all the objects currently registered as
90ce3da70b43 Initial load
duke
parents:
diff changeset
   228
     * <code><em>Foo</em>Listener</code>s
90ce3da70b43 Initial load
duke
parents:
diff changeset
   229
     * upon this model.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   230
     * <code><em>Foo</em>Listener</code>s
90ce3da70b43 Initial load
duke
parents:
diff changeset
   231
     * are registered using the <code>add<em>Foo</em>Listener</code> method.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   232
     * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   233
     * You can specify the <code>listenerType</code> argument
90ce3da70b43 Initial load
duke
parents:
diff changeset
   234
     * with a class literal, such as <code><em>Foo</em>Listener.class</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   235
     * For example, you can query a <code>DefaultListSelectionModel</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   236
     * instance <code>m</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   237
     * for its list selection listeners
90ce3da70b43 Initial load
duke
parents:
diff changeset
   238
     * with the following code:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   239
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   240
     * <pre>ListSelectionListener[] lsls = (ListSelectionListener[])(m.getListeners(ListSelectionListener.class));</pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   241
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   242
     * If no such listeners exist,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   243
     * this method returns an empty array.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   244
     *
25386
9ef80c24fd74 8046590: fix doclint issues in swing classes, part 1 of 4
yan
parents: 25201
diff changeset
   245
     * @param <T> the type of {@code EventListener} class being requested
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   246
     * @param listenerType  the type of listeners requested;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   247
     *          this parameter should specify an interface
90ce3da70b43 Initial load
duke
parents:
diff changeset
   248
     *          that descends from <code>java.util.EventListener</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
     * @return an array of all objects registered as
90ce3da70b43 Initial load
duke
parents:
diff changeset
   250
     *          <code><em>Foo</em>Listener</code>s
90ce3da70b43 Initial load
duke
parents:
diff changeset
   251
     *          on this model,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   252
     *          or an empty array if no such
90ce3da70b43 Initial load
duke
parents:
diff changeset
   253
     *          listeners have been added
90ce3da70b43 Initial load
duke
parents:
diff changeset
   254
     * @exception ClassCastException if <code>listenerType</code> doesn't
90ce3da70b43 Initial load
duke
parents:
diff changeset
   255
     *          specify a class or interface that implements
90ce3da70b43 Initial load
duke
parents:
diff changeset
   256
     *          <code>java.util.EventListener</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   257
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   258
     * @see #getListSelectionListeners
90ce3da70b43 Initial load
duke
parents:
diff changeset
   259
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   260
     * @since 1.3
90ce3da70b43 Initial load
duke
parents:
diff changeset
   261
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   262
    public <T extends EventListener> T[] getListeners(Class<T> listenerType) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   263
        return listenerList.getListeners(listenerType);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   264
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   265
90ce3da70b43 Initial load
duke
parents:
diff changeset
   266
    // Updates first and last change indices
90ce3da70b43 Initial load
duke
parents:
diff changeset
   267
    private void markAsDirty(int r) {
12173
80420757767c 7027139: getFirstIndex() does not return the first index that has changed
rupashka
parents: 5506
diff changeset
   268
        if (r == -1) {
80420757767c 7027139: getFirstIndex() does not return the first index that has changed
rupashka
parents: 5506
diff changeset
   269
            return;
80420757767c 7027139: getFirstIndex() does not return the first index that has changed
rupashka
parents: 5506
diff changeset
   270
        }
80420757767c 7027139: getFirstIndex() does not return the first index that has changed
rupashka
parents: 5506
diff changeset
   271
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   272
        firstAdjustedIndex = Math.min(firstAdjustedIndex, r);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   273
        lastAdjustedIndex =  Math.max(lastAdjustedIndex, r);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   274
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   275
90ce3da70b43 Initial load
duke
parents:
diff changeset
   276
    // Sets the state at this index and update all relevant state.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
    private void set(int r) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   278
        if (value.get(r)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   279
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   280
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   281
        value.set(r);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   282
        markAsDirty(r);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   283
90ce3da70b43 Initial load
duke
parents:
diff changeset
   284
        // Update minimum and maximum indices
90ce3da70b43 Initial load
duke
parents:
diff changeset
   285
        minIndex = Math.min(minIndex, r);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   286
        maxIndex = Math.max(maxIndex, r);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   288
90ce3da70b43 Initial load
duke
parents:
diff changeset
   289
    // Clears the state at this index and update all relevant state.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   290
    private void clear(int r) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
        if (!value.get(r)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   293
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   294
        value.clear(r);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   295
        markAsDirty(r);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   296
90ce3da70b43 Initial load
duke
parents:
diff changeset
   297
        // Update minimum and maximum indices
90ce3da70b43 Initial load
duke
parents:
diff changeset
   298
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   299
           If (r > minIndex) the minimum has not changed.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   300
           The case (r < minIndex) is not possible because r'th value was set.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
           We only need to check for the case when lowest entry has been cleared,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
           and in this case we need to search for the first value set above it.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   303
        */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   304
        if (r == minIndex) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   305
            for(minIndex = minIndex + 1; minIndex <= maxIndex; minIndex++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   306
                if (value.get(minIndex)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   307
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   308
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   309
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   310
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
           If (r < maxIndex) the maximum has not changed.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   313
           The case (r > maxIndex) is not possible because r'th value was set.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
           We only need to check for the case when highest entry has been cleared,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
           and in this case we need to search for the first value set below it.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
        */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
        if (r == maxIndex) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   318
            for(maxIndex = maxIndex - 1; minIndex <= maxIndex; maxIndex--) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   319
                if (value.get(maxIndex)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   320
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   321
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   322
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   323
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   324
        /* Performance note: This method is called from inside a loop in
90ce3da70b43 Initial load
duke
parents:
diff changeset
   325
           changeSelection() but we will only iterate in the loops
90ce3da70b43 Initial load
duke
parents:
diff changeset
   326
           above on the basis of one iteration per deselected cell - in total.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   327
           Ie. the next time this method is called the work of the previous
90ce3da70b43 Initial load
duke
parents:
diff changeset
   328
           deselection will not be repeated.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   329
90ce3da70b43 Initial load
duke
parents:
diff changeset
   330
           We also don't need to worry about the case when the min and max
90ce3da70b43 Initial load
duke
parents:
diff changeset
   331
           values are in their unassigned states. This cannot happen because
90ce3da70b43 Initial load
duke
parents:
diff changeset
   332
           this method's initial check ensures that the selection was not empty
90ce3da70b43 Initial load
duke
parents:
diff changeset
   333
           and therefore that the minIndex and maxIndex had 'real' values.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   334
90ce3da70b43 Initial load
duke
parents:
diff changeset
   335
           If we have cleared the whole selection, set the minIndex and maxIndex
90ce3da70b43 Initial load
duke
parents:
diff changeset
   336
           to their cannonical values so that the next set command always works
90ce3da70b43 Initial load
duke
parents:
diff changeset
   337
           just by using Math.min and Math.max.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   338
        */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   339
        if (isSelectionEmpty()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   340
            minIndex = MAX;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   341
            maxIndex = MIN;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   342
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   343
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   344
90ce3da70b43 Initial load
duke
parents:
diff changeset
   345
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   346
     * Sets the value of the leadAnchorNotificationEnabled flag.
25386
9ef80c24fd74 8046590: fix doclint issues in swing classes, part 1 of 4
yan
parents: 25201
diff changeset
   347
     *
9ef80c24fd74 8046590: fix doclint issues in swing classes, part 1 of 4
yan
parents: 25201
diff changeset
   348
     * @param flag boolean value for {@code leadAnchorNotificationEnabled}
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   349
     * @see             #isLeadAnchorNotificationEnabled()
90ce3da70b43 Initial load
duke
parents:
diff changeset
   350
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   351
    public void setLeadAnchorNotificationEnabled(boolean flag) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   352
        leadAnchorNotificationEnabled = flag;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   353
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   354
90ce3da70b43 Initial load
duke
parents:
diff changeset
   355
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   356
     * Returns the value of the <code>leadAnchorNotificationEnabled</code> flag.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   357
     * When <code>leadAnchorNotificationEnabled</code> is true the model
90ce3da70b43 Initial load
duke
parents:
diff changeset
   358
     * generates notification events with bounds that cover all the changes to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   359
     * the selection plus the changes to the lead and anchor indices.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   360
     * Setting the flag to false causes a narrowing of the event's bounds to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   361
     * include only the elements that have been selected or deselected since
90ce3da70b43 Initial load
duke
parents:
diff changeset
   362
     * the last change. Either way, the model continues to maintain the lead
90ce3da70b43 Initial load
duke
parents:
diff changeset
   363
     * and anchor variables internally. The default is true.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   364
     * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   365
     * Note: It is possible for the lead or anchor to be changed without a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   366
     * change to the selection. Notification of these changes is often
90ce3da70b43 Initial load
duke
parents:
diff changeset
   367
     * important, such as when the new lead or anchor needs to be updated in
90ce3da70b43 Initial load
duke
parents:
diff changeset
   368
     * the view. Therefore, caution is urged when changing the default value.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   369
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   370
     * @return  the value of the <code>leadAnchorNotificationEnabled</code> flag
90ce3da70b43 Initial load
duke
parents:
diff changeset
   371
     * @see             #setLeadAnchorNotificationEnabled(boolean)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   372
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   373
    public boolean isLeadAnchorNotificationEnabled() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   374
        return leadAnchorNotificationEnabled;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   375
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   376
90ce3da70b43 Initial load
duke
parents:
diff changeset
   377
    private void updateLeadAnchorIndices(int anchorIndex, int leadIndex) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   378
        if (leadAnchorNotificationEnabled) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   379
            if (this.anchorIndex != anchorIndex) {
12173
80420757767c 7027139: getFirstIndex() does not return the first index that has changed
rupashka
parents: 5506
diff changeset
   380
                markAsDirty(this.anchorIndex);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   381
                markAsDirty(anchorIndex);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   382
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   383
90ce3da70b43 Initial load
duke
parents:
diff changeset
   384
            if (this.leadIndex != leadIndex) {
12173
80420757767c 7027139: getFirstIndex() does not return the first index that has changed
rupashka
parents: 5506
diff changeset
   385
                markAsDirty(this.leadIndex);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   386
                markAsDirty(leadIndex);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   387
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   388
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   389
        this.anchorIndex = anchorIndex;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   390
        this.leadIndex = leadIndex;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   391
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   392
90ce3da70b43 Initial load
duke
parents:
diff changeset
   393
    private boolean contains(int a, int b, int i) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   394
        return (i >= a) && (i <= b);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   395
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   396
90ce3da70b43 Initial load
duke
parents:
diff changeset
   397
    private void changeSelection(int clearMin, int clearMax,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   398
                                 int setMin, int setMax, boolean clearFirst) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   399
        for(int i = Math.min(setMin, clearMin); i <= Math.max(setMax, clearMax); i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   400
90ce3da70b43 Initial load
duke
parents:
diff changeset
   401
            boolean shouldClear = contains(clearMin, clearMax, i);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   402
            boolean shouldSet = contains(setMin, setMax, i);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   403
90ce3da70b43 Initial load
duke
parents:
diff changeset
   404
            if (shouldSet && shouldClear) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   405
                if (clearFirst) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   406
                    shouldClear = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   407
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   408
                else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   409
                    shouldSet = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   410
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   411
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   412
90ce3da70b43 Initial load
duke
parents:
diff changeset
   413
            if (shouldSet) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   414
                set(i);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   415
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   416
            if (shouldClear) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   417
                clear(i);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   418
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   419
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   420
        fireValueChanged();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   421
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   422
90ce3da70b43 Initial load
duke
parents:
diff changeset
   423
   /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   424
    * Change the selection with the effect of first clearing the values
90ce3da70b43 Initial load
duke
parents:
diff changeset
   425
    * in the inclusive range [clearMin, clearMax] then setting the values
90ce3da70b43 Initial load
duke
parents:
diff changeset
   426
    * in the inclusive range [setMin, setMax]. Do this in one pass so
90ce3da70b43 Initial load
duke
parents:
diff changeset
   427
    * that no values are cleared if they would later be set.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   428
    */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   429
    private void changeSelection(int clearMin, int clearMax, int setMin, int setMax) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   430
        changeSelection(clearMin, clearMax, setMin, setMax, true);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   431
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   432
90ce3da70b43 Initial load
duke
parents:
diff changeset
   433
    /** {@inheritDoc} */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   434
    public void clearSelection() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   435
        removeSelectionIntervalImpl(minIndex, maxIndex, false);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   436
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   437
90ce3da70b43 Initial load
duke
parents:
diff changeset
   438
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   439
     * Changes the selection to be between {@code index0} and {@code index1}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   440
     * inclusive. {@code index0} doesn't have to be less than or equal to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   441
     * {@code index1}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   442
     * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   443
     * In {@code SINGLE_SELECTION} selection mode, only the second index
90ce3da70b43 Initial load
duke
parents:
diff changeset
   444
     * is used.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   445
     * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   446
     * If this represents a change to the current selection, then each
90ce3da70b43 Initial load
duke
parents:
diff changeset
   447
     * {@code ListSelectionListener} is notified of the change.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   448
     * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   449
     * If either index is {@code -1}, this method does nothing and returns
90ce3da70b43 Initial load
duke
parents:
diff changeset
   450
     * without exception. Otherwise, if either index is less than {@code -1},
90ce3da70b43 Initial load
duke
parents:
diff changeset
   451
     * an {@code IndexOutOfBoundsException} is thrown.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   452
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   453
     * @param index0 one end of the interval.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   454
     * @param index1 other end of the interval
90ce3da70b43 Initial load
duke
parents:
diff changeset
   455
     * @throws IndexOutOfBoundsException if either index is less than {@code -1}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   456
     *         (and neither index is {@code -1})
90ce3da70b43 Initial load
duke
parents:
diff changeset
   457
     * @see #addListSelectionListener
90ce3da70b43 Initial load
duke
parents:
diff changeset
   458
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   459
    public void setSelectionInterval(int index0, int index1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   460
        if (index0 == -1 || index1 == -1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   461
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   462
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   463
90ce3da70b43 Initial load
duke
parents:
diff changeset
   464
        if (getSelectionMode() == SINGLE_SELECTION) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   465
            index0 = index1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   466
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   467
90ce3da70b43 Initial load
duke
parents:
diff changeset
   468
        updateLeadAnchorIndices(index0, index1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   469
90ce3da70b43 Initial load
duke
parents:
diff changeset
   470
        int clearMin = minIndex;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   471
        int clearMax = maxIndex;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   472
        int setMin = Math.min(index0, index1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   473
        int setMax = Math.max(index0, index1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   474
        changeSelection(clearMin, clearMax, setMin, setMax);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   475
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   476
90ce3da70b43 Initial load
duke
parents:
diff changeset
   477
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   478
     * Changes the selection to be the set union of the current selection
90ce3da70b43 Initial load
duke
parents:
diff changeset
   479
     * and the indices between {@code index0} and {@code index1} inclusive.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   480
     * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   481
     * In {@code SINGLE_SELECTION} selection mode, this is equivalent
90ce3da70b43 Initial load
duke
parents:
diff changeset
   482
     * to calling {@code setSelectionInterval}, and only the second index
90ce3da70b43 Initial load
duke
parents:
diff changeset
   483
     * is used. In {@code SINGLE_INTERVAL_SELECTION} selection mode, this
90ce3da70b43 Initial load
duke
parents:
diff changeset
   484
     * method behaves like {@code setSelectionInterval}, unless the given
90ce3da70b43 Initial load
duke
parents:
diff changeset
   485
     * interval is immediately adjacent to or overlaps the existing selection,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   486
     * and can therefore be used to grow it.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   487
     * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   488
     * If this represents a change to the current selection, then each
90ce3da70b43 Initial load
duke
parents:
diff changeset
   489
     * {@code ListSelectionListener} is notified of the change. Note that
90ce3da70b43 Initial load
duke
parents:
diff changeset
   490
     * {@code index0} doesn't have to be less than or equal to {@code index1}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   491
     * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   492
     * If either index is {@code -1}, this method does nothing and returns
90ce3da70b43 Initial load
duke
parents:
diff changeset
   493
     * without exception. Otherwise, if either index is less than {@code -1},
90ce3da70b43 Initial load
duke
parents:
diff changeset
   494
     * an {@code IndexOutOfBoundsException} is thrown.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   495
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   496
     * @param index0 one end of the interval.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   497
     * @param index1 other end of the interval
90ce3da70b43 Initial load
duke
parents:
diff changeset
   498
     * @throws IndexOutOfBoundsException if either index is less than {@code -1}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   499
     *         (and neither index is {@code -1})
90ce3da70b43 Initial load
duke
parents:
diff changeset
   500
     * @see #addListSelectionListener
90ce3da70b43 Initial load
duke
parents:
diff changeset
   501
     * @see #setSelectionInterval
90ce3da70b43 Initial load
duke
parents:
diff changeset
   502
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   503
    public void addSelectionInterval(int index0, int index1)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   504
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   505
        if (index0 == -1 || index1 == -1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   506
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   507
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   508
90ce3da70b43 Initial load
duke
parents:
diff changeset
   509
        // If we only allow a single selection, channel through
90ce3da70b43 Initial load
duke
parents:
diff changeset
   510
        // setSelectionInterval() to enforce the rule.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   511
        if (getSelectionMode() == SINGLE_SELECTION) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   512
            setSelectionInterval(index0, index1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   513
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   514
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   515
90ce3da70b43 Initial load
duke
parents:
diff changeset
   516
        updateLeadAnchorIndices(index0, index1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   517
90ce3da70b43 Initial load
duke
parents:
diff changeset
   518
        int clearMin = MAX;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   519
        int clearMax = MIN;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   520
        int setMin = Math.min(index0, index1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   521
        int setMax = Math.max(index0, index1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   522
90ce3da70b43 Initial load
duke
parents:
diff changeset
   523
        // If we only allow a single interval and this would result
90ce3da70b43 Initial load
duke
parents:
diff changeset
   524
        // in multiple intervals, then set the selection to be just
90ce3da70b43 Initial load
duke
parents:
diff changeset
   525
        // the new range.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   526
        if (getSelectionMode() == SINGLE_INTERVAL_SELECTION &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   527
                (setMax < minIndex - 1 || setMin > maxIndex + 1)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   528
90ce3da70b43 Initial load
duke
parents:
diff changeset
   529
            setSelectionInterval(index0, index1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   530
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   531
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   532
90ce3da70b43 Initial load
duke
parents:
diff changeset
   533
        changeSelection(clearMin, clearMax, setMin, setMax);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   534
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   535
90ce3da70b43 Initial load
duke
parents:
diff changeset
   536
90ce3da70b43 Initial load
duke
parents:
diff changeset
   537
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   538
     * Changes the selection to be the set difference of the current selection
90ce3da70b43 Initial load
duke
parents:
diff changeset
   539
     * and the indices between {@code index0} and {@code index1} inclusive.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   540
     * {@code index0} doesn't have to be less than or equal to {@code index1}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   541
     * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   542
     * In {@code SINGLE_INTERVAL_SELECTION} selection mode, if the removal
90ce3da70b43 Initial load
duke
parents:
diff changeset
   543
     * would produce two disjoint selections, the removal is extended through
90ce3da70b43 Initial load
duke
parents:
diff changeset
   544
     * the greater end of the selection. For example, if the selection is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   545
     * {@code 0-10} and you supply indices {@code 5,6} (in any order) the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   546
     * resulting selection is {@code 0-4}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   547
     * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   548
     * If this represents a change to the current selection, then each
90ce3da70b43 Initial load
duke
parents:
diff changeset
   549
     * {@code ListSelectionListener} is notified of the change.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   550
     * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   551
     * If either index is {@code -1}, this method does nothing and returns
90ce3da70b43 Initial load
duke
parents:
diff changeset
   552
     * without exception. Otherwise, if either index is less than {@code -1},
90ce3da70b43 Initial load
duke
parents:
diff changeset
   553
     * an {@code IndexOutOfBoundsException} is thrown.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   554
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   555
     * @param index0 one end of the interval
90ce3da70b43 Initial load
duke
parents:
diff changeset
   556
     * @param index1 other end of the interval
90ce3da70b43 Initial load
duke
parents:
diff changeset
   557
     * @throws IndexOutOfBoundsException if either index is less than {@code -1}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   558
     *         (and neither index is {@code -1})
90ce3da70b43 Initial load
duke
parents:
diff changeset
   559
     * @see #addListSelectionListener
90ce3da70b43 Initial load
duke
parents:
diff changeset
   560
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   561
    public void removeSelectionInterval(int index0, int index1)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   562
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   563
        removeSelectionIntervalImpl(index0, index1, true);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   564
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   565
90ce3da70b43 Initial load
duke
parents:
diff changeset
   566
    // private implementation allowing the selection interval
90ce3da70b43 Initial load
duke
parents:
diff changeset
   567
    // to be removed without affecting the lead and anchor
90ce3da70b43 Initial load
duke
parents:
diff changeset
   568
    private void removeSelectionIntervalImpl(int index0, int index1,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   569
                                             boolean changeLeadAnchor) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   570
90ce3da70b43 Initial load
duke
parents:
diff changeset
   571
        if (index0 == -1 || index1 == -1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   572
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   573
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   574
90ce3da70b43 Initial load
duke
parents:
diff changeset
   575
        if (changeLeadAnchor) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   576
            updateLeadAnchorIndices(index0, index1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   577
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   578
90ce3da70b43 Initial load
duke
parents:
diff changeset
   579
        int clearMin = Math.min(index0, index1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   580
        int clearMax = Math.max(index0, index1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   581
        int setMin = MAX;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   582
        int setMax = MIN;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   583
90ce3da70b43 Initial load
duke
parents:
diff changeset
   584
        // If the removal would produce to two disjoint selections in a mode
90ce3da70b43 Initial load
duke
parents:
diff changeset
   585
        // that only allows one, extend the removal to the end of the selection.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   586
        if (getSelectionMode() != MULTIPLE_INTERVAL_SELECTION &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   587
               clearMin > minIndex && clearMax < maxIndex) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   588
            clearMax = maxIndex;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   589
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   590
90ce3da70b43 Initial load
duke
parents:
diff changeset
   591
        changeSelection(clearMin, clearMax, setMin, setMax);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   592
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   593
90ce3da70b43 Initial load
duke
parents:
diff changeset
   594
    private void setState(int index, boolean state) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   595
        if (state) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   596
            set(index);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   597
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   598
        else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   599
            clear(index);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   600
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   601
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   602
90ce3da70b43 Initial load
duke
parents:
diff changeset
   603
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   604
     * Insert length indices beginning before/after index. If the value
90ce3da70b43 Initial load
duke
parents:
diff changeset
   605
     * at index is itself selected and the selection mode is not
90ce3da70b43 Initial load
duke
parents:
diff changeset
   606
     * SINGLE_SELECTION, set all of the newly inserted items as selected.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   607
     * Otherwise leave them unselected. This method is typically
90ce3da70b43 Initial load
duke
parents:
diff changeset
   608
     * called to sync the selection model with a corresponding change
90ce3da70b43 Initial load
duke
parents:
diff changeset
   609
     * in the data model.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   610
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   611
    public void insertIndexInterval(int index, int length, boolean before)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   612
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   613
        /* The first new index will appear at insMinIndex and the last
90ce3da70b43 Initial load
duke
parents:
diff changeset
   614
         * one will appear at insMaxIndex
90ce3da70b43 Initial load
duke
parents:
diff changeset
   615
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   616
        int insMinIndex = (before) ? index : index + 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   617
        int insMaxIndex = (insMinIndex + length) - 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   618
90ce3da70b43 Initial load
duke
parents:
diff changeset
   619
        /* Right shift the entire bitset by length, beginning with
90ce3da70b43 Initial load
duke
parents:
diff changeset
   620
         * index-1 if before is true, index+1 if it's false (i.e. with
90ce3da70b43 Initial load
duke
parents:
diff changeset
   621
         * insMinIndex).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   622
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   623
        for(int i = maxIndex; i >= insMinIndex; i--) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   624
            setState(i + length, value.get(i));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   625
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   626
90ce3da70b43 Initial load
duke
parents:
diff changeset
   627
        /* Initialize the newly inserted indices.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   628
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   629
        boolean setInsertedValues = ((getSelectionMode() == SINGLE_SELECTION) ?
90ce3da70b43 Initial load
duke
parents:
diff changeset
   630
                                        false : value.get(index));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   631
        for(int i = insMinIndex; i <= insMaxIndex; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   632
            setState(i, setInsertedValues);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   633
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   634
90ce3da70b43 Initial load
duke
parents:
diff changeset
   635
        int leadIndex = this.leadIndex;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   636
        if (leadIndex > index || (before && leadIndex == index)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   637
            leadIndex = this.leadIndex + length;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   638
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   639
        int anchorIndex = this.anchorIndex;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   640
        if (anchorIndex > index || (before && anchorIndex == index)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   641
            anchorIndex = this.anchorIndex + length;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   642
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   643
        if (leadIndex != this.leadIndex || anchorIndex != this.anchorIndex) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   644
            updateLeadAnchorIndices(anchorIndex, leadIndex);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   645
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   646
90ce3da70b43 Initial load
duke
parents:
diff changeset
   647
        fireValueChanged();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   648
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   649
90ce3da70b43 Initial load
duke
parents:
diff changeset
   650
90ce3da70b43 Initial load
duke
parents:
diff changeset
   651
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   652
     * Remove the indices in the interval index0,index1 (inclusive) from
90ce3da70b43 Initial load
duke
parents:
diff changeset
   653
     * the selection model.  This is typically called to sync the selection
90ce3da70b43 Initial load
duke
parents:
diff changeset
   654
     * model width a corresponding change in the data model.  Note
21592
da6abe91602a 8025234: [javadoc] fix some errors in javax.swing.**
yan
parents: 21278
diff changeset
   655
     * that (as always) index0 need not be &lt;= index1.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   656
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   657
    public void removeIndexInterval(int index0, int index1)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   658
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   659
        int rmMinIndex = Math.min(index0, index1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   660
        int rmMaxIndex = Math.max(index0, index1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   661
        int gapLength = (rmMaxIndex - rmMinIndex) + 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   662
90ce3da70b43 Initial load
duke
parents:
diff changeset
   663
        /* Shift the entire bitset to the left to close the index0, index1
90ce3da70b43 Initial load
duke
parents:
diff changeset
   664
         * gap.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   665
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   666
        for(int i = rmMinIndex; i <= maxIndex; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   667
            setState(i, value.get(i + gapLength));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   668
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   669
90ce3da70b43 Initial load
duke
parents:
diff changeset
   670
        int leadIndex = this.leadIndex;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   671
        if (leadIndex == 0 && rmMinIndex == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   672
            // do nothing
90ce3da70b43 Initial load
duke
parents:
diff changeset
   673
        } else if (leadIndex > rmMaxIndex) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   674
            leadIndex = this.leadIndex - gapLength;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   675
        } else if (leadIndex >= rmMinIndex) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   676
            leadIndex = rmMinIndex - 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   677
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   678
90ce3da70b43 Initial load
duke
parents:
diff changeset
   679
        int anchorIndex = this.anchorIndex;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   680
        if (anchorIndex == 0 && rmMinIndex == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   681
            // do nothing
90ce3da70b43 Initial load
duke
parents:
diff changeset
   682
        } else if (anchorIndex > rmMaxIndex) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   683
            anchorIndex = this.anchorIndex - gapLength;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   684
        } else if (anchorIndex >= rmMinIndex) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   685
            anchorIndex = rmMinIndex - 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   686
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   687
90ce3da70b43 Initial load
duke
parents:
diff changeset
   688
        if (leadIndex != this.leadIndex || anchorIndex != this.anchorIndex) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   689
            updateLeadAnchorIndices(anchorIndex, leadIndex);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   690
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   691
90ce3da70b43 Initial load
duke
parents:
diff changeset
   692
        fireValueChanged();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   693
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   694
90ce3da70b43 Initial load
duke
parents:
diff changeset
   695
90ce3da70b43 Initial load
duke
parents:
diff changeset
   696
    /** {@inheritDoc} */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   697
    public void setValueIsAdjusting(boolean isAdjusting) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   698
        if (isAdjusting != this.isAdjusting) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   699
            this.isAdjusting = isAdjusting;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   700
            this.fireValueChanged(isAdjusting);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   701
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   702
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   703
90ce3da70b43 Initial load
duke
parents:
diff changeset
   704
90ce3da70b43 Initial load
duke
parents:
diff changeset
   705
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   706
     * Returns a string that displays and identifies this
90ce3da70b43 Initial load
duke
parents:
diff changeset
   707
     * object's properties.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   708
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   709
     * @return a <code>String</code> representation of this object
90ce3da70b43 Initial load
duke
parents:
diff changeset
   710
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   711
    public String toString() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   712
        String s =  ((getValueIsAdjusting()) ? "~" : "=") + value.toString();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   713
        return getClass().getName() + " " + Integer.toString(hashCode()) + " " + s;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   714
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   715
90ce3da70b43 Initial load
duke
parents:
diff changeset
   716
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   717
     * Returns a clone of this selection model with the same selection.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   718
     * <code>listenerLists</code> are not duplicated.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   719
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   720
     * @exception CloneNotSupportedException if the selection model does not
90ce3da70b43 Initial load
duke
parents:
diff changeset
   721
     *    both (a) implement the Cloneable interface and (b) define a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   722
     *    <code>clone</code> method.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   723
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   724
    public Object clone() throws CloneNotSupportedException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   725
        DefaultListSelectionModel clone = (DefaultListSelectionModel)super.clone();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   726
        clone.value = (BitSet)value.clone();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   727
        clone.listenerList = new EventListenerList();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   728
        return clone;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   729
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   730
90ce3da70b43 Initial load
duke
parents:
diff changeset
   731
    /** {@inheritDoc} */
466
6acd5ec503a8 4935607: RFE: LTP: Should be possible to set the TRANSIENT attribute of propertiies to FALSE
malenkov
parents: 2
diff changeset
   732
    @Transient
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   733
    public int getAnchorSelectionIndex() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   734
        return anchorIndex;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   735
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   736
90ce3da70b43 Initial load
duke
parents:
diff changeset
   737
    /** {@inheritDoc} */
466
6acd5ec503a8 4935607: RFE: LTP: Should be possible to set the TRANSIENT attribute of propertiies to FALSE
malenkov
parents: 2
diff changeset
   738
    @Transient
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   739
    public int getLeadSelectionIndex() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   740
        return leadIndex;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   741
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   742
90ce3da70b43 Initial load
duke
parents:
diff changeset
   743
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   744
     * Set the anchor selection index, leaving all selection values unchanged.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   745
     * If leadAnchorNotificationEnabled is true, send a notification covering
90ce3da70b43 Initial load
duke
parents:
diff changeset
   746
     * the old and new anchor cells.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   747
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   748
     * @see #getAnchorSelectionIndex
90ce3da70b43 Initial load
duke
parents:
diff changeset
   749
     * @see #setLeadSelectionIndex
90ce3da70b43 Initial load
duke
parents:
diff changeset
   750
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   751
    public void setAnchorSelectionIndex(int anchorIndex) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   752
        updateLeadAnchorIndices(anchorIndex, this.leadIndex);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   753
        fireValueChanged();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   754
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   755
90ce3da70b43 Initial load
duke
parents:
diff changeset
   756
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   757
     * Set the lead selection index, leaving all selection values unchanged.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   758
     * If leadAnchorNotificationEnabled is true, send a notification covering
90ce3da70b43 Initial load
duke
parents:
diff changeset
   759
     * the old and new lead cells.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   760
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   761
     * @param leadIndex the new lead selection index
90ce3da70b43 Initial load
duke
parents:
diff changeset
   762
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   763
     * @see #setAnchorSelectionIndex
90ce3da70b43 Initial load
duke
parents:
diff changeset
   764
     * @see #setLeadSelectionIndex
90ce3da70b43 Initial load
duke
parents:
diff changeset
   765
     * @see #getLeadSelectionIndex
90ce3da70b43 Initial load
duke
parents:
diff changeset
   766
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   767
     * @since 1.5
90ce3da70b43 Initial load
duke
parents:
diff changeset
   768
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   769
    public void moveLeadSelectionIndex(int leadIndex) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   770
        // disallow a -1 lead unless the anchor is already -1
90ce3da70b43 Initial load
duke
parents:
diff changeset
   771
        if (leadIndex == -1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   772
            if (this.anchorIndex != -1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   773
                return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   774
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   775
90ce3da70b43 Initial load
duke
parents:
diff changeset
   776
/* PENDING(shannonh) - The following check is nice, to be consistent with
90ce3da70b43 Initial load
duke
parents:
diff changeset
   777
                       setLeadSelectionIndex. However, it is not absolutely
90ce3da70b43 Initial load
duke
parents:
diff changeset
   778
                       necessary: One could work around it by setting the anchor
90ce3da70b43 Initial load
duke
parents:
diff changeset
   779
                       to something valid, modifying the lead, and then moving
90ce3da70b43 Initial load
duke
parents:
diff changeset
   780
                       the anchor back to -1. For this reason, there's no sense
90ce3da70b43 Initial load
duke
parents:
diff changeset
   781
                       in adding it at this time, as that would require
90ce3da70b43 Initial load
duke
parents:
diff changeset
   782
                       updating the spec and officially committing to it.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   783
90ce3da70b43 Initial load
duke
parents:
diff changeset
   784
        // otherwise, don't do anything if the anchor is -1
90ce3da70b43 Initial load
duke
parents:
diff changeset
   785
        } else if (this.anchorIndex == -1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   786
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   787
*/
90ce3da70b43 Initial load
duke
parents:
diff changeset
   788
90ce3da70b43 Initial load
duke
parents:
diff changeset
   789
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   790
90ce3da70b43 Initial load
duke
parents:
diff changeset
   791
        updateLeadAnchorIndices(this.anchorIndex, leadIndex);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   792
        fireValueChanged();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   793
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   794
90ce3da70b43 Initial load
duke
parents:
diff changeset
   795
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   796
     * Sets the lead selection index, ensuring that values between the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   797
     * anchor and the new lead are either all selected or all deselected.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   798
     * If the value at the anchor index is selected, first clear all the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   799
     * values in the range [anchor, oldLeadIndex], then select all the values
90ce3da70b43 Initial load
duke
parents:
diff changeset
   800
     * values in the range [anchor, newLeadIndex], where oldLeadIndex is the old
90ce3da70b43 Initial load
duke
parents:
diff changeset
   801
     * leadIndex and newLeadIndex is the new one.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   802
     * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   803
     * If the value at the anchor index is not selected, do the same thing in
21278
ef8a3a2a72f2 8022746: List of spelling errors in API doc
malenkov
parents: 20458
diff changeset
   804
     * reverse selecting values in the old range and deselecting values in the
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   805
     * new one.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   806
     * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   807
     * Generate a single event for this change and notify all listeners.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   808
     * For the purposes of generating minimal bounds in this event, do the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   809
     * operation in a single pass; that way the first and last index inside the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   810
     * ListSelectionEvent that is broadcast will refer to cells that actually
90ce3da70b43 Initial load
duke
parents:
diff changeset
   811
     * changed value because of this method. If, instead, this operation were
90ce3da70b43 Initial load
duke
parents:
diff changeset
   812
     * done in two steps the effect on the selection state would be the same
90ce3da70b43 Initial load
duke
parents:
diff changeset
   813
     * but two events would be generated and the bounds around the changed
90ce3da70b43 Initial load
duke
parents:
diff changeset
   814
     * values would be wider, including cells that had been first cleared only
90ce3da70b43 Initial load
duke
parents:
diff changeset
   815
     * to later be set.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   816
     * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   817
     * This method can be used in the <code>mouseDragged</code> method
90ce3da70b43 Initial load
duke
parents:
diff changeset
   818
     * of a UI class to extend a selection.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   819
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   820
     * @see #getLeadSelectionIndex
90ce3da70b43 Initial load
duke
parents:
diff changeset
   821
     * @see #setAnchorSelectionIndex
90ce3da70b43 Initial load
duke
parents:
diff changeset
   822
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   823
    public void setLeadSelectionIndex(int leadIndex) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   824
        int anchorIndex = this.anchorIndex;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   825
90ce3da70b43 Initial load
duke
parents:
diff changeset
   826
        // only allow a -1 lead if the anchor is already -1
90ce3da70b43 Initial load
duke
parents:
diff changeset
   827
        if (leadIndex == -1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   828
            if (anchorIndex == -1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   829
                updateLeadAnchorIndices(anchorIndex, leadIndex);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   830
                fireValueChanged();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   831
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   832
90ce3da70b43 Initial load
duke
parents:
diff changeset
   833
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   834
        // otherwise, don't do anything if the anchor is -1
90ce3da70b43 Initial load
duke
parents:
diff changeset
   835
        } else if (anchorIndex == -1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   836
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   837
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   838
90ce3da70b43 Initial load
duke
parents:
diff changeset
   839
        if (this.leadIndex == -1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   840
            this.leadIndex = leadIndex;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   841
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   842
90ce3da70b43 Initial load
duke
parents:
diff changeset
   843
        boolean shouldSelect = value.get(this.anchorIndex);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   844
90ce3da70b43 Initial load
duke
parents:
diff changeset
   845
        if (getSelectionMode() == SINGLE_SELECTION) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   846
            anchorIndex = leadIndex;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   847
            shouldSelect = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   848
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   849
90ce3da70b43 Initial load
duke
parents:
diff changeset
   850
        int oldMin = Math.min(this.anchorIndex, this.leadIndex);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   851
        int oldMax = Math.max(this.anchorIndex, this.leadIndex);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   852
        int newMin = Math.min(anchorIndex, leadIndex);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   853
        int newMax = Math.max(anchorIndex, leadIndex);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   854
90ce3da70b43 Initial load
duke
parents:
diff changeset
   855
        updateLeadAnchorIndices(anchorIndex, leadIndex);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   856
90ce3da70b43 Initial load
duke
parents:
diff changeset
   857
        if (shouldSelect) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   858
            changeSelection(oldMin, oldMax, newMin, newMax);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   859
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   860
        else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   861
            changeSelection(newMin, newMax, oldMin, oldMax, false);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   862
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   863
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   864
}