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