1 7 8 package javax.swing; 9 10 import java.util.EventListener ; 11 import java.util.BitSet ; 12 import java.io.Serializable ; 13 14 import javax.swing.event.*; 15 16 17 34 35 public class DefaultListSelectionModel implements ListSelectionModel , Cloneable , Serializable 36 { 37 private static final int MIN = -1; 38 private static final int MAX = Integer.MAX_VALUE; 39 private int selectionMode = MULTIPLE_INTERVAL_SELECTION; 40 private int minIndex = MAX; 41 private int maxIndex = MIN; 42 private int anchorIndex = -1; 43 private int leadIndex = -1; 44 private int firstAdjustedIndex = MAX; 45 private int lastAdjustedIndex = MIN; 46 private boolean isAdjusting = false; 47 48 private int firstChangedIndex = MAX; 49 private int lastChangedIndex = MIN; 50 51 private BitSet value = new BitSet (32); 52 protected EventListenerList listenerList = new EventListenerList(); 53 54 protected boolean leadAnchorNotificationEnabled = true; 55 56 public int getMinSelectionIndex() { return isSelectionEmpty() ? -1 : minIndex; } 58 59 public int getMaxSelectionIndex() { return maxIndex; } 61 62 public boolean getValueIsAdjusting() { return isAdjusting; } 64 65 76 public int getSelectionMode() { return selectionMode; } 77 78 92 public void setSelectionMode(int selectionMode) { 93 switch (selectionMode) { 94 case SINGLE_SELECTION: 95 case SINGLE_INTERVAL_SELECTION: 96 case MULTIPLE_INTERVAL_SELECTION: 97 this.selectionMode = selectionMode; 98 break; 99 default: 100 throw new IllegalArgumentException ("invalid selectionMode"); 101 } 102 } 103 104 public boolean isSelectedIndex(int index) { 106 return ((index < minIndex) || (index > maxIndex)) ? false : value.get(index); 107 } 108 109 public boolean isSelectionEmpty() { 111 return (minIndex > maxIndex); 112 } 113 114 public void addListSelectionListener(ListSelectionListener l) { 116 listenerList.add(ListSelectionListener.class, l); 117 } 118 119 public void removeListSelectionListener(ListSelectionListener l) { 121 listenerList.remove(ListSelectionListener.class, l); 122 } 123 124 137 public ListSelectionListener[] getListSelectionListeners() { 138 return (ListSelectionListener[])listenerList.getListeners( 139 ListSelectionListener.class); 140 } 141 142 145 protected void fireValueChanged(boolean isAdjusting) { 146 if (lastChangedIndex == MIN) { 147 return; 148 } 149 153 int oldFirstChangedIndex = firstChangedIndex; 154 int oldLastChangedIndex = lastChangedIndex; 155 firstChangedIndex = MAX; 156 lastChangedIndex = MIN; 157 fireValueChanged(oldFirstChangedIndex, oldLastChangedIndex, isAdjusting); 158 } 159 160 161 166 protected void fireValueChanged(int firstIndex, int lastIndex) { 167 fireValueChanged(firstIndex, lastIndex, getValueIsAdjusting()); 168 } 169 170 177 protected void fireValueChanged(int firstIndex, int lastIndex, boolean isAdjusting) 178 { 179 Object [] listeners = listenerList.getListenerList(); 180 ListSelectionEvent e = null; 181 182 for (int i = listeners.length - 2; i >= 0; i -= 2) { 183 if (listeners[i] == ListSelectionListener.class) { 184 if (e == null) { 185 e = new ListSelectionEvent(this, firstIndex, lastIndex, isAdjusting); 186 } 187 ((ListSelectionListener)listeners[i+1]).valueChanged(e); 188 } 189 } 190 } 191 192 private void fireValueChanged() { 193 if (lastAdjustedIndex == MIN) { 194 return; 195 } 196 201 if (getValueIsAdjusting()) { 202 firstChangedIndex = Math.min(firstChangedIndex, firstAdjustedIndex); 203 lastChangedIndex = Math.max(lastChangedIndex, lastAdjustedIndex); 204 } 205 209 int oldFirstAdjustedIndex = firstAdjustedIndex; 210 int oldLastAdjustedIndex = lastAdjustedIndex; 211 firstAdjustedIndex = MAX; 212 lastAdjustedIndex = MIN; 213 214 fireValueChanged(oldFirstAdjustedIndex, oldLastAdjustedIndex); 215 } 216 217 252 public <T extends EventListener > T[] getListeners(Class <T> listenerType) { 253 return listenerList.getListeners(listenerType); 254 } 255 256 private void markAsDirty(int r) { 258 firstAdjustedIndex = Math.min(firstAdjustedIndex, r); 259 lastAdjustedIndex = Math.max(lastAdjustedIndex, r); 260 } 261 262 private void set(int r) { 264 if (value.get(r)) { 265 return; 266 } 267 value.set(r); 268 markAsDirty(r); 269 270 minIndex = Math.min(minIndex, r); 272 maxIndex = Math.max(maxIndex, r); 273 } 274 275 private void clear(int r) { 277 if (!value.get(r)) { 278 return; 279 } 280 value.clear(r); 281 markAsDirty(r); 282 283 290 if (r == minIndex) { 291 for(minIndex = minIndex + 1; minIndex <= maxIndex; minIndex++) { 292 if (value.get(minIndex)) { 293 break; 294 } 295 } 296 } 297 303 if (r == maxIndex) { 304 for(maxIndex = maxIndex - 1; minIndex <= maxIndex; maxIndex--) { 305 if (value.get(maxIndex)) { 306 break; 307 } 308 } 309 } 310 325 if (isSelectionEmpty()) { 326 minIndex = MAX; 327 maxIndex = MIN; 328 } 329 } 330 331 335 public void setLeadAnchorNotificationEnabled(boolean flag) { 336 leadAnchorNotificationEnabled = flag; 337 } 338 339 357 public boolean isLeadAnchorNotificationEnabled() { 358 return leadAnchorNotificationEnabled; 359 } 360 361 private void updateLeadAnchorIndices(int anchorIndex, int leadIndex) { 362 if (leadAnchorNotificationEnabled) { 363 if (this.anchorIndex != anchorIndex) { 364 if (this.anchorIndex != -1) { markAsDirty(this.anchorIndex); 366 } 367 markAsDirty(anchorIndex); 368 } 369 370 if (this.leadIndex != leadIndex) { 371 if (this.leadIndex != -1) { markAsDirty(this.leadIndex); 373 } 374 markAsDirty(leadIndex); 375 } 376 } 377 this.anchorIndex = anchorIndex; 378 this.leadIndex = leadIndex; 379 } 380 381 private boolean contains(int a, int b, int i) { 382 return (i >= a) && (i <= b); 383 } 384 385 private void changeSelection(int clearMin, int clearMax, 386 int setMin, int setMax, boolean clearFirst) { 387 for(int i = Math.min(setMin, clearMin); i <= Math.max(setMax, clearMax); i++) { 388 389 boolean shouldClear = contains(clearMin, clearMax, i); 390 boolean shouldSet = contains(setMin, setMax, i); 391 392 if (shouldSet && shouldClear) { 393 if (clearFirst) { 394 shouldClear = false; 395 } 396 else { 397 shouldSet = false; 398 } 399 } 400 401 if (shouldSet) { 402 set(i); 403 } 404 if (shouldClear) { 405 clear(i); 406 } 407 } 408 fireValueChanged(); 409 } 410 411 416 private void changeSelection(int clearMin, int clearMax, int setMin, int setMax) { 417 changeSelection(clearMin, clearMax, setMin, setMax, true); 418 } 419 420 public void clearSelection() { 422 removeSelectionIntervalImpl(minIndex, maxIndex, false); 423 } 424 425 public void setSelectionInterval(int index0, int index1) { 427 if (index0 == -1 || index1 == -1) { 428 return; 429 } 430 431 if (getSelectionMode() == SINGLE_SELECTION) { 432 index0 = index1; 433 } 434 435 updateLeadAnchorIndices(index0, index1); 436 437 int clearMin = minIndex; 438 int clearMax = maxIndex; 439 int setMin = Math.min(index0, index1); 440 int setMax = Math.max(index0, index1); 441 changeSelection(clearMin, clearMax, setMin, setMax); 442 } 443 444 public void addSelectionInterval(int index0, int index1) 446 { 447 if (index0 == -1 || index1 == -1) { 448 return; 449 } 450 451 if (getSelectionMode() == SINGLE_SELECTION) { 454 setSelectionInterval(index0, index1); 455 return; 456 } 457 458 updateLeadAnchorIndices(index0, index1); 459 460 int clearMin = MAX; 461 int clearMax = MIN; 462 int setMin = Math.min(index0, index1); 463 int setMax = Math.max(index0, index1); 464 465 if (getSelectionMode() == SINGLE_INTERVAL_SELECTION && 469 (setMax < minIndex - 1 || setMin > maxIndex + 1)) { 470 471 setSelectionInterval(index0, index1); 472 return; 473 } 474 475 changeSelection(clearMin, clearMax, setMin, setMax); 476 } 477 478 479 public void removeSelectionInterval(int index0, int index1) 481 { 482 removeSelectionIntervalImpl(index0, index1, true); 483 } 484 485 private void removeSelectionIntervalImpl(int index0, int index1, 488 boolean changeLeadAnchor) { 489 490 if (index0 == -1 || index1 == -1) { 491 return; 492 } 493 494 if (changeLeadAnchor) { 495 updateLeadAnchorIndices(index0, index1); 496 } 497 498 int clearMin = Math.min(index0, index1); 499 int clearMax = Math.max(index0, index1); 500 int setMin = MAX; 501 int setMax = MIN; 502 503 if (getSelectionMode() != MULTIPLE_INTERVAL_SELECTION && 506 clearMin > minIndex && clearMax < maxIndex) { 507 clearMax = maxIndex; 508 } 509 510 changeSelection(clearMin, clearMax, setMin, setMax); 511 } 512 513 private void setState(int index, boolean state) { 514 if (state) { 515 set(index); 516 } 517 else { 518 clear(index); 519 } 520 } 521 522 530 public void insertIndexInterval(int index, int length, boolean before) 531 { 532 535 int insMinIndex = (before) ? index : index + 1; 536 int insMaxIndex = (insMinIndex + length) - 1; 537 538 542 for(int i = maxIndex; i >= insMinIndex; i--) { 543 setState(i + length, value.get(i)); 544 } 545 546 548 boolean setInsertedValues = ((getSelectionMode() == SINGLE_SELECTION) ? 549 false : value.get(index)); 550 for(int i = insMinIndex; i <= insMaxIndex; i++) { 551 setState(i, setInsertedValues); 552 } 553 554 int leadIndex = this.leadIndex; 555 if (leadIndex > index || (before && leadIndex == index)) { 556 leadIndex = this.leadIndex + length; 557 } 558 int anchorIndex = this.anchorIndex; 559 if (anchorIndex > index || (before && anchorIndex == index)) { 560 anchorIndex = this.anchorIndex + length; 561 } 562 if (leadIndex != this.leadIndex || anchorIndex != this.anchorIndex) { 563 updateLeadAnchorIndices(anchorIndex, leadIndex); 564 } 565 566 fireValueChanged(); 567 } 568 569 570 576 public void removeIndexInterval(int index0, int index1) 577 { 578 int rmMinIndex = Math.min(index0, index1); 579 int rmMaxIndex = Math.max(index0, index1); 580 int gapLength = (rmMaxIndex - rmMinIndex) + 1; 581 582 585 for(int i = rmMinIndex; i <= maxIndex; i++) { 586 setState(i, value.get(i + gapLength)); 587 } 588 589 int leadIndex = this.leadIndex; 590 if (leadIndex == 0 && rmMinIndex == 0) { 591 } else if (leadIndex > rmMaxIndex) { 593 leadIndex = this.leadIndex - gapLength; 594 } else if (leadIndex >= rmMinIndex) { 595 leadIndex = rmMinIndex - 1; 596 } 597 598 int anchorIndex = this.anchorIndex; 599 if (anchorIndex == 0 && rmMinIndex == 0) { 600 } else if (anchorIndex > rmMaxIndex) { 602 anchorIndex = this.anchorIndex - gapLength; 603 } else if (anchorIndex >= rmMinIndex) { 604 anchorIndex = rmMinIndex - 1; 605 } 606 607 if (leadIndex != this.leadIndex || anchorIndex != this.anchorIndex) { 608 updateLeadAnchorIndices(anchorIndex, leadIndex); 609 } 610 611 fireValueChanged(); 612 } 613 614 615 public void setValueIsAdjusting(boolean isAdjusting) { 617 if (isAdjusting != this.isAdjusting) { 618 this.isAdjusting = isAdjusting; 619 this.fireValueChanged(isAdjusting); 620 } 621 } 622 623 624 630 public String toString() { 631 String s = ((getValueIsAdjusting()) ? "~" : "=") + value.toString(); 632 return getClass().getName() + " " + Integer.toString(hashCode()) + " " + s; 633 } 634 635 643 public Object clone() throws CloneNotSupportedException { 644 DefaultListSelectionModel clone = (DefaultListSelectionModel )super.clone(); 645 clone.value = (BitSet )value.clone(); 646 clone.listenerList = new EventListenerList(); 647 return clone; 648 } 649 650 public int getAnchorSelectionIndex() { 652 return anchorIndex; 653 } 654 655 public int getLeadSelectionIndex() { 657 return leadIndex; 658 } 659 660 668 public void setAnchorSelectionIndex(int anchorIndex) { 669 updateLeadAnchorIndices(anchorIndex, this.leadIndex); 670 fireValueChanged(); 671 } 672 673 686 public void moveLeadSelectionIndex(int leadIndex) { 687 if (leadIndex == -1) { 689 if (this.anchorIndex != -1) { 690 return; 691 } 692 693 705 706 } 707 708 updateLeadAnchorIndices(this.anchorIndex, leadIndex); 709 fireValueChanged(); 710 } 711 712 740 public void setLeadSelectionIndex(int leadIndex) { 741 int anchorIndex = this.anchorIndex; 742 743 if (leadIndex == -1) { 745 if (anchorIndex == -1) { 746 updateLeadAnchorIndices(anchorIndex, leadIndex); 747 fireValueChanged(); 748 } 749 750 return; 751 } else if (anchorIndex == -1) { 753 return; 754 } 755 756 if (this.leadIndex == -1) { 757 this.leadIndex = leadIndex; 758 } 759 760 boolean shouldSelect = value.get(this.anchorIndex); 761 762 if (getSelectionMode() == SINGLE_SELECTION) { 763 anchorIndex = leadIndex; 764 shouldSelect = true; 765 } 766 767 int oldMin = Math.min(this.anchorIndex, this.leadIndex); 768 int oldMax = Math.max(this.anchorIndex, this.leadIndex); 769 int newMin = Math.min(anchorIndex, leadIndex); 770 int newMax = Math.max(anchorIndex, leadIndex); 771 772 updateLeadAnchorIndices(anchorIndex, leadIndex); 773 774 if (shouldSelect) { 775 changeSelection(oldMin, oldMax, newMin, newMax); 776 } 777 else { 778 changeSelection(newMin, newMax, oldMin, oldMax, false); 779 } 780 } 781 } 782 783 | Popular Tags |