1 /*
2  * Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.  Oracle designates this
8  * particular file as subject to the "Classpath" exception as provided
9  * by Oracle in the LICENSE file that accompanied this code.
10  *
11  * This code is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14  * version 2 for more details (a copy is included in the LICENSE file that
15  * accompanied this code).
16  *
17  * You should have received a copy of the GNU General Public License version
18  * 2 along with this work; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22  * or visit www.oracle.com if you need additional information or have any
23  * questions.
24  */
25 
26 package javax.swing;
27 
28 import javax.swing.event.*;
29 
30 /**
31  * This interface represents the current state of the
32  * selection for any of the components that display a
33  * list of values with stable indices.  The selection is
34  * modeled as a set of intervals, each interval represents
35  * a contiguous range of selected list elements.
36  * The methods for modifying the set of selected intervals
37  * all take a pair of indices, index0 and index1, that represent
38  * a closed interval, i.e. the interval includes both index0 and
39  * index1.
40  *
41  * @author Hans Muller
42  * @author Philip Milne
43  * @see DefaultListSelectionModel
44  * @since 1.2
45  */
46 
47 public interface ListSelectionModel
48 {
49     /**
50      * A value for the selectionMode property: select one list index
51      * at a time.
52      *
53      * @see #setSelectionMode
54      */
55     int SINGLE_SELECTION = 0;
56 
57     /**
58      * A value for the selectionMode property: select one contiguous
59      * range of indices at a time.
60      *
61      * @see #setSelectionMode
62      */
63     int SINGLE_INTERVAL_SELECTION = 1;
64 
65     /**
66      * A value for the selectionMode property: select one or more
67      * contiguous ranges of indices at a time.
68      *
69      * @see #setSelectionMode
70      */
71     int MULTIPLE_INTERVAL_SELECTION = 2;
72 
73 
74     /**
75      * Changes the selection to be between {@code index0} and {@code index1}
76      * inclusive. {@code index0} doesn't have to be less than or equal to
77      * {@code index1}.
78      * <p>
79      * In {@code SINGLE_SELECTION} selection mode, only the second index
80      * is used.
81      * <p>
82      * If this represents a change to the current selection, then each
83      * {@code ListSelectionListener} is notified of the change.
84      *
85      * @param index0 one end of the interval.
86      * @param index1 other end of the interval
87      * @see #addListSelectionListener
88      */
setSelectionInterval(int index0, int index1)89     void setSelectionInterval(int index0, int index1);
90 
91 
92     /**
93      * Changes the selection to be the set union of the current selection
94      * and the indices between {@code index0} and {@code index1} inclusive.
95      * {@code index0} doesn't have to be less than or equal to {@code index1}.
96      * <p>
97      * In {@code SINGLE_SELECTION} selection mode, this is equivalent
98      * to calling {@code setSelectionInterval}, and only the second index
99      * is used. In {@code SINGLE_INTERVAL_SELECTION} selection mode, this
100      * method behaves like {@code setSelectionInterval}, unless the given
101      * interval is immediately adjacent to or overlaps the existing selection,
102      * and can therefore be used to grow the selection.
103      * <p>
104      * If this represents a change to the current selection, then each
105      * {@code ListSelectionListener} is notified of the change.
106      *
107      * @param index0 one end of the interval.
108      * @param index1 other end of the interval
109      * @see #addListSelectionListener
110      * @see #setSelectionInterval
111      */
addSelectionInterval(int index0, int index1)112     void addSelectionInterval(int index0, int index1);
113 
114 
115     /**
116      * Changes the selection to be the set difference of the current selection
117      * and the indices between {@code index0} and {@code index1} inclusive.
118      * {@code index0} doesn't have to be less than or equal to {@code index1}.
119      * <p>
120      * In {@code SINGLE_INTERVAL_SELECTION} selection mode, if the removal
121      * would produce two disjoint selections, the removal is extended through
122      * the greater end of the selection. For example, if the selection is
123      * {@code 0-10} and you supply indices {@code 5,6} (in any order) the
124      * resulting selection is {@code 0-4}.
125      * <p>
126      * If this represents a change to the current selection, then each
127      * {@code ListSelectionListener} is notified of the change.
128      *
129      * @param index0 one end of the interval.
130      * @param index1 other end of the interval
131      * @see #addListSelectionListener
132      */
removeSelectionInterval(int index0, int index1)133     void removeSelectionInterval(int index0, int index1);
134 
135 
136     /**
137      * Returns the first selected index or -1 if the selection is empty.
138      *
139      * @return the first selected index or -1 if the selection is empty.
140      */
getMinSelectionIndex()141     int getMinSelectionIndex();
142 
143 
144     /**
145      * Returns the last selected index or -1 if the selection is empty.
146      *
147      * @return the last selected index or -1 if the selection is empty.
148      */
getMaxSelectionIndex()149     int getMaxSelectionIndex();
150 
151 
152     /**
153      * Returns true if the specified index is selected.
154      *
155      * @param index an index
156      * @return {@code true} if the specified index is selected
157      */
isSelectedIndex(int index)158     boolean isSelectedIndex(int index);
159 
160 
161     /**
162      * Return the first index argument from the most recent call to
163      * setSelectionInterval(), addSelectionInterval() or removeSelectionInterval().
164      * The most recent index0 is considered the "anchor" and the most recent
165      * index1 is considered the "lead".  Some interfaces display these
166      * indices specially, e.g. Windows95 displays the lead index with a
167      * dotted yellow outline.
168      *
169      * @return the anchor selection index
170      * @see #getLeadSelectionIndex
171      * @see #setSelectionInterval
172      * @see #addSelectionInterval
173      */
getAnchorSelectionIndex()174     int getAnchorSelectionIndex();
175 
176 
177     /**
178      * Set the anchor selection index.
179      *
180      * @param index the anchor selection index
181      * @see #getAnchorSelectionIndex
182      */
setAnchorSelectionIndex(int index)183     void setAnchorSelectionIndex(int index);
184 
185 
186     /**
187      * Return the second index argument from the most recent call to
188      * setSelectionInterval(), addSelectionInterval() or removeSelectionInterval().
189      *
190      * @return the lead selection index.
191      * @see #getAnchorSelectionIndex
192      * @see #setSelectionInterval
193      * @see #addSelectionInterval
194      */
getLeadSelectionIndex()195     int getLeadSelectionIndex();
196 
197     /**
198      * Set the lead selection index.
199      *
200      * @param index the lead selection index
201      * @see #getLeadSelectionIndex
202      */
setLeadSelectionIndex(int index)203     void setLeadSelectionIndex(int index);
204 
205     /**
206      * Change the selection to the empty set.  If this represents
207      * a change to the current selection then notify each ListSelectionListener.
208      *
209      * @see #addListSelectionListener
210      */
clearSelection()211     void clearSelection();
212 
213     /**
214      * Returns true if no indices are selected.
215      *
216      * @return {@code true} if no indices are selected.
217      */
isSelectionEmpty()218     boolean isSelectionEmpty();
219 
220     /**
221      * Insert {@code length} indices beginning before/after {@code index}. This is typically
222      * called to sync the selection model with a corresponding change
223      * in the data model.
224      *
225      * @param index the beginning of the interval
226      * @param length the length of the interval
227      * @param before if {@code true}, interval inserts before the {@code index},
228      *               otherwise, interval inserts after the {@code index}
229      */
insertIndexInterval(int index, int length, boolean before)230     void insertIndexInterval(int index, int length, boolean before);
231 
232     /**
233      * Remove the indices in the interval {@code index0,index1} (inclusive) from
234      * the selection model.  This is typically called to sync the selection
235      * model width a corresponding change in the data model.
236      *
237      * @param index0 the beginning of the interval
238      * @param index1 the end of the interval
239      */
removeIndexInterval(int index0, int index1)240     void removeIndexInterval(int index0, int index1);
241 
242     /**
243      * Sets the {@code valueIsAdjusting} property, which indicates whether
244      * or not upcoming selection changes should be considered part of a single
245      * change. The value of this property is used to initialize the
246      * {@code valueIsAdjusting} property of the {@code ListSelectionEvent}s that
247      * are generated.
248      * <p>
249      * For example, if the selection is being updated in response to a user
250      * drag, this property can be set to {@code true} when the drag is initiated
251      * and set to {@code false} when the drag is finished. During the drag,
252      * listeners receive events with a {@code valueIsAdjusting} property
253      * set to {@code true}. At the end of the drag, when the change is
254      * finalized, listeners receive an event with the value set to {@code false}.
255      * Listeners can use this pattern if they wish to update only when a change
256      * has been finalized.
257      * <p>
258      * Setting this property to {@code true} begins a series of changes that
259      * is to be considered part of a single change. When the property is changed
260      * back to {@code false}, an event is sent out characterizing the entire
261      * selection change (if there was one), with the event's
262      * {@code valueIsAdjusting} property set to {@code false}.
263      *
264      * @param valueIsAdjusting the new value of the property
265      * @see #getValueIsAdjusting
266      * @see javax.swing.event.ListSelectionEvent#getValueIsAdjusting
267      */
setValueIsAdjusting(boolean valueIsAdjusting)268     void setValueIsAdjusting(boolean valueIsAdjusting);
269 
270     /**
271      * Returns {@code true} if the selection is undergoing a series of changes.
272      *
273      * @return true if the selection is undergoing a series of changes
274      * @see #setValueIsAdjusting
275      */
getValueIsAdjusting()276     boolean getValueIsAdjusting();
277 
278     /**
279      * Sets the selection mode. The following list describes the accepted
280      * selection modes:
281      * <ul>
282      * <li>{@code ListSelectionModel.SINGLE_SELECTION} -
283      *   Only one list index can be selected at a time. In this mode,
284      *   {@code setSelectionInterval} and {@code addSelectionInterval} are
285      *   equivalent, both replacing the current selection with the index
286      *   represented by the second argument (the "lead").
287      * <li>{@code ListSelectionModel.SINGLE_INTERVAL_SELECTION} -
288      *   Only one contiguous interval can be selected at a time.
289      *   In this mode, {@code addSelectionInterval} behaves like
290      *   {@code setSelectionInterval} (replacing the current selection),
291      *   unless the given interval is immediately adjacent to or overlaps
292      *   the existing selection, and can therefore be used to grow it.
293      * <li>{@code ListSelectionModel.MULTIPLE_INTERVAL_SELECTION} -
294      *   In this mode, there's no restriction on what can be selected.
295      * </ul>
296      *
297      * @param selectionMode the selection mode
298      * @see #getSelectionMode
299      * @throws IllegalArgumentException if the selection mode isn't
300      *         one of those allowed
301      */
setSelectionMode(int selectionMode)302     void setSelectionMode(int selectionMode);
303 
304     /**
305      * Returns the current selection mode.
306      *
307      * @return the current selection mode
308      * @see #setSelectionMode
309      */
getSelectionMode()310     int getSelectionMode();
311 
312     /**
313      * Add a listener to the list that's notified each time a change
314      * to the selection occurs.
315      *
316      * @param x the ListSelectionListener
317      * @see #removeListSelectionListener
318      * @see #setSelectionInterval
319      * @see #addSelectionInterval
320      * @see #removeSelectionInterval
321      * @see #clearSelection
322      * @see #insertIndexInterval
323      * @see #removeIndexInterval
324      */
addListSelectionListener(ListSelectionListener x)325     void addListSelectionListener(ListSelectionListener x);
326 
327     /**
328      * Remove a listener from the list that's notified each time a
329      * change to the selection occurs.
330      *
331      * @param x the ListSelectionListener
332      * @see #addListSelectionListener
333      */
removeListSelectionListener(ListSelectionListener x)334     void removeListSelectionListener(ListSelectionListener x);
335 
336     /**
337      * Returns an array of all of the selected indices in the selection model,
338      * in increasing order.
339      *
340      * @return all of the selected indices, in increasing order,
341      *         or an empty array if nothing is selected
342      * @see #removeSelectionInterval
343      * @see #addListSelectionListener
344      * @since 11
345      * @implSpec The default implementation iterates from minimum selected
346      * index {@link #getMinSelectionIndex()} to maximum selected index {@link
347      * #getMaxSelectionIndex()} and returns the selected indices {@link
348      * #isSelectedIndex(int)} in a newly allocated int array.
349      */
getSelectedIndices()350     default int[] getSelectedIndices() {
351         int iMin = getMinSelectionIndex();
352         int iMax = getMaxSelectionIndex();
353 
354         if ((iMin < 0) || (iMax < 0)) {
355             return new int[0];
356         }
357 
358         int[] rvTmp = new int[1+ (iMax - iMin)];
359         int n = 0;
360         for(int i = iMin; i <= iMax; i++) {
361             if (isSelectedIndex(i)) {
362                 rvTmp[n++] = i;
363             }
364         }
365         int[] rv = new int[n];
366         System.arraycopy(rvTmp, 0, rv, 0, n);
367         return rv;
368     }
369 
370     /**
371      * Returns the number of selected items.
372      *
373      * @return the number of selected items, 0 if no items are selected
374      * @since 11
375      * @implSpec The default implementation iterates from minimum selected
376      * index {@link #getMinSelectionIndex()} to maximum selected index {@link
377      * #getMaxSelectionIndex()} and returns the number of selected indices
378      * {@link #isSelectedIndex(int)}
379      */
getSelectedItemsCount()380     default int getSelectedItemsCount() {
381         int iMin = getMinSelectionIndex();
382         int iMax = getMaxSelectionIndex();
383         int count = 0;
384 
385         for(int i = iMin; i <= iMax; i++) {
386             if (isSelectedIndex(i)) {
387                 count++;
388             }
389         }
390         return count;
391     }
392 }
393