GNU Classpath (0.91) | |
Frames | No Frames |
1: /* 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: * Gets the value of the {@link #selectionMode} property. 154: * 155: * @return The current value of the property 156: */ 157: public int getSelectionMode() 158: { 159: return selectionMode; 160: } 161: 162: /** 163: * Sets the value of the {@link #selectionMode} property. 164: * 165: * @param mode The new value of the property 166: */ 167: public void setSelectionMode(int mode) 168: { 169: if (mode < ListSelectionModel.SINGLE_SELECTION 170: || mode > ListSelectionModel.MULTIPLE_INTERVAL_SELECTION) 171: throw new IllegalArgumentException("Unrecognised mode: " + mode); 172: selectionMode = mode; 173: } 174: 175: /** 176: * Gets the value of the {@link #anchorSelectionIndex} property. 177: * 178: * @return The current property value 179: * 180: * @see #setAnchorSelectionIndex 181: */ 182: public int getAnchorSelectionIndex() 183: { 184: return anchorSelectionIndex; 185: } 186: 187: /** 188: * Sets the value of the {@link #anchorSelectionIndex} property. 189: * 190: * @param anchorIndex The new property value 191: * 192: * @see #getAnchorSelectionIndex 193: */ 194: public void setAnchorSelectionIndex(int anchorIndex) 195: { 196: anchorSelectionIndex = anchorIndex; 197: } 198: 199: /** 200: * Gets the value of the {@link #leadSelectionIndex} property. 201: * 202: * @return The current property value 203: * 204: * @see #setLeadSelectionIndex 205: */ 206: public int getLeadSelectionIndex() 207: { 208: return leadSelectionIndex; 209: } 210: 211: /** 212: * <p>Sets the value of the {@link #anchorSelectionIndex} property. As a 213: * side effect, alters the selection status of two ranges of indices. Let 214: * <code>OL</code> be the old lead selection index, <code>NL</code> be 215: * the new lead selection index, and <code>A</code> be the anchor 216: * selection index. Then if <code>A</code> is a valid selection index, 217: * one of two things happens depending on the seleciton status of 218: * <code>A</code>:</p> 219: * 220: * <ul> 221: * 222: * <li><code>isSelectedIndex(A) == true</code>: set <code>[A,OL]</code> 223: * to <em>deselected</em>, then set <code>[A,NL]</code> to 224: * <em>selected</em>.</li> 225: * 226: * <li><code>isSelectedIndex(A) == false</code>: set <code>[A,OL]</code> 227: * to <em>selected</em>, then set <code>[A,NL]</code> to 228: * <em>deselected</em>.</li> 229: * 230: * </ul> 231: * 232: * <p>This method generates at most a single {@link ListSelectionEvent} 233: * despite changing multiple ranges. The range of values provided to the 234: * {@link ListSelectionEvent} includes only the minimum range of values 235: * which changed selection status between the beginning and end of the 236: * method.</p> 237: * 238: * @param leadIndex The new property value 239: * 240: * @see #getAnchorSelectionIndex 241: */ 242: public void setLeadSelectionIndex(int leadIndex) 243: { 244: // Only set the lead selection index to < 0 if anchorSelectionIndex < 0. 245: if (leadIndex < 0) 246: { 247: if (anchorSelectionIndex < 0) 248: leadSelectionIndex = -1; 249: else 250: return; 251: } 252: 253: // Only touch the lead selection index if the anchor is >= 0. 254: if (anchorSelectionIndex < 0) 255: return; 256: 257: if (selectionMode == SINGLE_SELECTION) 258: setSelectionInterval (leadIndex, leadIndex); 259: 260: int oldLeadIndex = leadSelectionIndex; 261: if (oldLeadIndex == -1) 262: oldLeadIndex = leadIndex; 263: if (setLeadCalledFromAdd == false) 264: oldSel = sel.clone(); 265: leadSelectionIndex = leadIndex; 266: 267: if (anchorSelectionIndex == -1) 268: return; 269: 270: int R1 = Math.min(anchorSelectionIndex, oldLeadIndex); 271: int R2 = Math.max(anchorSelectionIndex, oldLeadIndex); 272: int S1 = Math.min(anchorSelectionIndex, leadIndex); 273: int S2 = Math.max(anchorSelectionIndex, leadIndex); 274: 275: int lo = Math.min(R1, S1); 276: int hi = Math.max(R2, S2); 277: 278: if (isSelectedIndex(anchorSelectionIndex)) 279: { 280: sel.clear(R1, R2+1); 281: sel.set(S1, S2+1); 282: } 283: else 284: { 285: sel.set(R1, R2+1); 286: sel.clear(S1, S2+1); 287: } 288: 289: int beg = sel.nextSetBit(0), end = -1; 290: for(int i=beg; i >= 0; i=sel.nextSetBit(i+1)) 291: end = i; 292: 293: BitSet old = (BitSet) oldSel; 294: 295: // The new and previous lead location requires repainting. 296: old.set(oldLeadIndex, !sel.get(oldLeadIndex)); 297: old.set(leadSelectionIndex, !sel.get(leadSelectionIndex)); 298: 299: fireDifference(sel, old); 300: } 301: 302: /** 303: * Moves the lead selection index to <code>leadIndex</code> without 304: * changing the selection values. 305: * 306: * If leadAnchorNotificationEnabled is true, send a notification covering the 307: * old and new lead cells. 308: * 309: * @param leadIndex the new lead selection index 310: * @since 1.5 311: */ 312: public void moveLeadSelectionIndex (int leadIndex) 313: { 314: if (leadSelectionIndex == leadIndex) 315: return; 316: 317: leadSelectionIndex = leadIndex; 318: if (isLeadAnchorNotificationEnabled()) 319: fireValueChanged(Math.min(leadSelectionIndex, leadIndex), 320: Math.max(leadSelectionIndex, leadIndex)); 321: } 322: 323: /** 324: * Gets the value of the {@link #leadAnchorNotificationEnabled} property. 325: * 326: * @return The current property value 327: * 328: * @see #setLeadAnchorNotificationEnabled 329: */ 330: public boolean isLeadAnchorNotificationEnabled() 331: { 332: return leadAnchorNotificationEnabled; 333: } 334: 335: /** 336: * Sets the value of the {@link #leadAnchorNotificationEnabled} property. 337: * 338: * @param l The new property value 339: * 340: * @see #isLeadAnchorNotificationEnabled 341: */ 342: public void setLeadAnchorNotificationEnabled(boolean l) 343: { 344: leadAnchorNotificationEnabled = l; 345: } 346: 347: /** 348: * Gets the value of the {@link #valueIsAdjusting} property. 349: * 350: * @return The current property value 351: * 352: * @see #setValueIsAdjusting 353: */ 354: public boolean getValueIsAdjusting() 355: { 356: return valueIsAdjusting; 357: } 358: 359: /** 360: * Sets the value of the {@link #valueIsAdjusting} property. 361: * 362: * @param v The new property value 363: * 364: * @see #getValueIsAdjusting 365: */ 366: public void setValueIsAdjusting(boolean v) 367: { 368: valueIsAdjusting = v; 369: } 370: 371: /** 372: * Determines whether the selection is empty. 373: * 374: * @return <code>true</code> if the selection is empty, otherwise 375: * <code>false</code> 376: */ 377: public boolean isSelectionEmpty() 378: { 379: return sel.isEmpty(); 380: } 381: 382: /** 383: * Gets the smallest index which is currently a member of a selection 384: * interval. 385: * 386: * @return The least integer <code>i</code> such that <code>i >= 387: * 0</code> and <code>i</code> is a member of a selected interval, or 388: * <code>-1</code> if there are no selected intervals 389: * 390: * @see #getMaxSelectionIndex 391: */ 392: public int getMinSelectionIndex() 393: { 394: if (isSelectionEmpty()) 395: return -1; 396: 397: return sel.nextSetBit(0); 398: } 399: 400: /** 401: * Gets the largest index which is currently a member of a selection 402: * interval. 403: * 404: * @return The greatest integer <code>i</code> such that <code>i >= 405: * 0</code> and <code>i</code> is a member of a selected interval, or 406: * <code>-1</code> if there are no selected intervals 407: * 408: * @see #getMinSelectionIndex 409: */ 410: public int getMaxSelectionIndex() 411: { 412: if (isSelectionEmpty()) 413: return -1; 414: 415: int mx = -1; 416: for(int i=sel.nextSetBit(0); i >= 0; i=sel.nextSetBit(i+1)) 417: { 418: mx = i; 419: } 420: return mx; 421: } 422: 423: /** 424: * Determines whether a particular index is a member of a selection 425: * interval. 426: * 427: * @param a The index to search for 428: * 429: * @return <code>true</code> if the index is a member of a selection interval, 430: * otherwise <code>false</code> 431: */ 432: public boolean isSelectedIndex(int a) 433: { 434: // TODO: Probably throw an exception here? 435: if (a >= sel.length() || a < 0) 436: return false; 437: return sel.get(a); 438: } 439: 440: /** 441: * If the {@link #selectionMode} property is equal to 442: * <code>SINGLE_SELECTION</code> equivalent to calling 443: * <code>setSelectionInterval(index1, index2)</code>; 444: * If the {@link #selectionMode} property is equal to 445: * <code>SINGLE_INTERVAL_SELECTION</code> and the interval being 446: * added is not adjacent to an already selected interval, 447: * equivalent to <code>setSelectionInterval(index1, index2)</code>. 448: * Otherwise adds the range <code>[index0, index1]</code> 449: * to the selection interval set. 450: * 451: * @param index0 The beginning of the range of indices to select 452: * @param index1 The end of the range of indices to select 453: * 454: * @see #setSelectionInterval 455: * @see #removeSelectionInterval 456: */ 457: public void addSelectionInterval(int index0, int index1) 458: { 459: if (index0 == -1 || index1 == -1) 460: return; 461: 462: int lo = Math.min(index0, index1); 463: int hi = Math.max(index0, index1); 464: oldSel = sel.clone(); 465: 466: if (selectionMode == SINGLE_SELECTION) 467: setSelectionInterval(index0, index1); 468: 469: // COMPAT: Like Sun (but not like IBM), we allow calls to 470: // addSelectionInterval when selectionMode is 471: // SINGLE_SELECTION_INTERVAL iff the interval being added 472: // is adjacent to an already selected interval 473: if (selectionMode == SINGLE_INTERVAL_SELECTION) 474: if (!(isSelectedIndex(index0) || 475: isSelectedIndex(index1) || 476: isSelectedIndex(Math.max(lo-1,0)) || 477: isSelectedIndex(Math.min(hi+1,sel.size())))) 478: sel.clear(); 479: 480: // We have to update the anchorSelectionIndex and leadSelectionIndex 481: // variables 482: 483: // The next if statements breaks down to "if this selection is adjacent 484: // to the previous selection and going in the same direction" 485: if ((isSelectedIndex(leadSelectionIndex)) 486: && ((index0 - 1 == leadSelectionIndex 487: && (index1 >= index0) 488: && (leadSelectionIndex >= anchorSelectionIndex)) 489: || (index0 + 1 == leadSelectionIndex && (index1 <= index0) 490: && (leadSelectionIndex <= anchorSelectionIndex))) 491: && (anchorSelectionIndex != -1 || leadSelectionIndex != -1)) 492: { 493: // setting setLeadCalledFromAdd to true tells setLeadSelectionIndex 494: // not to update oldSel 495: setLeadCalledFromAdd = true; 496: setLeadSelectionIndex(index1); 497: setLeadCalledFromAdd = false; 498: } 499: else 500: { 501: leadSelectionIndex = index1; 502: anchorSelectionIndex = index0; 503: sel.set(lo, hi+1); 504: fireDifference(sel, (BitSet) oldSel); 505: } 506: } 507: 508: 509: /** 510: * Deselects all indices in the inclusive range 511: * <code>[index0,index1]</code>. 512: * 513: * @param index0 The beginning of the range of indices to deselect 514: * @param index1 The end of the range of indices to deselect 515: * 516: * @see #addSelectionInterval 517: * @see #setSelectionInterval 518: */ 519: public void removeSelectionInterval(int index0, 520: int index1) 521: { 522: if (index0 == -1 || index1 == -1) 523: return; 524: 525: oldSel = sel.clone(); 526: int lo = Math.min(index0, index1); 527: int hi = Math.max(index0, index1); 528: 529: // if selectionMode is SINGLE_INTERVAL_SELECTION and removing the interval 530: // (index0,index1) would leave two disjoint selection intervals, remove all 531: // selected indices from lo to the last selected index 532: if (getMinSelectionIndex() > 0 && getMinSelectionIndex() < lo && 533: selectionMode == SINGLE_INTERVAL_SELECTION) 534: hi = sel.size() - 1; 535: 536: sel.clear(lo, hi+1); 537: //update anchorSelectionIndex and leadSelectionIndex variables 538: //TODO: will probably need MouseDragged to test properly and know if this works 539: setAnchorSelectionIndex(index0); 540: leadSelectionIndex = index1; 541: 542: fireDifference(sel, (BitSet) oldSel); 543: } 544: 545: /** 546: * Removes all intervals in the selection set. 547: */ 548: public void clearSelection() 549: { 550: // Find the selected interval. 551: int from = sel.nextSetBit(0); 552: if (from < 0) 553: return; // Empty selection - nothing to do. 554: int to = from; 555: 556: int i; 557: 558: for (i = from; i>=0; i=sel.nextSetBit(i+1)) 559: to = i; 560: 561: sel.clear(); 562: fireValueChanged(from, to, valueIsAdjusting); 563: } 564: 565: /** 566: * Fire the change event, covering the difference between the two sets. 567: * 568: * @param current the current set 569: * @param x the previous set, the object will be reused. 570: */ 571: private void fireDifference(BitSet current, BitSet x) 572: { 573: x.xor(current); 574: int from = x.nextSetBit(0); 575: if (from < 0) 576: return; // No difference. 577: int to = from; 578: int i; 579: 580: for (i = from; i >= 0; i = x.nextSetBit(i+1)) 581: to = i; 582: 583: fireValueChanged(from, to, valueIsAdjusting); 584: } 585: 586: /** 587: * Clears the current selection and marks a given interval as "selected". If 588: * the current selection mode is <code>SINGLE_SELECTION</code> only the 589: * index <code>index2</code> is selected. 590: * 591: * @param index0 The low end of the new selection 592: * @param index1 The high end of the new selection 593: */ 594: public void setSelectionInterval(int index0, int index1) 595: { 596: if (index0 == -1 || index1 == -1) 597: return; 598: 599: BitSet oldSel = (BitSet) sel.clone(); 600: sel.clear(); 601: if (selectionMode == SINGLE_SELECTION) 602: index0 = index1; 603: 604: int lo = Math.min(index0, index1); 605: int hi = Math.max(index0, index1); 606: sel.set(lo, hi+1); 607: // update the anchorSelectionIndex and leadSelectionIndex variables 608: setAnchorSelectionIndex(index0); 609: leadSelectionIndex=index1; 610: 611: fireDifference(sel, oldSel); 612: } 613: 614: /** 615: * Inserts a number of indices either before or after a particular 616: * position in the set of indices. Renumbers all indices after the 617: * inserted range. The new indices in the inserted range are not 618: * selected. This method is typically called to synchronize the selection 619: * model with an inserted range of elements in a {@link ListModel}. 620: * 621: * @param index The position to insert indices at 622: * @param length The number of indices to insert 623: * @param before Indicates whether to insert the indices before the index 624: * or after it 625: */ 626: public void insertIndexInterval(int index, 627: int length, 628: boolean before) 629: { 630: if (!before) 631: { 632: index++; 633: length--; 634: } 635: BitSet tmp = sel.get(index, sel.size()); 636: sel.clear(index, sel.size()); 637: int n = tmp.size(); 638: for (int i = 0; i < n; ++i) 639: sel.set(index + length + i, tmp.get(i)); 640: } 641: 642: /** 643: * Removes a range from the set of indices. Renumbers all indices after 644: * the removed range. This method is typically called to synchronize the 645: * selection model with a deleted range of elements in a {@link 646: * ListModel}. 647: * 648: * @param index0 The first index to remove (inclusive) 649: * @param index1 The last index to remove (inclusive) 650: */ 651: public void removeIndexInterval(int index0, 652: int index1) 653: { 654: int lo = Math.min(index0, index1); 655: int hi = Math.max(index0, index1); 656: 657: BitSet tmp = sel.get(hi, sel.size()); 658: sel.clear(lo, sel.size()); 659: int n = tmp.size(); 660: for (int i = 0; i < n; ++i) 661: sel.set(lo + i, tmp.get(i)); 662: } 663: 664: /** 665: * Fires a {@link ListSelectionEvent} to all the listeners of type {@link 666: * ListSelectionListener} registered with this selection model to 667: * indicate that a series of adjustment has just ended. 668: * 669: * The values of {@link #getMinSelectionIndex} and 670: * {@link #getMaxSelectionIndex} are used in the {@link ListSelectionEvent} 671: * that gets fired. 672: * 673: * @param isAdjusting <code>true</code> if this is the final change 674: * in a series of adjustments, <code>false/code> otherwise 675: */ 676: protected void fireValueChanged(boolean isAdjusting) 677: { 678: fireValueChanged(getMinSelectionIndex(), getMaxSelectionIndex(), 679: isAdjusting); 680: } 681: 682: /** 683: * Fires a {@link ListSelectionEvent} to all the listeners of type {@link 684: * ListSelectionListener} registered with this selection model. 685: * 686: * @param firstIndex The low index of the changed range 687: * @param lastIndex The high index of the changed range 688: */ 689: protected void fireValueChanged(int firstIndex, int lastIndex) 690: { 691: fireValueChanged(firstIndex, lastIndex, getValueIsAdjusting()); 692: } 693: 694: /** 695: * Fires a {@link ListSelectionEvent} to all the listeners of type {@link 696: * ListSelectionListener} registered with this selection model. 697: * 698: * @param firstIndex The low index of the changed range 699: * @param lastIndex The high index of the changed range 700: * @param isAdjusting Whether this change is part of a seqence of adjustments 701: * made to the selection, such as during interactive scrolling 702: */ 703: protected void fireValueChanged(int firstIndex, int lastIndex, 704: boolean isAdjusting) 705: { 706: ListSelectionEvent evt = new ListSelectionEvent(this, firstIndex, 707: lastIndex, isAdjusting); 708: ListSelectionListener[] listeners = getListSelectionListeners(); 709: for (int i = 0; i < listeners.length; ++i) 710: listeners[i].valueChanged(evt); 711: } 712: 713: /** 714: * Adds a listener. 715: * 716: * @param listener The listener to add 717: * 718: * @see #removeListSelectionListener 719: * @see #getListSelectionListeners 720: */ 721: public void addListSelectionListener(ListSelectionListener listener) 722: { 723: listenerList.add(ListSelectionListener.class, listener); 724: } 725: 726: /** 727: * Removes a registered listener. 728: * 729: * @param listener The listener to remove 730: * 731: * @see #addListSelectionListener 732: * @see #getListSelectionListeners 733: */ 734: public void removeListSelectionListener(ListSelectionListener listener) 735: { 736: listenerList.remove(ListSelectionListener.class, listener); 737: } 738: 739: /** 740: * Returns an array of all registerers listeners. 741: * 742: * @param listenerType The type of listener to retrieve 743: * 744: * @return The array 745: * 746: * @see #getListSelectionListeners 747: * @since 1.3 748: */ 749: public EventListener[] getListeners(Class listenerType) 750: { 751: return listenerList.getListeners(listenerType); 752: } 753: 754: /** 755: * Returns an array of all registerd list selection listeners. 756: * 757: * @return the array 758: * 759: * @see #addListSelectionListener 760: * @see #removeListSelectionListener 761: * @see #getListeners 762: * @since 1.4 763: */ 764: public ListSelectionListener[] getListSelectionListeners() 765: { 766: return (ListSelectionListener[]) getListeners(ListSelectionListener.class); 767: } 768: 769: /** 770: * Returns a clone of this object. 771: * <code>listenerList</code> don't gets duplicated. 772: * 773: * @return the cloned object 774: * 775: * @throws CloneNotSupportedException if an error occurs 776: */ 777: public Object clone() 778: throws CloneNotSupportedException 779: { 780: DefaultListSelectionModel model = 781: (DefaultListSelectionModel) super.clone(); 782: model.sel = (BitSet) sel.clone(); 783: model.listenerList = new EventListenerList(); 784: return model; 785: } 786: }
GNU Classpath (0.91) |