1 7 package javax.swing.text.html; 8 9 import javax.swing.*; 10 import javax.swing.event.*; 11 import java.util.EventListener ; 12 import java.util.BitSet ; 13 import java.io.Serializable ; 14 15 16 29 30 class OptionListModel extends DefaultListModel implements ListSelectionModel, Serializable { 31 32 33 private static final int MIN = -1; 34 private static final int MAX = Integer.MAX_VALUE; 35 private int selectionMode = SINGLE_SELECTION; 36 private int minIndex = MAX; 37 private int maxIndex = MIN; 38 private int anchorIndex = -1; 39 private int leadIndex = -1; 40 private int firstChangedIndex = MAX; 41 private int lastChangedIndex = MIN; 42 private boolean isAdjusting = false; 43 private BitSet value = new BitSet (32); 44 private BitSet initialValue = new BitSet (32); 45 protected EventListenerList listenerList = new EventListenerList(); 46 47 protected boolean leadAnchorNotificationEnabled = true; 48 49 public int getMinSelectionIndex() { return isSelectionEmpty() ? -1 : minIndex; } 50 51 public int getMaxSelectionIndex() { return maxIndex; } 52 53 public boolean getValueIsAdjusting() { return isAdjusting; } 54 55 public int getSelectionMode() { return selectionMode; } 56 57 public void setSelectionMode(int selectionMode) { 58 switch (selectionMode) { 59 case SINGLE_SELECTION: 60 case SINGLE_INTERVAL_SELECTION: 61 case MULTIPLE_INTERVAL_SELECTION: 62 this.selectionMode = selectionMode; 63 break; 64 default: 65 throw new IllegalArgumentException ("invalid selectionMode"); 66 } 67 } 68 69 public boolean isSelectedIndex(int index) { 70 return ((index < minIndex) || (index > maxIndex)) ? false : value.get(index); 71 } 72 73 public boolean isSelectionEmpty() { 74 return (minIndex > maxIndex); 75 } 76 77 public void addListSelectionListener(ListSelectionListener l) { 78 listenerList.add(ListSelectionListener.class, l); 79 } 80 81 public void removeListSelectionListener(ListSelectionListener l) { 82 listenerList.remove(ListSelectionListener.class, l); 83 } 84 85 93 public ListSelectionListener[] getListSelectionListeners() { 94 return (ListSelectionListener[])listenerList.getListeners( 95 ListSelectionListener.class); 96 } 97 98 102 protected void fireValueChanged(boolean isAdjusting) { 103 fireValueChanged(getMinSelectionIndex(), getMaxSelectionIndex(), isAdjusting); 104 } 105 106 107 111 protected void fireValueChanged(int firstIndex, int lastIndex) { 112 fireValueChanged(firstIndex, lastIndex, getValueIsAdjusting()); 113 } 114 115 121 protected void fireValueChanged(int firstIndex, int lastIndex, boolean isAdjusting) 122 { 123 Object [] listeners = listenerList.getListenerList(); 124 ListSelectionEvent e = null; 125 126 for (int i = listeners.length - 2; i >= 0; i -= 2) { 127 if (listeners[i] == ListSelectionListener.class) { 128 if (e == null) { 129 e = new ListSelectionEvent(this, firstIndex, lastIndex, isAdjusting); 130 } 131 ((ListSelectionListener)listeners[i+1]).valueChanged(e); 132 } 133 } 134 } 135 136 private void fireValueChanged() { 137 if (lastChangedIndex == MIN) { 138 return; 139 } 140 144 int oldFirstChangedIndex = firstChangedIndex; 145 int oldLastChangedIndex = lastChangedIndex; 146 firstChangedIndex = MAX; 147 lastChangedIndex = MIN; 148 fireValueChanged(oldFirstChangedIndex, oldLastChangedIndex); 149 } 150 151 152 private void markAsDirty(int r) { 154 firstChangedIndex = Math.min(firstChangedIndex, r); 155 lastChangedIndex = Math.max(lastChangedIndex, r); 156 } 157 158 private void set(int r) { 160 if (value.get(r)) { 161 return; 162 } 163 value.set(r); 164 Option option = (Option )get(r); 165 option.setSelection(true); 166 markAsDirty(r); 167 168 minIndex = Math.min(minIndex, r); 170 maxIndex = Math.max(maxIndex, r); 171 } 172 173 private void clear(int r) { 175 if (!value.get(r)) { 176 return; 177 } 178 value.clear(r); 179 Option option = (Option )get(r); 180 option.setSelection(false); 181 markAsDirty(r); 182 183 190 if (r == minIndex) { 191 for(minIndex = minIndex + 1; minIndex <= maxIndex; minIndex++) { 192 if (value.get(minIndex)) { 193 break; 194 } 195 } 196 } 197 203 if (r == maxIndex) { 204 for(maxIndex = maxIndex - 1; minIndex <= maxIndex; maxIndex--) { 205 if (value.get(maxIndex)) { 206 break; 207 } 208 } 209 } 210 225 if (isSelectionEmpty()) { 226 minIndex = MAX; 227 maxIndex = MIN; 228 } 229 } 230 231 235 public void setLeadAnchorNotificationEnabled(boolean flag) { 236 leadAnchorNotificationEnabled = flag; 237 } 238 239 251 public boolean isLeadAnchorNotificationEnabled() { 252 return leadAnchorNotificationEnabled; 253 } 254 255 private void updateLeadAnchorIndices(int anchorIndex, int leadIndex) { 256 if (leadAnchorNotificationEnabled) { 257 if (this.anchorIndex != anchorIndex) { 258 if (this.anchorIndex != -1) { markAsDirty(this.anchorIndex); 260 } 261 markAsDirty(anchorIndex); 262 } 263 264 if (this.leadIndex != leadIndex) { 265 if (this.leadIndex != -1) { markAsDirty(this.leadIndex); 267 } 268 markAsDirty(leadIndex); 269 } 270 } 271 this.anchorIndex = anchorIndex; 272 this.leadIndex = leadIndex; 273 } 274 275 private boolean contains(int a, int b, int i) { 276 return (i >= a) && (i <= b); 277 } 278 279 private void changeSelection(int clearMin, int clearMax, 280 int setMin, int setMax, boolean clearFirst) { 281 for(int i = Math.min(setMin, clearMin); i <= Math.max(setMax, clearMax); i++) { 282 283 boolean shouldClear = contains(clearMin, clearMax, i); 284 boolean shouldSet = contains(setMin, setMax, i); 285 286 if (shouldSet && shouldClear) { 287 if (clearFirst) { 288 shouldClear = false; 289 } 290 else { 291 shouldSet = false; 292 } 293 } 294 295 if (shouldSet) { 296 set(i); 297 } 298 if (shouldClear) { 299 clear(i); 300 } 301 } 302 fireValueChanged(); 303 } 304 305 310 private void changeSelection(int clearMin, int clearMax, int setMin, int setMax) { 311 changeSelection(clearMin, clearMax, setMin, setMax, true); 312 } 313 314 public void clearSelection() { 315 removeSelectionInterval(minIndex, maxIndex); 316 } 317 318 public void setSelectionInterval(int index0, int index1) { 319 if (index0 == -1 || index1 == -1) { 320 return; 321 } 322 323 if (getSelectionMode() == SINGLE_SELECTION) { 324 index0 = index1; 325 } 326 327 updateLeadAnchorIndices(index0, index1); 328 329 int clearMin = minIndex; 330 int clearMax = maxIndex; 331 int setMin = Math.min(index0, index1); 332 int setMax = Math.max(index0, index1); 333 changeSelection(clearMin, clearMax, setMin, setMax); 334 } 335 336 public void addSelectionInterval(int index0, int index1) 337 { 338 if (index0 == -1 || index1 == -1) { 339 return; 340 } 341 342 if (getSelectionMode() != MULTIPLE_INTERVAL_SELECTION) { 343 setSelectionInterval(index0, index1); 344 return; 345 } 346 347 updateLeadAnchorIndices(index0, index1); 348 349 int clearMin = MAX; 350 int clearMax = MIN; 351 int setMin = Math.min(index0, index1); 352 int setMax = Math.max(index0, index1); 353 changeSelection(clearMin, clearMax, setMin, setMax); 354 } 355 356 357 public void removeSelectionInterval(int index0, int index1) 358 { 359 if (index0 == -1 || index1 == -1) { 360 return; 361 } 362 363 updateLeadAnchorIndices(index0, index1); 364 365 int clearMin = Math.min(index0, index1); 366 int clearMax = Math.max(index0, index1); 367 int setMin = MAX; 368 int setMax = MIN; 369 changeSelection(clearMin, clearMax, setMin, setMax); 370 } 371 372 private void setState(int index, boolean state) { 373 if (state) { 374 set(index); 375 } 376 else { 377 clear(index); 378 } 379 } 380 381 388 public void insertIndexInterval(int index, int length, boolean before) 389 { 390 393 int insMinIndex = (before) ? index : index + 1; 394 int insMaxIndex = (insMinIndex + length) - 1; 395 396 400 for(int i = maxIndex; i >= insMinIndex; i--) { 401 setState(i + length, value.get(i)); 402 } 403 404 406 boolean setInsertedValues = value.get(index); 407 for(int i = insMinIndex; i <= insMaxIndex; i++) { 408 setState(i, setInsertedValues); 409 } 410 } 411 412 413 419 public void removeIndexInterval(int index0, int index1) 420 { 421 int rmMinIndex = Math.min(index0, index1); 422 int rmMaxIndex = Math.max(index0, index1); 423 int gapLength = (rmMaxIndex - rmMinIndex) + 1; 424 425 428 for(int i = rmMinIndex; i <= maxIndex; i++) { 429 setState(i, value.get(i + gapLength)); 430 } 431 } 432 433 434 public void setValueIsAdjusting(boolean isAdjusting) { 435 if (isAdjusting != this.isAdjusting) { 436 this.isAdjusting = isAdjusting; 437 this.fireValueChanged(isAdjusting); 438 } 439 } 440 441 442 public String toString() { 443 String s = ((getValueIsAdjusting()) ? "~" : "=") + value.toString(); 444 return getClass().getName() + " " + Integer.toString(hashCode()) + " " + s; 445 } 446 447 456 public Object clone() throws CloneNotSupportedException { 457 OptionListModel clone = (OptionListModel )super.clone(); 458 clone.value = (BitSet )value.clone(); 459 clone.listenerList = new EventListenerList(); 460 return clone; 461 } 462 463 public int getAnchorSelectionIndex() { 464 return anchorIndex; 465 } 466 467 public int getLeadSelectionIndex() { 468 return leadIndex; 469 } 470 471 477 public void setAnchorSelectionIndex(int anchorIndex) { 478 this.anchorIndex = anchorIndex; 479 } 480 481 508 public void setLeadSelectionIndex(int leadIndex) { 509 int anchorIndex = this.anchorIndex; 510 if (getSelectionMode() == SINGLE_SELECTION) { 511 anchorIndex = leadIndex; 512 } 513 514 int oldMin = Math.min(this.anchorIndex, this.leadIndex);; 515 int oldMax = Math.max(this.anchorIndex, this.leadIndex);; 516 int newMin = Math.min(anchorIndex, leadIndex); 517 int newMax = Math.max(anchorIndex, leadIndex); 518 if (value.get(this.anchorIndex)) { 519 changeSelection(oldMin, oldMax, newMin, newMax); 520 } 521 else { 522 changeSelection(newMin, newMax, oldMin, oldMax, false); 523 } 524 this.anchorIndex = anchorIndex; 525 this.leadIndex = leadIndex; 526 } 527 528 529 536 public void setInitialSelection(int i) { 537 if (initialValue.get(i)) { 538 return; 539 } 540 if (selectionMode == SINGLE_SELECTION) { 541 initialValue.and(new BitSet ()); 543 } 544 initialValue.set(i); 545 } 546 547 551 public BitSet getInitialSelection() { 552 return initialValue; 553 } 554 } 555 556 557 | Popular Tags |