1 11 package org.eclipse.jface.viewers; 12 13 import java.util.ArrayList ; 14 import java.util.List ; 15 16 import org.eclipse.core.runtime.ListenerList; 17 import org.eclipse.core.runtime.Assert; 18 import org.eclipse.jface.util.SafeRunnable; 19 import org.eclipse.swt.SWT; 20 import org.eclipse.swt.events.SelectionEvent; 21 import org.eclipse.swt.widgets.Composite; 22 import org.eclipse.swt.widgets.Control; 23 import org.eclipse.swt.widgets.Item; 24 import org.eclipse.swt.widgets.Tree; 25 import org.eclipse.swt.widgets.TreeItem; 26 import org.eclipse.swt.widgets.Widget; 27 28 38 public class CheckboxTreeViewer extends TreeViewer implements ICheckable { 39 40 43 private ListenerList checkStateListeners = new ListenerList(); 44 45 48 private TreeItem lastClickedItem = null; 49 50 58 public CheckboxTreeViewer(Composite parent) { 59 this(parent, SWT.BORDER); 60 } 61 62 71 public CheckboxTreeViewer(Composite parent, int style) { 72 this(new Tree(parent, SWT.CHECK | style)); 73 } 74 75 83 public CheckboxTreeViewer(Tree tree) { 84 super(tree); 85 } 86 87 90 public void addCheckStateListener(ICheckStateListener listener) { 91 checkStateListeners.add(listener); 92 } 93 94 102 private void applyState(CustomHashtable checked, CustomHashtable grayed, 103 Widget widget) { 104 Item[] items = getChildren(widget); 105 for (int i = 0; i < items.length; i++) { 106 Item item = items[i]; 107 if (item instanceof TreeItem) { 108 Object data = item.getData(); 109 if (data != null) { 110 TreeItem ti = (TreeItem) item; 111 ti.setChecked(checked.containsKey(data)); 112 ti.setGrayed(grayed.containsKey(data)); 113 } 114 } 115 applyState(checked, grayed, item); 116 } 117 } 118 119 127 protected void fireCheckStateChanged(final CheckStateChangedEvent event) { 128 Object [] array = checkStateListeners.getListeners(); 129 for (int i = 0; i < array.length; i++) { 130 final ICheckStateListener l = (ICheckStateListener) array[i]; 131 SafeRunnable.run(new SafeRunnable() { 132 public void run() { 133 l.checkStateChanged(event); 134 } 135 }); 136 } 137 138 } 139 140 148 private void gatherState(CustomHashtable checked, CustomHashtable grayed, 149 Widget widget) { 150 Item[] items = getChildren(widget); 151 for (int i = 0; i < items.length; i++) { 152 Item item = items[i]; 153 if (item instanceof TreeItem) { 154 Object data = item.getData(); 155 if (data != null) { 156 TreeItem ti = (TreeItem) item; 157 if (ti.getChecked()) { 158 checked.put(data, data); 159 } 160 if (ti.getGrayed()) { 161 grayed.put(data, data); 162 } 163 } 164 } 165 gatherState(checked, grayed, item); 166 } 167 } 168 169 172 public boolean getChecked(Object element) { 173 Widget widget = findItem(element); 174 if (widget instanceof TreeItem) { 175 return ((TreeItem) widget).getChecked(); 176 } 177 return false; 178 } 179 180 193 public Object [] getCheckedElements() { 194 ArrayList v = new ArrayList (); 195 Control tree = getControl(); 196 internalCollectChecked(v, tree); 197 return v.toArray(); 198 } 199 200 207 public boolean getGrayed(Object element) { 208 Widget widget = findItem(element); 209 if (widget instanceof TreeItem) { 210 return ((TreeItem) widget).getGrayed(); 211 } 212 return false; 213 } 214 215 228 public Object [] getGrayedElements() { 229 List result = new ArrayList (); 230 internalCollectGrayed(result, getControl()); 231 return result.toArray(); 232 } 233 234 237 protected void handleDoubleSelect(SelectionEvent event) { 238 239 if (lastClickedItem != null) { 240 TreeItem item = lastClickedItem; 241 Object data = item.getData(); 242 if (data != null) { 243 boolean state = item.getChecked(); 244 setChecked(data, !state); 245 fireCheckStateChanged(new CheckStateChangedEvent(this, data, 246 !state)); 247 } 248 lastClickedItem = null; 249 } else { 250 super.handleDoubleSelect(event); 251 } 252 } 253 254 257 protected void handleSelect(SelectionEvent event) { 258 259 lastClickedItem = null; 260 if (event.detail == SWT.CHECK) { 261 TreeItem item = (TreeItem) event.item; 262 lastClickedItem = item; 263 super.handleSelect(event); 264 265 Object data = item.getData(); 266 if (data != null) { 267 fireCheckStateChanged(new CheckStateChangedEvent(this, data, 268 item.getChecked())); 269 } 270 } else { 271 super.handleSelect(event); 272 } 273 } 274 275 282 private void internalCollectChecked(List result, Widget widget) { 283 Item[] items = getChildren(widget); 284 for (int i = 0; i < items.length; i++) { 285 Item item = items[i]; 286 if (item instanceof TreeItem && ((TreeItem) item).getChecked()) { 287 Object data = item.getData(); 288 if (data != null) { 289 result.add(data); 290 } 291 } 292 internalCollectChecked(result, item); 293 } 294 } 295 296 303 private void internalCollectGrayed(List result, Widget widget) { 304 Item[] items = getChildren(widget); 305 for (int i = 0; i < items.length; i++) { 306 Item item = items[i]; 307 if (item instanceof TreeItem && ((TreeItem) item).getGrayed()) { 308 Object data = item.getData(); 309 if (data != null) { 310 result.add(data); 311 } 312 } 313 internalCollectGrayed(result, item); 314 } 315 } 316 317 323 private void internalSetChecked(CustomHashtable checkedElements, 324 Widget widget) { 325 Item[] items = getChildren(widget); 326 for (int i = 0; i < items.length; i++) { 327 TreeItem item = (TreeItem) items[i]; 328 Object data = item.getData(); 329 if (data != null) { 330 boolean checked = checkedElements.containsKey(data); 331 if (checked != item.getChecked()) { 332 item.setChecked(checked); 333 } 334 } 335 internalSetChecked(checkedElements, item); 336 } 337 } 338 339 345 private void internalSetGrayed(CustomHashtable grayedElements, Widget widget) { 346 Item[] items = getChildren(widget); 347 for (int i = 0; i < items.length; i++) { 348 TreeItem item = (TreeItem) items[i]; 349 Object data = item.getData(); 350 if (data != null) { 351 boolean grayed = grayedElements.containsKey(data); 352 if (grayed != item.getGrayed()) { 353 item.setGrayed(grayed); 354 } 355 } 356 internalSetGrayed(grayedElements, item); 357 } 358 } 359 360 363 protected void preservingSelection(Runnable updateCode) { 364 365 int n = getItemCount(getControl()); 366 CustomHashtable checkedNodes = newHashtable(n * 2 + 1); 367 CustomHashtable grayedNodes = newHashtable(n * 2 + 1); 368 369 gatherState(checkedNodes, grayedNodes, getControl()); 370 371 super.preservingSelection(updateCode); 372 373 applyState(checkedNodes, grayedNodes, getControl()); 374 } 375 376 379 public void removeCheckStateListener(ICheckStateListener listener) { 380 checkStateListeners.remove(listener); 381 } 382 383 386 public boolean setChecked(Object element, boolean state) { 387 Assert.isNotNull(element); 388 Widget widget = internalExpand(element, false); 389 if (widget instanceof TreeItem) { 390 ((TreeItem) widget).setChecked(state); 391 return true; 392 } 393 return false; 394 } 395 396 403 private void setCheckedChildren(Item item, boolean state) { 404 createChildren(item); 405 Item[] items = getChildren(item); 406 if (items != null) { 407 for (int i = 0; i < items.length; i++) { 408 Item it = items[i]; 409 if (it.getData() != null && (it instanceof TreeItem)) { 410 TreeItem treeItem = (TreeItem) it; 411 treeItem.setChecked(state); 412 setCheckedChildren(treeItem, state); 413 } 414 } 415 } 416 } 417 418 431 public void setCheckedElements(Object [] elements) { 432 assertElementsNotNull(elements); 433 CustomHashtable checkedElements = newHashtable(elements.length * 2 + 1); 434 for (int i = 0; i < elements.length; ++i) { 435 Object element = elements[i]; 436 internalExpand(element, false); 438 checkedElements.put(element, element); 439 } 440 Control tree = getControl(); 441 tree.setRedraw(false); 442 internalSetChecked(checkedElements, tree); 443 tree.setRedraw(true); 444 } 445 446 455 public boolean setGrayed(Object element, boolean state) { 456 Assert.isNotNull(element); 457 Widget widget = internalExpand(element, false); 458 if (widget instanceof TreeItem) { 459 ((TreeItem) widget).setGrayed(state); 460 return true; 461 } 462 return false; 463 } 464 465 473 public boolean setGrayChecked(Object element, boolean state) { 474 Assert.isNotNull(element); 475 Widget widget = internalExpand(element, false); 476 if (widget instanceof TreeItem) { 477 TreeItem item = (TreeItem) widget; 478 item.setChecked(state); 479 item.setGrayed(state); 480 return true; 481 } 482 return false; 483 } 484 485 498 public void setGrayedElements(Object [] elements) { 499 assertElementsNotNull(elements); 500 CustomHashtable grayedElements = newHashtable(elements.length * 2 + 1); 501 for (int i = 0; i < elements.length; ++i) { 502 Object element = elements[i]; 503 internalExpand(element, false); 505 grayedElements.put(element, element); 506 } 507 Control tree = getControl(); 508 tree.setRedraw(false); 509 internalSetGrayed(grayedElements, tree); 510 tree.setRedraw(true); 511 } 512 513 524 public boolean setParentsGrayed(Object element, boolean state) { 525 Assert.isNotNull(element); 526 Widget widget = internalExpand(element, false); 527 if (widget instanceof TreeItem) { 528 TreeItem item = (TreeItem) widget; 529 item.setGrayed(state); 530 item = item.getParentItem(); 531 while (item != null) { 532 item.setGrayed(state); 533 item = item.getParentItem(); 534 } 535 return true; 536 } 537 return false; 538 } 539 540 554 public boolean setSubtreeChecked(Object element, boolean state) { 555 Widget widget = internalExpand(element, false); 556 if (widget instanceof TreeItem) { 557 TreeItem item = (TreeItem) widget; 558 item.setChecked(state); 559 setCheckedChildren(item, state); 560 return true; 561 } 562 return false; 563 } 564 565 574 public void setAllChecked(boolean state) { 575 setAllChecked(state, getTree().getItems()); 576 577 } 578 579 584 private void setAllChecked(boolean state, TreeItem[] items) { 585 for (int i = 0; i < items.length; i++) { 586 items[i].setChecked(state); 587 TreeItem[] children = items[i].getItems(); 588 setAllChecked(state, children); 589 } 590 } 591 } 592 | Popular Tags |