1 23 24 package org.netbeans.swing.tabcontrol; 25 26 import javax.swing.event.ChangeListener ; 27 import org.netbeans.swing.tabcontrol.event.ComplexListDataEvent; 28 import org.netbeans.swing.tabcontrol.event.ComplexListDataListener; 29 import org.netbeans.swing.tabcontrol.event.VeryComplexListDataEvent; 30 31 import javax.swing.*; 32 import javax.swing.event.ChangeEvent ; 33 import javax.swing.event.ListDataEvent ; 34 import java.util.*; 35 36 41 public class DefaultTabDataModel implements TabDataModel { 42 45 private transient ArrayList<ComplexListDataListener> listenerList; 46 47 private class L extends ArrayList<TabData> { 48 public void removeRange(int fromIndex, int toIndex) { 49 super.removeRange(fromIndex, toIndex); 50 } 51 } 52 53 private L list = new L(); 54 55 58 private transient ArrayList<ChangeListener > changeListenerList; 59 60 63 public DefaultTabDataModel() { 64 } 65 66 69 public DefaultTabDataModel(TabData[] data) { 70 list.addAll(Arrays.asList(data)); 71 } 72 73 public java.util.List <TabData> getTabs() { 74 return Collections.unmodifiableList(list); 75 } 76 77 public TabData getTab(int index) { 78 return (TabData) list.get(index); 79 } 80 81 public void setTabs(TabData[] data) { 82 83 TabData[] oldContents = new TabData[list.size()]; 84 oldContents = (TabData[]) list.toArray(oldContents); 85 86 if (Arrays.equals(data, oldContents)) { 88 return; 89 } 90 91 List newContents = Arrays.asList(data); 92 93 list.clear(); 94 list.addAll(Arrays.asList(data)); 95 96 VeryComplexListDataEvent vclde = new VeryComplexListDataEvent(this, 97 oldContents, 98 data); 99 fireIndicesChanged(vclde); 100 } 101 102 public void setIcon(int index, Icon i) { 103 boolean[] widthChanged = new boolean[]{false}; 104 105 boolean fireChange = _setIcon(index, i, widthChanged); 106 if (fireChange) { 107 ComplexListDataEvent clde = new ComplexListDataEvent(this, 108 ComplexListDataEvent.CONTENTS_CHANGED, 109 index, index, 110 widthChanged[0]); 111 fireContentsChanged(clde); 112 } 113 } 114 115 private boolean _setIcon(int index, Icon i, final boolean[] widthChanged) { 116 if (i == null) { 117 i = TabData.NO_ICON; 118 } 119 TabData data = getTab(index); 120 if (i != data.getIcon()) { 121 widthChanged[0] = data.getIcon().getIconWidth() 122 != i.getIconWidth(); 123 data.icon = i; 124 return true; 125 } else { 126 return false; 127 } 128 } 129 130 public void setText(int index, String txt) { 131 boolean[] widthChanged = new boolean[]{false}; 132 boolean fireChange = _setText(index, txt, widthChanged); 133 if (fireChange) { 134 ComplexListDataEvent clde = new ComplexListDataEvent(this, 135 ComplexListDataEvent.CONTENTS_CHANGED, 136 index, index, 137 widthChanged[0]); 138 fireContentsChanged(clde); 139 } 140 } 141 142 private int[] _setText(int[] indices, String [] txt, 143 final boolean[] widthChanged) { 144 widthChanged[0] = false; 145 boolean fireChange = false; 146 boolean[] changed = new boolean[indices.length]; 147 int changedCount = 0; 148 Arrays.fill(changed, false); 149 for (int i = 0; i < indices.length; i++) { 150 boolean[] currWidthChanged = new boolean[]{false}; 151 fireChange |= 152 _setText(indices[i], txt[i], currWidthChanged); 153 widthChanged[0] |= currWidthChanged[0]; 154 if (currWidthChanged[0]) 155 changedCount++; 156 changed[i] = currWidthChanged[0]; 157 } 158 int[] toFire; 159 if (widthChanged[0] || fireChange) { 160 if (changedCount == indices.length) { 161 toFire = indices; 162 } else { 163 toFire = new int[changedCount]; 164 int idx = 0; 165 for (int i = 0; i < indices.length; i++) { 166 if (changed[i]) { 167 toFire[idx] = indices[i]; 168 idx++; 169 } 170 } 171 } 172 return toFire; 173 } 174 return null; 175 } 176 177 private int[] _setIcon(int[] indices, Icon[] icons, 178 final boolean[] widthChanged) { 179 widthChanged[0] = false; 180 boolean fireChange = false; 181 boolean[] changed = new boolean[indices.length]; 182 int changedCount = 0; 183 Arrays.fill(changed, false); 184 boolean[] currWidthChanged = new boolean[]{false}; 185 boolean currChanged = false; 186 for (int i = 0; i < indices.length; i++) { 187 currChanged = 188 _setIcon(indices[i], icons[i], currWidthChanged); 189 fireChange |= currChanged; 190 widthChanged[0] |= currWidthChanged[0]; 191 if (currChanged) 192 changedCount++; 193 changed[i] = currChanged; 194 } 195 int[] toFire; 196 if (widthChanged[0] || fireChange) { 197 if (changedCount == indices.length) { 198 toFire = indices; 199 } else { 200 toFire = new int[changedCount]; 201 int idx = 0; 202 for (int i = 0; i < indices.length; i++) { 203 if (changed[i]) { 204 toFire[idx] = indices[i]; 205 idx++; 206 } 207 } 208 } 209 return toFire; 210 } 211 return null; 212 } 213 214 public void setIconsAndText(int[] indices, String [] txt, Icon[] icons) { 215 boolean[] iconWidthsChanged = new boolean[]{false}; 216 boolean[] txtWidthsChanged = new boolean[]{false}; 217 int[] iconsToFire = _setIcon(indices, icons, iconWidthsChanged); 218 int[] txtToFire = _setText(indices, txt, txtWidthsChanged); 219 boolean widthChanged = iconWidthsChanged[0] || txtWidthsChanged[0]; 220 boolean fire = widthChanged || iconsToFire != null 221 || txtToFire != null; 222 if (fire) { 223 if ((indices == iconsToFire) && (indices == txtToFire)) { 224 ComplexListDataEvent clde = new ComplexListDataEvent(this, 226 ComplexListDataEvent.CONTENTS_CHANGED, 227 indices, 228 widthChanged); 229 fireContentsChanged(clde); 230 } else { 231 int size = (iconsToFire != null ? iconsToFire.length : 0) 234 + (txtToFire != null ? txtToFire.length : 0); 235 Set<Integer > allIndicesToFire = new HashSet<Integer >(size); 236 Integer [] o; 237 if (iconsToFire != null) { 238 o = toObjectArray(iconsToFire); 239 allIndicesToFire.addAll(Arrays.asList(o)); 240 } 241 if (txtToFire != null) { 242 o = toObjectArray(txtToFire); 243 allIndicesToFire.addAll(Arrays.asList(o)); 244 } 245 Integer [] all = new Integer [allIndicesToFire.size()]; 246 all = (Integer []) allIndicesToFire.toArray(all); 247 int[] allPrimitive = toPrimitiveArray(all); 248 ComplexListDataEvent clde = new ComplexListDataEvent(this, 249 ComplexListDataEvent.CONTENTS_CHANGED, 250 allPrimitive, 251 widthChanged); 252 fireContentsChanged(clde); 253 } 254 } 255 } 256 257 public void setIcon(int[] indices, Icon[] icons) { 258 boolean[] widthChanged = new boolean[]{false}; 259 int[] toFire = _setIcon(indices, icons, widthChanged); 260 if (toFire != null) { 261 ComplexListDataEvent clde = new ComplexListDataEvent(this, 262 ComplexListDataEvent.CONTENTS_CHANGED, 263 toFire, 264 widthChanged[0]); 265 fireContentsChanged(clde); 266 } 267 } 268 269 public void setText(int[] indices, String [] txt) { 270 boolean[] widthChanged = new boolean[]{false}; 271 int[] toFire = _setText(indices, txt, widthChanged); 272 if (toFire != null) { 273 ComplexListDataEvent clde = new ComplexListDataEvent(this, 274 ComplexListDataEvent.CONTENTS_CHANGED, 275 toFire, 276 widthChanged[0]); 277 fireContentsChanged(clde); 278 } 279 } 280 281 private boolean _setText(int index, String txt, 282 final boolean[] widthChanged) { 283 TabData data = getTab(index); 284 if (txt != data.txt) { 285 widthChanged[0] = data.getText() != txt; 286 data.txt = txt; 287 return true; 288 } else { 289 return false; 290 } 291 } 292 293 public void setTab(int index, TabData data) { 294 if (!data.equals(getTab(index))) { 295 TabData olddata = getTab(index); 296 boolean txtChg = data.getText().equals(olddata.getText()); 297 boolean compChg = data.getUserObject() != olddata.getUserObject(); 298 list.set(index, data); 299 ComplexListDataEvent lde = new ComplexListDataEvent(this, 300 ListDataEvent.CONTENTS_CHANGED, 301 index, index, 302 txtChg, 303 compChg); 304 lde.setAffectedItems(new TabData[]{data}); 305 fireContentsChanged(lde); 306 } 307 } 308 309 public void addTab(int index, TabData data) { 310 list.add(index, data); 311 ComplexListDataEvent lde = new ComplexListDataEvent(this, 312 ComplexListDataEvent.INTERVAL_ADDED, 313 index, index, true); 314 lde.setAffectedItems(new TabData[]{data}); 315 fireIntervalAdded(lde); 316 } 317 318 public void addTabs(int start, TabData[] data) { 319 list.addAll(start, Arrays.asList(data)); 320 ComplexListDataEvent lde = new ComplexListDataEvent(this, ListDataEvent.INTERVAL_ADDED, start, start 321 + data.length 322 - 1, true); 323 lde.setAffectedItems(data); 324 fireIntervalAdded(lde); 325 } 326 327 public void removeTab(int index) { 328 TabData[] td = new TabData[]{(TabData) list.get(index)}; 329 list.remove(index); 330 ComplexListDataEvent lde = new ComplexListDataEvent(this, 331 ListDataEvent.INTERVAL_REMOVED, 332 index, index); 333 lde.setAffectedItems(td); 334 fireIntervalRemoved(lde); 335 } 336 337 341 public void removeTabs(int start, int end) { 342 java.util.List affected = list.subList(start, end); 343 if (start == end) { 344 list.remove(start); 345 } else { 346 list.removeRange(start, end + 1); 347 } 348 ComplexListDataEvent lde = new ComplexListDataEvent(this, 349 ListDataEvent.INTERVAL_REMOVED, 350 start, end); 351 lde.setAffectedItems((TabData[]) list.toArray(new TabData[0])); 352 fireIntervalRemoved(lde); 353 } 354 355 public void addTabs(int[] indices, TabData[] data) { 356 Map<Integer ,TabData> m = new HashMap<Integer ,TabData>(data.length); 357 for (int i = 0; i < data.length; i++) { 358 m.put(new Integer (indices[i]), data[i]); 359 } 360 Arrays.sort(indices); 361 for (int i = 0; i < indices.length; i++) { 362 Integer key = new Integer (indices[i]); 363 TabData currData = m.get(key); 364 list.add(indices[i], currData); 365 } 366 ComplexListDataEvent clde = new ComplexListDataEvent(this, 367 ComplexListDataEvent.ITEMS_ADDED, 368 indices, true); 369 clde.setAffectedItems(data); 370 fireIndicesAdded(clde); 371 } 372 373 public void removeTabs(int[] indices) { 374 Arrays.sort(indices); 375 TabData[] affected = new TabData[indices.length]; 376 for (int i = indices.length - 1; i >= 0; i--) { 377 affected[i] = (TabData) list.remove(indices[i]); 378 } 379 ComplexListDataEvent clde = new ComplexListDataEvent(this, 380 ComplexListDataEvent.ITEMS_REMOVED, 381 indices, true); 382 clde.setAffectedItems(affected); 383 fireIndicesRemoved(clde); 384 } 385 386 public int size() { 387 return list.size(); 388 } 389 390 public synchronized void addComplexListDataListener( 391 ComplexListDataListener listener) { 392 if (listenerList == null) { 393 listenerList = new ArrayList<ComplexListDataListener>(); 394 } 395 listenerList.add(listener); 396 } 397 398 public synchronized void removeComplexListDataListener( 399 ComplexListDataListener listener) { 400 listenerList.remove(listener); 401 } 402 403 private void fireIntervalAdded(ListDataEvent event) { 404 if (listenerList == null) { 405 return; 406 } 407 int max = listenerList.size(); 408 for (int i = 0; i < max; i++) { 409 ComplexListDataListener l = (ComplexListDataListener) listenerList.get( 410 i); 411 l.intervalAdded(event); 412 } 413 fireChange(); 414 } 415 416 private void fireIntervalRemoved(ListDataEvent event) { 417 if (listenerList == null) 418 return; 419 int max = listenerList.size(); 420 for (int i = 0; i < max; i++) { 421 ComplexListDataListener l = (ComplexListDataListener) listenerList.get( 422 i); 423 l.intervalRemoved(event); 424 } 425 fireChange(); 426 } 427 428 private void fireContentsChanged(ListDataEvent event) { 429 if (listenerList == null) 430 return; 431 int max = listenerList.size(); 432 for (int i = 0; i < max; i++) { 433 ComplexListDataListener l = (ComplexListDataListener) listenerList.get( 434 i); 435 l.contentsChanged(event); 436 } 437 fireChange(); 438 } 439 440 private void fireIndicesAdded(ComplexListDataEvent event) { 441 if (listenerList == null) 442 return; 443 int max = listenerList.size(); 444 for (int i = 0; i < max; i++) { 445 ComplexListDataListener l = (ComplexListDataListener) listenerList.get( 446 i); 447 l.indicesAdded(event); 448 } 449 fireChange(); 450 } 451 452 private void fireIndicesRemoved(ComplexListDataEvent event) { 453 if (listenerList == null) 454 return; 455 int max = listenerList.size(); 456 for (int i = 0; i < max; i++) { 457 ComplexListDataListener l = (ComplexListDataListener) listenerList.get( 458 i); 459 l.indicesRemoved(event); 460 } 461 fireChange(); 462 } 463 464 private void fireIndicesChanged(ComplexListDataEvent event) { 465 if (listenerList == null) 466 return; 467 int max = listenerList.size(); 468 for (int i = 0; i < max; i++) { 469 ComplexListDataListener l = (ComplexListDataListener) listenerList.get( 470 i); 471 l.indicesChanged(event); 472 } 473 fireChange(); 474 } 475 476 public String toString() { 477 StringBuffer out = new StringBuffer (getClass().getName()); 478 out.append(" size ="); 479 int max = size(); 480 out.append(max); 481 out.append(" - "); 482 for (int i = 0; i < max; i++) { 483 TabData td = getTab(i); 484 out.append(td.toString()); 485 if (i != max - 1) { 486 out.append(','); 487 } 488 } 489 return out.toString(); 490 } 491 492 496 497 502 public synchronized void addChangeListener(ChangeListener listener) { 503 if (changeListenerList == null) { 504 changeListenerList = new ArrayList<ChangeListener >(); 505 } 506 changeListenerList.add(listener); 507 } 508 509 514 public synchronized void removeChangeListener( 515 javax.swing.event.ChangeListener listener) { 516 if (changeListenerList != null) { 517 changeListenerList.remove(listener); 518 } 519 } 520 521 ChangeEvent event = null; 522 523 private void fireChange() { 524 java.util.ArrayList list; 525 synchronized (this) { 526 if (changeListenerList == null) 527 return; 528 list = (java.util.ArrayList ) changeListenerList.clone(); 529 } 530 if (event == null) { 531 event = new ChangeEvent (this); 532 } 533 for (int i = 0; i < list.size(); i++) { 534 ((javax.swing.event.ChangeListener ) list.get(i)).stateChanged( 535 event); 536 } 537 } 538 539 public int indexOf(TabData td) { 540 return list.indexOf(td); 541 } 542 543 private Integer [] toObjectArray(int[] o) { 544 Integer [] result = new Integer [o.length]; 545 for (int i = 0; i < o.length; i++) { 546 result[i] = new Integer (o[i]); 547 } 548 return result; 549 } 550 551 private int[] toPrimitiveArray(Integer [] o) { 552 int[] result = new int[o.length]; 553 for (int i = 0; i < o.length; i++) { 554 result[i] = o[i].intValue(); 555 } 556 return result; 557 } 558 559 } 560 | Popular Tags |