OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [classpath/] [javax/] [swing/] [DefaultListSelectionModel.java] - Blame information for rev 772

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 772 jeremybenn
/* DefaultListSelectionModel.java --
2
   Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
3
 
4
This file is part of GNU Classpath.
5
 
6
GNU Classpath is free software; you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 2, or (at your option)
9
any later version.
10
 
11
GNU Classpath is distributed in the hope that it will be useful, but
12
WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
General Public License for more details.
15
 
16
You should have received a copy of the GNU General Public License
17
along with GNU Classpath; see the file COPYING.  If not, write to the
18
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19
02110-1301 USA.
20
 
21
Linking this library statically or dynamically with other modules is
22
making a combined work based on this library.  Thus, the terms and
23
conditions of the GNU General Public License cover the whole
24
combination.
25
 
26
As a special exception, the copyright holders of this library give you
27
permission to link this library with independent modules to produce an
28
executable, regardless of the license terms of these independent
29
modules, and to copy and distribute the resulting executable under
30
terms of your choice, provided that you also meet, for each linked
31
independent module, the terms and conditions of the license of that
32
module.  An independent module is a module which is not derived from
33
or based on this library.  If you modify this library, you may extend
34
this exception to your version of the library, but you are not
35
obligated to do so.  If you do not wish to do so, delete this
36
exception statement from your version. */
37
 
38
 
39
package javax.swing;
40
 
41
import java.io.Serializable;
42
import java.util.BitSet;
43
import java.util.EventListener;
44
 
45
import javax.swing.event.EventListenerList;
46
import javax.swing.event.ListSelectionEvent;
47
import javax.swing.event.ListSelectionListener;
48
 
49
/**
50
 * The default implementation of {@link ListSelectionModel},
51
 * which is used by {@link javax.swing.JList} and
52
 * similar classes to manage the selection status of a number of data
53
 * elements.
54
 *
55
 * <p>The class is organized <em>abstractly</em> as a set of intervals of
56
 * integers. Each interval indicates an inclusive range of indices in a
57
 * list -- held by some other object and unknown to this class -- which is
58
 * considered "selected". There are various accessors for querying and
59
 * modifying the set of intervals, with simplified forms accepting a single
60
 * index, representing an interval with only one element. </p>
61
 */
62
public class DefaultListSelectionModel implements Cloneable,
63
                                                  ListSelectionModel,
64
                                                  Serializable
65
{
66
  private static final long serialVersionUID = -5718799865110415860L;
67
 
68
  /** The list of ListSelectionListeners subscribed to this selection model. */
69
  protected EventListenerList listenerList = new EventListenerList();
70
 
71
 
72
  /**
73
   * The current list selection mode. Must be one of the numeric constants
74
   * <code>SINGLE_SELECTION</code>, <code>SINGLE_INTERVAL_SELECTION</code>
75
   * or <code>MULTIPLE_INTERVAL_SELECTION</code> from {@link
76
   * ListSelectionModel}. The default value is
77
   * <code>MULTIPLE_INTERVAL_SELECTION</code>.
78
   */
79
  int selectionMode = MULTIPLE_INTERVAL_SELECTION;
80
 
81
  /**
82
   * The index of the "lead" of the most recent selection. The lead is the
83
   * second argument in any call to {@link #setSelectionInterval}, {@link
84
   * #addSelectionInterval} or {@link #removeSelectionInterval}. Generally
85
   * the lead refers to the most recent position a user dragged their mouse
86
   * over.
87
   */
88
  int leadSelectionIndex = -1;
89
 
90
  /**
91
   * The index of the "anchor" of the most recent selection. The anchor is
92
   * the first argument in any call to {@link #setSelectionInterval},
93
   * {@link #addSelectionInterval} or {@link
94
   * #removeSelectionInterval}. Generally the anchor refers to the first
95
   * recent position a user clicks when they begin to drag their mouse over
96
   * a list.
97
   *
98
   * @see #getAnchorSelectionIndex
99
   * @see #setAnchorSelectionIndex
100
   */
101
  int anchorSelectionIndex = -1;
102
 
103
  /**
104
   * controls the range of indices provided in any {@link
105
   * ListSelectionEvent} fired by the selectionModel. Let
106
   * <code>[A,L]</code> be the range of indices between {@link
107
   * #anchorSelectionIndex} and {@link #leadSelectionIndex} inclusive, and
108
   * let <code>[i0,i1]</code> be the range of indices changed in a given
109
   * call which generates a {@link ListSelectionEvent}. Then when this
110
   * property is <code>true</code>, the {@link ListSelectionEvent} contains
111
   * the range <code>[A,L] union [i0,i1]</code>; when <code>false</code> it
112
   * will contain only <code>[i0,i1]</code>. The default is
113
   * <code>true</code>.
114
   *
115
   * @see #isLeadAnchorNotificationEnabled
116
   * @see #setLeadAnchorNotificationEnabled
117
   */
118
  protected boolean leadAnchorNotificationEnabled = true;
119
 
120
  /**
121
   * Whether the selection is currently "adjusting". Any {@link
122
   * ListSelectionEvent} events constructed in response to changes in this
123
   * list selection model will have their {@link
124
   * ListSelectionEvent#isAdjusting} field set to this value.
125
   *
126
   * @see #getValueIsAdjusting
127
   * @see #setValueIsAdjusting
128
   */
129
  boolean valueIsAdjusting = false;
130
 
131
 
132
  /**
133
   * The current set of "intervals", represented simply by a {@link
134
   * java.util.BitSet}. A set bit indicates a selected index, whereas a
135
   * cleared bit indicates a non-selected index.
136
   */
137
  BitSet sel = new BitSet();
138
 
139
  /**
140
   * A variable to store the previous value of sel.
141
   * Used to make sure we only fireValueChanged when the BitSet
142
   * actually does change.
143
   */
144
  Object oldSel;
145
 
146
  /**
147
   * Whether this call of setLeadSelectionInterval was called locally
148
   * from addSelectionInterval
149
   */
150
  boolean setLeadCalledFromAdd = false;
151
 
152
  /**
153
   * Returns the selection mode, which is one of {@link #SINGLE_SELECTION},
154
   * {@link #SINGLE_INTERVAL_SELECTION} and
155
   * {@link #MULTIPLE_INTERVAL_SELECTION}.  The default value is
156
   * {@link #MULTIPLE_INTERVAL_SELECTION}.
157
   *
158
   * @return The selection mode.
159
   *
160
   * @see #setSelectionMode(int)
161
   */
162
  public int getSelectionMode()
163
  {
164
    return selectionMode;
165
  }
166
 
167
  /**
168
   * Sets the value of the {@link #selectionMode} property.
169
   *
170
   * @param mode The new value of the property
171
   */
172
  public void setSelectionMode(int mode)
173
  {
174
    if (mode < ListSelectionModel.SINGLE_SELECTION
175
        || mode > ListSelectionModel.MULTIPLE_INTERVAL_SELECTION)
176
      throw new IllegalArgumentException("Unrecognised mode: " + mode);
177
    selectionMode = mode;
178
  }
179
 
180
  /**
181
   * Gets the value of the {@link #anchorSelectionIndex} property.
182
   *
183
   * @return The current property value
184
   *
185
   * @see #setAnchorSelectionIndex
186
   */
187
  public int getAnchorSelectionIndex()
188
  {
189
    return anchorSelectionIndex;
190
  }
191
 
192
  /**
193
   * Sets the value of the {@link #anchorSelectionIndex} property.
194
   *
195
   * @param index The new property value
196
   *
197
   * @see #getAnchorSelectionIndex
198
   */
199
  public void setAnchorSelectionIndex(int index)
200
  {
201
    if (anchorSelectionIndex != index)
202
      {
203
        int old = anchorSelectionIndex;
204
        anchorSelectionIndex = index;
205
        if (leadAnchorNotificationEnabled)
206
          fireValueChanged(index, old);
207
      }
208
  }
209
 
210
  /**
211
   * Gets the value of the {@link #leadSelectionIndex} property.
212
   *
213
   * @return The current property value
214
   *
215
   * @see #setLeadSelectionIndex
216
   */
217
  public int getLeadSelectionIndex()
218
  {
219
    return leadSelectionIndex;
220
  }
221
 
222
  /**
223
   * <p>Sets the value of the {@link #anchorSelectionIndex} property. As a
224
   * side effect, alters the selection status of two ranges of indices. Let
225
   * <code>OL</code> be the old lead selection index, <code>NL</code> be
226
   * the new lead selection index, and <code>A</code> be the anchor
227
   * selection index. Then if <code>A</code> is a valid selection index,
228
   * one of two things happens depending on the seleciton status of
229
   * <code>A</code>:</p>
230
   *
231
   * <ul>
232
   *
233
   * <li><code>isSelectedIndex(A) == true</code>: set <code>[A,OL]</code>
234
   * to <em>deselected</em>, then set <code>[A,NL]</code> to
235
   * <em>selected</em>.</li>
236
   *
237
   * <li><code>isSelectedIndex(A) == false</code>: set <code>[A,OL]</code>
238
   * to <em>selected</em>, then set <code>[A,NL]</code> to
239
   * <em>deselected</em>.</li>
240
   *
241
   * </ul>
242
   *
243
   * <p>This method generates at most a single {@link ListSelectionEvent}
244
   * despite changing multiple ranges. The range of values provided to the
245
   * {@link ListSelectionEvent} includes only the minimum range of values
246
   * which changed selection status between the beginning and end of the
247
   * method.</p>
248
   *
249
   * @param leadIndex The new property value
250
   *
251
   * @see #getAnchorSelectionIndex
252
   */
253
  public void setLeadSelectionIndex(int leadIndex)
254
  {
255
    // Only set the lead selection index to < 0 if anchorSelectionIndex < 0.
256
    if (leadIndex < 0)
257
      {
258
        if (anchorSelectionIndex < 0)
259
          leadSelectionIndex = -1;
260
        else
261
          return;
262
      }
263
 
264
    // Only touch the lead selection index if the anchor is >= 0.
265
    if (anchorSelectionIndex < 0)
266
      return;
267
 
268
    if (selectionMode == SINGLE_SELECTION)
269
      setSelectionInterval (leadIndex, leadIndex);
270
 
271
    int oldLeadIndex = leadSelectionIndex;
272
    if (oldLeadIndex == -1)
273
      oldLeadIndex = leadIndex;
274
    if (setLeadCalledFromAdd == false)
275
      oldSel = sel.clone();
276
    leadSelectionIndex = leadIndex;
277
 
278
    if (anchorSelectionIndex == -1)
279
      return;
280
 
281
    int R1 = Math.min(anchorSelectionIndex, oldLeadIndex);
282
    int R2 = Math.max(anchorSelectionIndex, oldLeadIndex);
283
    int S1 = Math.min(anchorSelectionIndex, leadIndex);
284
    int S2 = Math.max(anchorSelectionIndex, leadIndex);
285
 
286
    int lo = Math.min(R1, S1);
287
    int hi = Math.max(R2, S2);
288
 
289
    if (isSelectedIndex(anchorSelectionIndex))
290
      {
291
        sel.clear(R1, R2+1);
292
        sel.set(S1, S2+1);
293
      }
294
    else
295
      {
296
        sel.set(R1, R2+1);
297
        sel.clear(S1, S2+1);
298
      }
299
 
300
    int beg = sel.nextSetBit(0), end = -1;
301
    for(int i=beg; i >= 0; i=sel.nextSetBit(i+1))
302
      end = i;
303
 
304
    BitSet old = (BitSet) oldSel;
305
 
306
    // The new and previous lead location requires repainting.
307
    old.set(oldLeadIndex, !sel.get(oldLeadIndex));
308
    old.set(leadSelectionIndex, !sel.get(leadSelectionIndex));
309
 
310
    fireDifference(sel, old);
311
  }
312
 
313
  /**
314
   * Moves the lead selection index to <code>leadIndex</code> without
315
   * changing the selection values.
316
   *
317
   * If leadAnchorNotificationEnabled is true, send a notification covering the
318
   * old and new lead cells.
319
   *
320
   * @param leadIndex the new lead selection index
321
   * @since 1.5
322
   */
323
  public void moveLeadSelectionIndex (int leadIndex)
324
  {
325
    if (leadSelectionIndex == leadIndex)
326
      return;
327
 
328
    leadSelectionIndex = leadIndex;
329
    if (isLeadAnchorNotificationEnabled())
330
      fireValueChanged(Math.min(leadSelectionIndex, leadIndex),
331
                       Math.max(leadSelectionIndex, leadIndex));
332
  }
333
 
334
  /**
335
   * Gets the value of the {@link #leadAnchorNotificationEnabled} property.
336
   *
337
   * @return The current property value
338
   *
339
   * @see #setLeadAnchorNotificationEnabled
340
   */
341
  public boolean isLeadAnchorNotificationEnabled()
342
  {
343
    return leadAnchorNotificationEnabled;
344
  }
345
 
346
  /**
347
   * Sets the value of the {@link #leadAnchorNotificationEnabled} property.
348
   *
349
   * @param l The new property value
350
   *
351
   * @see #isLeadAnchorNotificationEnabled
352
   */
353
  public void setLeadAnchorNotificationEnabled(boolean l)
354
  {
355
    leadAnchorNotificationEnabled = l;
356
  }
357
 
358
  /**
359
   * Gets the value of the {@link #valueIsAdjusting} property.
360
   *
361
   * @return The current property value
362
   *
363
   * @see #setValueIsAdjusting
364
   */
365
  public boolean getValueIsAdjusting()
366
  {
367
    return valueIsAdjusting;
368
  }
369
 
370
  /**
371
   * Sets the value of the {@link #valueIsAdjusting} property.
372
   *
373
   * @param v The new property value
374
   *
375
   * @see #getValueIsAdjusting
376
   */
377
  public void setValueIsAdjusting(boolean v)
378
  {
379
    valueIsAdjusting = v;
380
  }
381
 
382
  /**
383
   * Determines whether the selection is empty.
384
   *
385
   * @return <code>true</code> if the selection is empty, otherwise
386
   * <code>false</code>
387
   */
388
  public boolean isSelectionEmpty()
389
  {
390
    return sel.isEmpty();
391
  }
392
 
393
  /**
394
   * Gets the smallest index which is currently a member of a selection
395
   * interval.
396
   *
397
   * @return The least integer <code>i</code> such that <code>i >=
398
   *     0</code> and <code>i</code> is a member of a selected interval, or
399
   *     <code>-1</code> if there are no selected intervals
400
   *
401
   * @see #getMaxSelectionIndex
402
   */
403
  public int getMinSelectionIndex()
404
  {
405
    if (isSelectionEmpty())
406
      return -1;
407
 
408
    return sel.nextSetBit(0);
409
  }
410
 
411
  /**
412
   * Gets the largest index which is currently a member of a selection
413
   * interval.
414
   *
415
   * @return The greatest integer <code>i</code> such that <code>i >=
416
   *     0</code> and <code>i</code> is a member of a selected interval, or
417
   *     <code>-1</code> if there are no selected intervals
418
   *
419
   * @see #getMinSelectionIndex
420
   */
421
  public int getMaxSelectionIndex()
422
  {
423
    if (isSelectionEmpty())
424
      return -1;
425
 
426
    int mx = -1;
427
    for(int i=sel.nextSetBit(0); i >= 0; i=sel.nextSetBit(i+1))
428
      {
429
        mx = i;
430
      }
431
    return mx;
432
  }
433
 
434
  /**
435
   * Determines whether a particular index is a member of a selection
436
   * interval.
437
   *
438
   * @param a The index to search for
439
   *
440
   * @return <code>true</code> if the index is a member of a selection interval,
441
   *     otherwise <code>false</code>
442
   */
443
  public boolean isSelectedIndex(int a)
444
  {
445
    // TODO: Probably throw an exception here?
446
    if (a >= sel.length() || a < 0)
447
      return false;
448
    return sel.get(a);
449
  }
450
 
451
  /**
452
   * If the {@link #selectionMode} property is equal to
453
   * <code>SINGLE_SELECTION</code> equivalent to calling
454
   * <code>setSelectionInterval(index1, index2)</code>;
455
   * If the {@link #selectionMode} property is equal to
456
   * <code>SINGLE_INTERVAL_SELECTION</code> and the interval being
457
   * added is not adjacent to an already selected interval,
458
   * equivalent to <code>setSelectionInterval(index1, index2)</code>.
459
   * Otherwise adds the range <code>[index0, index1]</code>
460
   * to the selection interval set.
461
   *
462
   * @param index0 The beginning of the range of indices to select
463
   * @param index1 The end of the range of indices to select
464
   *
465
   * @see #setSelectionInterval
466
   * @see #removeSelectionInterval
467
   */
468
  public void addSelectionInterval(int index0, int index1)
469
  {
470
    if (index0 == -1 || index1 == -1)
471
      return;
472
 
473
    if (selectionMode == SINGLE_SELECTION)
474
      setSelectionInterval(index0, index1);
475
    else
476
    {
477
    int lo = Math.min(index0, index1);
478
    int hi = Math.max(index0, index1);
479
    oldSel = sel.clone();
480
 
481
 
482
    // COMPAT: Like Sun (but not like IBM), we allow calls to
483
    // addSelectionInterval when selectionMode is
484
    // SINGLE_SELECTION_INTERVAL iff the interval being added
485
    // is adjacent to an already selected interval
486
    if (selectionMode == SINGLE_INTERVAL_SELECTION)
487
      if (!(isSelectedIndex(index0) ||
488
            isSelectedIndex(index1) ||
489
            isSelectedIndex(Math.max(lo-1,0)) ||
490
            isSelectedIndex(Math.min(hi+1,sel.size()))))
491
        sel.clear();
492
 
493
    // We have to update the anchorSelectionIndex and leadSelectionIndex
494
    // variables
495
 
496
    // The next if statements breaks down to "if this selection is adjacent
497
    // to the previous selection and going in the same direction"
498
    if ((isSelectedIndex(leadSelectionIndex))
499
        && ((index0 - 1 == leadSelectionIndex
500
             && (index1 >= index0)
501
             && (leadSelectionIndex >= anchorSelectionIndex))
502
            || (index0 + 1 == leadSelectionIndex && (index1 <= index0)
503
                && (leadSelectionIndex <= anchorSelectionIndex)))
504
        && (anchorSelectionIndex != -1 || leadSelectionIndex != -1))
505
      {
506
        // setting setLeadCalledFromAdd to true tells setLeadSelectionIndex
507
        //   not to update oldSel
508
        setLeadCalledFromAdd = true;
509
        setLeadSelectionIndex(index1);
510
        setLeadCalledFromAdd = false;
511
      }
512
    else
513
      {
514
        leadSelectionIndex = index1;
515
        anchorSelectionIndex = index0;
516
        sel.set(lo, hi+1);
517
        fireDifference(sel, (BitSet) oldSel);
518
      }
519
    }
520
  }
521
 
522
 
523
  /**
524
   * Deselects all indices in the inclusive range
525
   * <code>[index0,index1]</code>.
526
   *
527
   * @param index0 The beginning of the range of indices to deselect
528
   * @param index1 The end of the range of indices to deselect
529
   *
530
   * @see #addSelectionInterval
531
   * @see #setSelectionInterval
532
   */
533
  public void removeSelectionInterval(int index0,
534
                                      int index1)
535
  {
536
    if (index0 == -1 || index1 == -1)
537
      return;
538
 
539
    oldSel = sel.clone();
540
    int lo = Math.min(index0, index1);
541
    int hi = Math.max(index0, index1);
542
 
543
    // if selectionMode is SINGLE_INTERVAL_SELECTION and removing the interval
544
    //   (index0,index1) would leave two disjoint selection intervals, remove all
545
    //   selected indices from lo to the last selected index
546
    if (getMinSelectionIndex() > 0 && getMinSelectionIndex() < lo &&
547
        selectionMode == SINGLE_INTERVAL_SELECTION)
548
      hi = sel.size() - 1;
549
 
550
    sel.clear(lo, hi+1);
551
    //update anchorSelectionIndex and leadSelectionIndex variables
552
    //TODO: will probably need MouseDragged to test properly and know if this works
553
    setAnchorSelectionIndex(index0);
554
    leadSelectionIndex = index1;
555
 
556
    fireDifference(sel, (BitSet) oldSel);
557
  }
558
 
559
  /**
560
   * Removes all intervals in the selection set.
561
   */
562
  public void clearSelection()
563
  {
564
    // Find the selected interval.
565
    int from = sel.nextSetBit(0);
566
    if (from < 0)
567
      return; // Empty selection - nothing to do.
568
    int to = from;
569
 
570
    int i;
571
 
572
    for (i = from; i>=0; i=sel.nextSetBit(i+1))
573
      to = i;
574
 
575
    sel.clear();
576
    fireValueChanged(from, to, valueIsAdjusting);
577
  }
578
 
579
  /**
580
   * Fire the change event, covering the difference between the two sets.
581
   *
582
   * @param current the current set
583
   * @param x the previous set, the object will be reused.
584
   */
585
  private void fireDifference(BitSet current, BitSet x)
586
  {
587
    x.xor(current);
588
    int from = x.nextSetBit(0);
589
    if (from < 0)
590
      return; // No difference.
591
    int to = from;
592
    int i;
593
 
594
    for (i = from; i >= 0; i = x.nextSetBit(i+1))
595
      to = i;
596
 
597
    fireValueChanged(from, to, valueIsAdjusting);
598
  }
599
 
600
  /**
601
   * Clears the current selection and marks a given interval as "selected". If
602
   * the current selection mode is <code>SINGLE_SELECTION</code> only the
603
   * index <code>index2</code> is selected.
604
   *
605
   * @param anchor  the anchor selection index.
606
   * @param lead  the lead selection index.
607
   */
608
  public void setSelectionInterval(int anchor, int lead)
609
  {
610
    if (anchor == -1 || lead == -1)
611
      return;
612
    if (selectionMode == SINGLE_SELECTION)
613
      {
614
        int lo = lead;
615
        int hi = lead;
616
        int selected = sel.nextSetBit(0);
617
        if (selected == lead)
618
          return;  // the selection is not changing
619
        if (selected >= 0)
620
          {
621
            lo = Math.min(lo, selected);
622
            hi = Math.max(hi, selected);
623
          }
624
        if (anchorSelectionIndex >= 0)
625
          {
626
            lo = Math.min(lo, anchorSelectionIndex);
627
            hi = Math.max(hi, anchorSelectionIndex);
628
          }
629
        sel.clear();
630
        sel.set(lead);
631
        leadSelectionIndex = lead;
632
        anchorSelectionIndex = lead;
633
        fireValueChanged(lo, hi);
634
      }
635
    else if (selectionMode == SINGLE_INTERVAL_SELECTION)
636
      {
637
        // determine the current interval
638
        int first = sel.nextSetBit(0);
639
        int last = first;
640
        if (first >= 0)
641
          last += (sel.cardinality() - 1);
642
 
643
        // update the selection
644
        int lo = Math.min(anchor, lead);
645
        int hi = Math.max(anchor, lead);
646
        if (lo == first && hi == last)
647
          return;  // selected interval is not being changed
648
        sel.clear();
649
        sel.set(lo, hi + 1);
650
 
651
        // include the old selection in the event range
652
        if (first >= 0)
653
          lo = Math.min(lo, first);
654
        if (last >= 0)
655
          hi = Math.max(hi, last);
656
        if (anchorSelectionIndex >= 0)
657
          {
658
            lo = Math.min(lo, anchorSelectionIndex);
659
            hi = Math.max(hi, anchorSelectionIndex);
660
          }
661
        anchorSelectionIndex = anchor;
662
        leadSelectionIndex = lead;
663
        fireValueChanged(lo, hi);
664
      }
665
    else
666
    {
667
      BitSet oldSel = (BitSet) sel.clone();
668
      sel.clear();
669
      if (selectionMode == SINGLE_SELECTION)
670
        anchor = lead;
671
 
672
      int lo = Math.min(anchor, lead);
673
      int hi = Math.max(anchor, lead);
674
      sel.set(lo, hi+1);
675
      // update the anchorSelectionIndex and leadSelectionIndex variables
676
      setAnchorSelectionIndex(anchor);
677
      leadSelectionIndex = lead;
678
 
679
      fireDifference(sel, oldSel);
680
    }
681
  }
682
 
683
  /**
684
   * Inserts a number of indices either before or after a particular
685
   * position in the set of indices. Renumbers all indices after the
686
   * inserted range. The new indices in the inserted range are not
687
   * selected. This method is typically called to synchronize the selection
688
   * model with an inserted range of elements in a {@link ListModel}.
689
   *
690
   * @param index The position to insert indices at
691
   * @param length The number of indices to insert
692
   * @param before Indicates whether to insert the indices before the index
693
   *     or after it
694
   */
695
  public void insertIndexInterval(int index,
696
                                  int length,
697
                                  boolean before)
698
  {
699
    if (!before)
700
      {
701
        index++;
702
        length--;
703
      }
704
    BitSet tmp = sel.get(index, sel.size());
705
    sel.clear(index, sel.size());
706
    int n = tmp.size();
707
    for (int i = 0; i < n; ++i)
708
      sel.set(index + length + i, tmp.get(i));
709
  }
710
 
711
  /**
712
   * Removes a range from the set of indices. Renumbers all indices after
713
   * the removed range. This method is typically called to synchronize the
714
   * selection model with a deleted range of elements in a {@link
715
   * ListModel}.
716
   *
717
   * @param index0 The first index to remove (inclusive)
718
   * @param index1 The last index to remove (inclusive)
719
   */
720
  public void removeIndexInterval(int index0,
721
                                  int index1)
722
  {
723
    int lo = Math.min(index0, index1);
724
    int hi = Math.max(index0, index1);
725
 
726
    BitSet tmp = sel.get(hi, sel.size());
727
    sel.clear(lo, sel.size());
728
    int n = tmp.size();
729
    for (int i = 0; i < n; ++i)
730
      sel.set(lo + i, tmp.get(i));
731
  }
732
 
733
  /**
734
   * Fires a {@link ListSelectionEvent} to all the listeners of type {@link
735
   * ListSelectionListener} registered with this selection model to
736
   * indicate that a series of adjustment has just ended.
737
   *
738
   * The values of {@link #getMinSelectionIndex} and
739
   * {@link #getMaxSelectionIndex} are used in the {@link ListSelectionEvent}
740
   * that gets fired.
741
   *
742
   * @param isAdjusting <code>true</code> if this is the final change
743
   *     in a series of adjustments, <code>false/code> otherwise
744
   */
745
  protected void fireValueChanged(boolean isAdjusting)
746
  {
747
    fireValueChanged(getMinSelectionIndex(), getMaxSelectionIndex(),
748
                     isAdjusting);
749
  }
750
 
751
  /**
752
   * Fires a {@link ListSelectionEvent} to all the listeners of type {@link
753
   * ListSelectionListener} registered with this selection model.
754
   *
755
   * @param firstIndex The low index of the changed range
756
   * @param lastIndex The high index of the changed range
757
   */
758
  protected void fireValueChanged(int firstIndex, int lastIndex)
759
  {
760
    fireValueChanged(firstIndex, lastIndex, getValueIsAdjusting());
761
  }
762
 
763
  /**
764
   * Fires a {@link ListSelectionEvent} to all the listeners of type {@link
765
   * ListSelectionListener} registered with this selection model.
766
   *
767
   * @param firstIndex The low index of the changed range
768
   * @param lastIndex The high index of the changed range
769
   * @param isAdjusting Whether this change is part of a seqence of adjustments
770
   *     made to the selection, such as during interactive scrolling
771
   */
772
  protected void fireValueChanged(int firstIndex, int lastIndex,
773
                                  boolean isAdjusting)
774
  {
775
    ListSelectionEvent evt = new ListSelectionEvent(this, firstIndex,
776
                                                    lastIndex, isAdjusting);
777
    ListSelectionListener[] listeners = getListSelectionListeners();
778
    for (int i = 0; i < listeners.length; ++i)
779
      listeners[i].valueChanged(evt);
780
  }
781
 
782
  /**
783
   * Adds a listener.
784
   *
785
   * @param listener The listener to add
786
   *
787
   * @see #removeListSelectionListener
788
   * @see #getListSelectionListeners
789
   */
790
  public void addListSelectionListener(ListSelectionListener listener)
791
  {
792
    listenerList.add(ListSelectionListener.class, listener);
793
  }
794
 
795
  /**
796
   * Removes a registered listener.
797
   *
798
   * @param listener The listener to remove
799
   *
800
   * @see #addListSelectionListener
801
   * @see #getListSelectionListeners
802
   */
803
  public void removeListSelectionListener(ListSelectionListener listener)
804
  {
805
    listenerList.remove(ListSelectionListener.class, listener);
806
  }
807
 
808
  /**
809
   * Returns an array of all registerers listeners.
810
   *
811
   * @param listenerType The type of listener to retrieve
812
   *
813
   * @return The array
814
   *
815
   * @see #getListSelectionListeners
816
   * @since 1.3
817
   */
818
  public <T extends EventListener> T[] getListeners(Class<T> listenerType)
819
  {
820
    return listenerList.getListeners(listenerType);
821
  }
822
 
823
  /**
824
   * Returns an array of all registerd list selection listeners.
825
   *
826
   * @return the array
827
   *
828
   * @see #addListSelectionListener
829
   * @see #removeListSelectionListener
830
   * @see #getListeners
831
   * @since 1.4
832
   */
833
  public ListSelectionListener[] getListSelectionListeners()
834
  {
835
    return (ListSelectionListener[]) getListeners(ListSelectionListener.class);
836
  }
837
 
838
  /**
839
   * Returns a clone of this object.
840
   * <code>listenerList</code> don't gets duplicated.
841
   *
842
   * @return the cloned object
843
   *
844
   * @throws CloneNotSupportedException if an error occurs
845
   */
846
  public Object clone()
847
    throws CloneNotSupportedException
848
  {
849
    DefaultListSelectionModel model =
850
      (DefaultListSelectionModel) super.clone();
851
    model.sel = (BitSet) sel.clone();
852
    model.listenerList = new EventListenerList();
853
    return model;
854
  }
855
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.