57 * 58 * <pre><code> 59 * // create the tree model 60 * CheckBoxTreeItem<String> jonathanGiles = new CheckBoxTreeItem<String>("Jonathan"); 61 * CheckBoxTreeItem<String> juliaGiles = new CheckBoxTreeItem<String>("Julia"); 62 * CheckBoxTreeItem<String> mattGiles = new CheckBoxTreeItem<String>("Matt"); 63 * CheckBoxTreeItem<String> sueGiles = new CheckBoxTreeItem<String>("Sue"); 64 * CheckBoxTreeItem<String> ianGiles = new CheckBoxTreeItem<String>("Ian"); 65 * 66 * CheckBoxTreeItem<String> gilesFamily = new CheckBoxTreeItem<String>("Giles Family"); 67 * gilesFamily.setExpanded(true); 68 * gilesFamily.getChildren().addAll(jonathanGiles, juliaGiles, mattGiles, sueGiles, ianGiles); 69 * 70 * // create the treeView 71 * final TreeView<String> treeView = new TreeView<String>(); 72 * treeView.setRoot(gilesFamily); 73 * 74 * // set the cell factory 75 * treeView.setCellFactory(CheckBoxTreeCell.<String>forTreeView());</code></pre> 76 * 77 * @see CheckBoxTreeCell 78 * @see TreeItem 79 * @see CheckBox 80 * @since JavaFX 2.2 81 */ 82 // TODO the TreeModificationEvent doesn't actually bubble in the same way as 83 // TreeItem - it just looks that way as the 'bubbling' is done via changing the 84 // state of all parent items. 85 public class CheckBoxTreeItem<T> extends TreeItem<T> { 86 87 /** 88 * An EventType used when the CheckBoxTreeItem selection / indeterminate 89 * state changes. To use this, it is recommended that you use code along the 90 * lines of the following: 91 * 92 *<pre> 93 * {@code 94 * child1.addEventHandler(CheckBoxTreeItem.<String>checkBoxSelectionChangedEvent(), new EventHandler<TreeModificationEvent<String>>() { 95 * public void handle(TreeModificationEvent<String> event) { 96 * ... 97 * } 98 * });} 99 * </pre> 100 * 101 * @param <T> The type of the value contained within the TreeItem. 102 */ 103 @SuppressWarnings("unchecked") 104 public static <T> EventType<TreeModificationEvent<T>> checkBoxSelectionChangedEvent() { 105 return (EventType<TreeModificationEvent<T>>) CHECK_BOX_SELECTION_CHANGED_EVENT; 106 } 107 private static final EventType<? extends Event> CHECK_BOX_SELECTION_CHANGED_EVENT 108 = new EventType<Event>(TreeModificationEvent.ANY, "checkBoxSelectionChangedEvent"); 109 110 /*************************************************************************** 111 * * 112 * Constructors * 113 * * 114 **************************************************************************/ 115 116 /** 117 * Creates an empty CheckBoxTreeItem. 118 */ 119 public CheckBoxTreeItem() { 120 this(null); 121 } 186 * * 187 **************************************************************************/ 188 private final ChangeListener<Boolean> stateChangeListener = (ov, oldVal, newVal) -> { 189 updateState(); 190 }; 191 192 193 /*************************************************************************** 194 * * 195 * Properties * 196 * * 197 **************************************************************************/ 198 199 // --- Selected 200 private final BooleanProperty selected = new SimpleBooleanProperty(this, "selected", false) { 201 @Override protected void invalidated() { 202 super.invalidated(); 203 fireEvent(CheckBoxTreeItem.this, true); 204 } 205 }; 206 /** Sets the selected state of this CheckBoxTreeItem. */ 207 public final void setSelected(boolean value) { selectedProperty().setValue(value); } 208 /** Returns the selected state of this CheckBoxTreeItem. */ 209 public final boolean isSelected() { return selected.getValue(); } 210 /** A {@link BooleanProperty} used to represent the selected state of this CheckBoxTreeItem. */ 211 public final BooleanProperty selectedProperty() { return selected; } 212 213 214 // --- Indeterminate 215 private final BooleanProperty indeterminate = new SimpleBooleanProperty(this, "indeterminate", false) { 216 @Override protected void invalidated() { 217 super.invalidated(); 218 fireEvent(CheckBoxTreeItem.this, false); 219 } 220 }; 221 /** Sets the indeterminate state of this CheckBoxTreeItem. */ 222 public final void setIndeterminate(boolean value) { indeterminateProperty().setValue(value); } 223 /** Returns the indeterminate state of this CheckBoxTreeItem. */ 224 public final boolean isIndeterminate() { return indeterminate.getValue(); } 225 /** A {@link BooleanProperty} used to represent the indeterminate state of this CheckBoxTreeItem. */ 226 public final BooleanProperty indeterminateProperty() { return indeterminate; } 227 228 229 // --- Independent 230 /** 231 * A {@link BooleanProperty} used to represent the independent state of this CheckBoxTreeItem. 232 * The independent state is used to represent whether changes to a single 233 * CheckBoxTreeItem should influence the state of its parent and children. 234 * 235 * <p>By default, the independent property is false, which means that when 236 * a CheckBoxTreeItem has state changes to the selected or indeterminate 237 * properties, the state of related CheckBoxTreeItems will possibly be changed. 238 * If the independent property is set to true, the state of related CheckBoxTreeItems 239 * will <b>never</b> change. 240 */ 241 public final BooleanProperty independentProperty() { return independent; } 242 private final BooleanProperty independent = new SimpleBooleanProperty(this, "independent", false); 243 public final void setIndependent(boolean value) { independentProperty().setValue(value); } 244 public final boolean isIndependent() { return independent.getValue(); } 245 246 247 248 /*************************************************************************** 249 * * 250 * Private Implementation * 251 * * 252 **************************************************************************/ 253 254 private static boolean updateLock = false; 255 256 private void updateState() { 257 if (isIndependent()) return; 258 259 boolean firstLock = ! updateLock; 323 * @param <T> The type of the value contained within the 324 * {@link CheckBoxTreeItem#valueProperty() value} property. 325 * @since JavaFX 2.2 326 */ 327 public static class TreeModificationEvent<T> extends Event { 328 private static final long serialVersionUID = -8445355590698862999L; 329 330 private transient final CheckBoxTreeItem<T> treeItem; 331 private final boolean selectionChanged; 332 333 /** 334 * Common supertype for all tree modification event types. 335 */ 336 public static final EventType<Event> ANY = 337 new EventType<Event> (Event.ANY, "TREE_MODIFICATION"); 338 339 /** 340 * Creates a default TreeModificationEvent instance to represent the 341 * change in selection/indeterminate states for the given CheckBoxTreeItem 342 * instance. 343 */ 344 public TreeModificationEvent(EventType<? extends Event> eventType, CheckBoxTreeItem<T> treeItem, boolean selectionChanged) { 345 super(eventType); 346 this.treeItem = treeItem; 347 this.selectionChanged = selectionChanged; 348 } 349 350 /** 351 * Returns the CheckBoxTreeItem that this event occurred upon. 352 * @return The CheckBoxTreeItem that this event occurred upon. 353 */ 354 public CheckBoxTreeItem<T> getTreeItem() { 355 return treeItem; 356 } 357 358 /** 359 * Indicates the the reason for this event is that the selection on the 360 * CheckBoxTreeItem changed (as opposed to it becoming indeterminate). 361 */ 362 public boolean wasSelectionChanged() { 363 return selectionChanged; 364 } 365 366 /** 367 * Indicates the the reason for this event is that the indeterminate 368 * state on the CheckBoxTreeItem changed (as opposed to it becoming 369 * selected or unselected). 370 */ 371 public boolean wasIndeterminateChanged() { 372 return ! selectionChanged; 373 } 374 } 375 } | 57 * 58 * <pre><code> 59 * // create the tree model 60 * CheckBoxTreeItem<String> jonathanGiles = new CheckBoxTreeItem<String>("Jonathan"); 61 * CheckBoxTreeItem<String> juliaGiles = new CheckBoxTreeItem<String>("Julia"); 62 * CheckBoxTreeItem<String> mattGiles = new CheckBoxTreeItem<String>("Matt"); 63 * CheckBoxTreeItem<String> sueGiles = new CheckBoxTreeItem<String>("Sue"); 64 * CheckBoxTreeItem<String> ianGiles = new CheckBoxTreeItem<String>("Ian"); 65 * 66 * CheckBoxTreeItem<String> gilesFamily = new CheckBoxTreeItem<String>("Giles Family"); 67 * gilesFamily.setExpanded(true); 68 * gilesFamily.getChildren().addAll(jonathanGiles, juliaGiles, mattGiles, sueGiles, ianGiles); 69 * 70 * // create the treeView 71 * final TreeView<String> treeView = new TreeView<String>(); 72 * treeView.setRoot(gilesFamily); 73 * 74 * // set the cell factory 75 * treeView.setCellFactory(CheckBoxTreeCell.<String>forTreeView());</code></pre> 76 * 77 * @param <T> The type of the value contained within the TreeItem 78 * @see CheckBoxTreeCell 79 * @see TreeItem 80 * @see CheckBox 81 * @since JavaFX 2.2 82 */ 83 // TODO the TreeModificationEvent doesn't actually bubble in the same way as 84 // TreeItem - it just looks that way as the 'bubbling' is done via changing the 85 // state of all parent items. 86 public class CheckBoxTreeItem<T> extends TreeItem<T> { 87 88 /** 89 * An EventType used when the CheckBoxTreeItem selection / indeterminate 90 * state changes. To use this, it is recommended that you use code along the 91 * lines of the following: 92 * 93 *<pre> 94 * {@code 95 * child1.addEventHandler(CheckBoxTreeItem.<String>checkBoxSelectionChangedEvent(), new EventHandler<TreeModificationEvent<String>>() { 96 * public void handle(TreeModificationEvent<String> event) { 97 * ... 98 * } 99 * });} 100 * </pre> 101 * 102 * @param <T> The type of the value contained within the TreeItem. 103 * @return the EventType used when the CheckBoxTreeItem selection / indeterminate 104 * state changes 105 */ 106 @SuppressWarnings("unchecked") 107 public static <T> EventType<TreeModificationEvent<T>> checkBoxSelectionChangedEvent() { 108 return (EventType<TreeModificationEvent<T>>) CHECK_BOX_SELECTION_CHANGED_EVENT; 109 } 110 private static final EventType<? extends Event> CHECK_BOX_SELECTION_CHANGED_EVENT 111 = new EventType<Event>(TreeModificationEvent.ANY, "checkBoxSelectionChangedEvent"); 112 113 /*************************************************************************** 114 * * 115 * Constructors * 116 * * 117 **************************************************************************/ 118 119 /** 120 * Creates an empty CheckBoxTreeItem. 121 */ 122 public CheckBoxTreeItem() { 123 this(null); 124 } 189 * * 190 **************************************************************************/ 191 private final ChangeListener<Boolean> stateChangeListener = (ov, oldVal, newVal) -> { 192 updateState(); 193 }; 194 195 196 /*************************************************************************** 197 * * 198 * Properties * 199 * * 200 **************************************************************************/ 201 202 // --- Selected 203 private final BooleanProperty selected = new SimpleBooleanProperty(this, "selected", false) { 204 @Override protected void invalidated() { 205 super.invalidated(); 206 fireEvent(CheckBoxTreeItem.this, true); 207 } 208 }; 209 210 /** 211 * Sets the selected state of this CheckBoxTreeItem. 212 * @param value the selected state of this CheckBoxTreeItem 213 */ 214 public final void setSelected(boolean value) { selectedProperty().setValue(value); } 215 216 /** 217 * Returns the selected state of this CheckBoxTreeItem. 218 * @return true if CheckBoxTreeItem is selected 219 */ 220 public final boolean isSelected() { return selected.getValue(); } 221 222 /** 223 * A {@link BooleanProperty} used to represent the selected state of this CheckBoxTreeItem. 224 * @return the selected state property of this CheckBoxTreeItem 225 */ 226 public final BooleanProperty selectedProperty() { return selected; } 227 228 229 // --- Indeterminate 230 private final BooleanProperty indeterminate = new SimpleBooleanProperty(this, "indeterminate", false) { 231 @Override protected void invalidated() { 232 super.invalidated(); 233 fireEvent(CheckBoxTreeItem.this, false); 234 } 235 }; 236 237 /** 238 * Sets the indeterminate state of this CheckBoxTreeItem. 239 * @param value the indeterminate state of this CheckBoxTreeItem 240 */ 241 public final void setIndeterminate(boolean value) { indeterminateProperty().setValue(value); } 242 243 /** 244 * Returns the indeterminate state of this CheckBoxTreeItem. 245 * @return true if CheckBoxTreeItem is indeterminate state 246 */ 247 public final boolean isIndeterminate() { return indeterminate.getValue(); } 248 249 /** 250 * A {@link BooleanProperty} used to represent the indeterminate state of this CheckBoxTreeItem. 251 * @return the indeterminate state property of this CheckBoxTreeItem 252 */ 253 public final BooleanProperty indeterminateProperty() { return indeterminate; } 254 255 256 // --- Independent 257 /** 258 * A {@link BooleanProperty} used to represent the independent state of this CheckBoxTreeItem. 259 * The independent state is used to represent whether changes to a single 260 * CheckBoxTreeItem should influence the state of its parent and children. 261 * 262 * <p>By default, the independent property is false, which means that when 263 * a CheckBoxTreeItem has state changes to the selected or indeterminate 264 * properties, the state of related CheckBoxTreeItems will possibly be changed. 265 * If the independent property is set to true, the state of related CheckBoxTreeItems 266 * will <b>never</b> change. 267 * @return the independent state property of this CheckBoxTreeItem 268 */ 269 public final BooleanProperty independentProperty() { return independent; } 270 private final BooleanProperty independent = new SimpleBooleanProperty(this, "independent", false); 271 public final void setIndependent(boolean value) { independentProperty().setValue(value); } 272 public final boolean isIndependent() { return independent.getValue(); } 273 274 275 276 /*************************************************************************** 277 * * 278 * Private Implementation * 279 * * 280 **************************************************************************/ 281 282 private static boolean updateLock = false; 283 284 private void updateState() { 285 if (isIndependent()) return; 286 287 boolean firstLock = ! updateLock; 351 * @param <T> The type of the value contained within the 352 * {@link CheckBoxTreeItem#valueProperty() value} property. 353 * @since JavaFX 2.2 354 */ 355 public static class TreeModificationEvent<T> extends Event { 356 private static final long serialVersionUID = -8445355590698862999L; 357 358 private transient final CheckBoxTreeItem<T> treeItem; 359 private final boolean selectionChanged; 360 361 /** 362 * Common supertype for all tree modification event types. 363 */ 364 public static final EventType<Event> ANY = 365 new EventType<Event> (Event.ANY, "TREE_MODIFICATION"); 366 367 /** 368 * Creates a default TreeModificationEvent instance to represent the 369 * change in selection/indeterminate states for the given CheckBoxTreeItem 370 * instance. 371 * @param eventType the eventType 372 * @param treeItem the treeItem 373 * @param selectionChanged the selectioonChanged 374 */ 375 public TreeModificationEvent(EventType<? extends Event> eventType, CheckBoxTreeItem<T> treeItem, boolean selectionChanged) { 376 super(eventType); 377 this.treeItem = treeItem; 378 this.selectionChanged = selectionChanged; 379 } 380 381 /** 382 * Returns the CheckBoxTreeItem that this event occurred upon. 383 * @return The CheckBoxTreeItem that this event occurred upon. 384 */ 385 public CheckBoxTreeItem<T> getTreeItem() { 386 return treeItem; 387 } 388 389 /** 390 * Indicates the reason for this event is that the selection on the 391 * CheckBoxTreeItem changed (as opposed to it becoming indeterminate). 392 * @return has the CheckBoxTreeItem's selection changed 393 */ 394 public boolean wasSelectionChanged() { 395 return selectionChanged; 396 } 397 398 /** 399 * Indicates the reason for this event is that the indeterminate 400 * state on the CheckBoxTreeItem changed (as opposed to it becoming 401 * selected or unselected). 402 * @return has the CheckBoxTreeItem's indeterminate changed 403 */ 404 public boolean wasIndeterminateChanged() { 405 return ! selectionChanged; 406 } 407 } 408 } |