/*
 * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package javafx.scene.control.cell;

import javafx.scene.control.CheckBoxTreeItem;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.value.ObservableValue;
import javafx.scene.control.CheckBox;
import javafx.scene.control.TreeCell;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeView;
import javafx.util.Callback;
import javafx.util.StringConverter;

A class containing a TreeCell implementation that draws a CheckBox node inside the cell, along with support for common interactions (discussed in more depth shortly).

To make creating TreeViews with CheckBoxes easier, a convenience class called CheckBoxTreeItem is provided. It is highly recommended that developers use this class, rather than the regular TreeItem class, when constructing their TreeView tree structures. Refer to the CheckBoxTreeItem API documentation for an example on how these two classes can be combined.

When used in a TreeView, the CheckBoxCell is rendered with a CheckBox to the right of the 'disclosure node' (i.e. the arrow). The item stored in TreeItem.getValue() will then have the StringConverter called on it, and this text will take all remaining horizontal space. Additionally, by using CheckBoxTreeItem, the TreeView will automatically handle situations such as:

  • Clicking on the CheckBox beside an item that has children will result in all children also becoming selected/unselected.
  • Clicking on the CheckBox beside an item that has a parent will possibly toggle the state of the parent. For example, if you select a single child, the parent will become indeterminate (indicating partial selection of children). If you proceed to select all children, the parent will then show that it too is selected. This is recursive, with all parent nodes updating as expected.
If it is decided that using CheckBoxTreeItem is not desirable, then it is necessary to call one of the constructors where a Callback is provided that can return an ObservableValue<Boolean> given a TreeItem instance. This ObservableValue<Boolean> should represent the boolean state of the given TreeItem.

Note that the CheckBoxTreeCell renders the CheckBox 'live', meaning that the CheckBox is always interactive and can be directly toggled by the user. This means that it is not necessary that the cell enter its editing state (usually by the user double-clicking on the cell). A side-effect of this is that the usual editing callbacks (such as on edit commit) will not be called. If you want to be notified of changes, it is recommended to directly observe the boolean properties that are manipulated by the CheckBox.

Type parameters:
  • <T> – The type of the elements contained within the TreeView TreeItem instances.
Since:JavaFX 2.2
/** * A class containing a {@link TreeCell} implementation that draws a * {@link CheckBox} node inside the cell, along with support for common * interactions (discussed in more depth shortly). * * <p>To make creating TreeViews with CheckBoxes easier, a convenience class * called {@link CheckBoxTreeItem} is provided. It is <b>highly</b> recommended * that developers use this class, rather than the regular {@link TreeItem} * class, when constructing their TreeView tree structures. Refer to the * CheckBoxTreeItem API documentation for an example on how these two classes * can be combined. * * <p>When used in a TreeView, the CheckBoxCell is rendered with a CheckBox to * the right of the 'disclosure node' (i.e. the arrow). The item stored in * {@link CheckBoxTreeItem#getValue()} will then have the StringConverter called * on it, and this text will take all remaining horizontal space. Additionally, * by using {@link CheckBoxTreeItem}, the TreeView will automatically handle * situations such as: * * <ul> * <li>Clicking on the {@link CheckBox} beside an item that has children will * result in all children also becoming selected/unselected. * <li>Clicking on the {@link CheckBox} beside an item that has a parent will * possibly toggle the state of the parent. For example, if you select a * single child, the parent will become indeterminate (indicating partial * selection of children). If you proceed to select all children, the * parent will then show that it too is selected. This is recursive, with * all parent nodes updating as expected. * </ul> * * If it is decided that using {@link CheckBoxTreeItem} is not desirable, * then it is necessary to call one of the constructors where a {@link Callback} * is provided that can return an {@code ObservableValue<Boolean>} * given a {@link TreeItem} instance. This {@code ObservableValue<Boolean>} * should represent the boolean state of the given {@link TreeItem}. * * <p>Note that the CheckBoxTreeCell renders the CheckBox 'live', meaning that * the CheckBox is always interactive and can be directly toggled by the user. * This means that it is not necessary that the cell enter its * {@link #editingProperty() editing state} (usually by the user double-clicking * on the cell). A side-effect of this is that the usual editing callbacks * (such as {@link javafx.scene.control.TreeView#onEditCommitProperty() on edit commit}) * will <strong>not</strong> be called. If you want to be notified of changes, * it is recommended to directly observe the boolean properties that are * manipulated by the CheckBox.</p> * * @param <T> The type of the elements contained within the TreeView TreeItem * instances. * @since JavaFX 2.2 */
public class CheckBoxTreeCell<T> extends DefaultTreeCell<T> { /*************************************************************************** * * * Static cell factories * * * **************************************************************************/
Creates a cell factory for use in a TreeView control, although there is a major assumption when used in a TreeView: this cell factory assumes that the TreeView root, and all children are instances of CheckBoxTreeItem, rather than the default TreeItem class that is used normally.

When used in a TreeView, the CheckBoxCell is rendered with a CheckBox to the right of the 'disclosure node' (i.e. the arrow). The item stored in TreeItem.getValue() will then have the StringConverter called on it, and this text will take all remaining horizontal space. Additionally, by using CheckBoxTreeItem, the TreeView will automatically handle situations such as:

  • Clicking on the CheckBox beside an item that has children will result in all children also becoming selected/unselected.
  • Clicking on the CheckBox beside an item that has a parent will possibly toggle the state of the parent. For example, if you select a single child, the parent will become indeterminate (indicating partial selection of children). If you proceed to select all children, the parent will then show that it too is selected. This is recursive, with all parent nodes updating as expected.

Unfortunately, due to limitations in Java, it is necessary to provide an explicit cast when using this method. For example:


final TreeView<String> treeView = new TreeView<String>();
treeView.setCellFactory(CheckBoxCell.<String>forTreeView());
Type parameters:
Returns:A Callback that will return a TreeCell that is able to work on the type of element contained within the TreeView root, and all of its children (recursively).
/** * Creates a cell factory for use in a TreeView control, although there is a * major assumption when used in a TreeView: this cell factory assumes that * the TreeView root, and <b>all</b> children are instances of * {@link CheckBoxTreeItem}, rather than the default {@link TreeItem} class * that is used normally. * * <p>When used in a TreeView, the CheckBoxCell is rendered with a CheckBox * to the right of the 'disclosure node' (i.e. the arrow). The item stored * in {@link CheckBoxTreeItem#getValue()} will then have the StringConverter * called on it, and this text will take all remaining horizontal space. * Additionally, by using {@link CheckBoxTreeItem}, the TreeView will * automatically handle situations such as: * * <ul> * <li>Clicking on the {@link CheckBox} beside an item that has children * will result in all children also becoming selected/unselected.</li> * <li>Clicking on the {@link CheckBox} beside an item that has a parent * will possibly toggle the state of the parent. For example, if you * select a single child, the parent will become indeterminate (indicating * partial selection of children). If you proceed to select all * children, the parent will then show that it too is selected. This is * recursive, with all parent nodes updating as expected.</li> * </ul> * * <p>Unfortunately, due to limitations in Java, it is necessary to provide * an explicit cast when using this method. For example: * * <pre> * {@code * final TreeView<String> treeView = new TreeView<String>(); * treeView.setCellFactory(CheckBoxCell.<String>forTreeView());}</pre> * * @param <T> The type of the elements contained within the * {@link CheckBoxTreeItem} instances. * @return A {@link Callback} that will return a TreeCell that is able to * work on the type of element contained within the TreeView root, and * all of its children (recursively). */
public static <T> Callback<TreeView<T>, TreeCell<T>> forTreeView() { Callback<TreeItem<T>, ObservableValue<Boolean>> getSelectedProperty = item -> { if (item instanceof CheckBoxTreeItem<?>) { return ((CheckBoxTreeItem<?>)item).selectedProperty(); } return null; }; return forTreeView(getSelectedProperty, CellUtils.<T>defaultTreeItemStringConverter()); }
Creates a cell factory for use in a TreeView control. Unlike forTreeView(), this method does not assume that all TreeItem instances in the TreeView are CheckBoxTreeItem instances.

When used in a TreeView, the CheckBoxCell is rendered with a CheckBox to the right of the 'disclosure node' (i.e. the arrow). The item stored in TreeItem.getValue() will then have the StringConverter called on it, and this text will take all remaining horizontal space.

Unlike forTreeView(), this cell factory does not handle updating the state of parent or children TreeItems - it simply toggles the ObservableValue<Boolean> that is provided, and no more. Of course, this functionality can then be implemented externally by adding observers to the ObservableValue<Boolean>, and toggling the state of other properties as necessary.

Params:
  • getSelectedProperty – A Callback that, given an object of type TreeItem<T>, will return an ObservableValue<Boolean> that represents whether the given item is selected or not. This ObservableValue<Boolean> will be bound bidirectionally (meaning that the CheckBox in the cell will set/unset this property based on user interactions, and the CheckBox will reflect the state of the ObservableValue<Boolean>, if it changes externally).
Type parameters:
  • <T> – The type of the elements contained within the TreeItem instances.
Returns:A Callback that will return a TreeCell that is able to work on the type of element contained within the TreeView root, and all of its children (recursively).
/** * Creates a cell factory for use in a TreeView control. Unlike * {@link #forTreeView()}, this method does not assume that all TreeItem * instances in the TreeView are {@link CheckBoxTreeItem} instances. * * <p>When used in a TreeView, the CheckBoxCell is rendered with a CheckBox * to the right of the 'disclosure node' (i.e. the arrow). The item stored * in {@link CheckBoxTreeItem#getValue()} will then have the StringConverter * called on it, and this text will take all remaining horizontal space. * * <p>Unlike {@link #forTreeView()}, this cell factory does not handle * updating the state of parent or children TreeItems - it simply toggles * the {@code ObservableValue<Boolean>} that is provided, and no more. Of * course, this functionality can then be implemented externally by adding * observers to the {@code ObservableValue<Boolean>}, and toggling the state * of other properties as necessary. * * @param <T> The type of the elements contained within the {@link TreeItem} * instances. * @param getSelectedProperty A {@link Callback} that, given an object of * type {@literal TreeItem<T>}, will return an {@code ObservableValue<Boolean>} * that represents whether the given item is selected or not. This * {@code ObservableValue<Boolean>} will be bound bidirectionally * (meaning that the CheckBox in the cell will set/unset this property * based on user interactions, and the CheckBox will reflect the state * of the {@code ObservableValue<Boolean>}, if it changes externally). * @return A {@link Callback} that will return a TreeCell that is able to * work on the type of element contained within the TreeView root, and * all of its children (recursively). */
public static <T> Callback<TreeView<T>, TreeCell<T>> forTreeView( final Callback<TreeItem<T>, ObservableValue<Boolean>> getSelectedProperty) { return forTreeView(getSelectedProperty, CellUtils.<T>defaultTreeItemStringConverter()); }
Creates a cell factory for use in a TreeView control. Unlike forTreeView(), this method does not assume that all TreeItem instances in the TreeView are CheckBoxTreeItem.

When used in a TreeView, the CheckBoxCell is rendered with a CheckBox to the right of the 'disclosure node' (i.e. the arrow). The item stored in TreeItem.getValue() will then have the the StringConverter called on it, and this text will take all remaining horizontal space.

Unlike forTreeView(), this cell factory does not handle updating the state of parent or children TreeItems - it simply toggles the ObservableValue<Boolean> that is provided, and no more. Of course, this functionality can then be implemented externally by adding observers to the ObservableValue<Boolean>, and toggling the state of other properties as necessary.

Params:
  • getSelectedProperty – A Callback that, given an object of type TreeItem<T>, will return an ObservableValue<Boolean> that represents whether the given item is selected or not. This ObservableValue<Boolean> will be bound bidirectionally (meaning that the CheckBox in the cell will set/unset this property based on user interactions, and the CheckBox will reflect the state of the ObservableValue<Boolean>, if it changes externally).
  • converter – A StringConverter that, give an object of type TreeItem<T>, will return a String that can be used to represent the object visually. The default implementation in forTreeView(Callback<TreeItem<Object>,ObservableValue<Boolean>>) is to simply call .toString() on all non-null items (and to just return an empty string in cases where the given item is null).
Type parameters:
  • <T> – The type of the elements contained within the TreeItem instances.
Returns:A Callback that will return a TreeCell that is able to work on the type of element contained within the TreeView root, and all of its children (recursively).
/** * Creates a cell factory for use in a TreeView control. Unlike * {@link #forTreeView()}, this method does not assume that all TreeItem * instances in the TreeView are {@link CheckBoxTreeItem}. * * <p>When used in a TreeView, the CheckBoxCell is rendered with a CheckBox * to the right of the 'disclosure node' (i.e. the arrow). The item stored * in {@link TreeItem#getValue()} will then have the the StringConverter * called on it, and this text will take all remaining horizontal space. * * <p>Unlike {@link #forTreeView()}, this cell factory does not handle * updating the state of parent or children TreeItems - it simply toggles * the {@code ObservableValue<Boolean>} that is provided, and no more. Of * course, this functionality can then be implemented externally by adding * observers to the {@code ObservableValue<Boolean>}, and toggling the state * of other properties as necessary. * * @param <T> The type of the elements contained within the {@link TreeItem} * instances. * @param getSelectedProperty A Callback that, given an object of * type {@literal TreeItem<T>}, will return an {@code ObservableValue<Boolean>} * that represents whether the given item is selected or not. This * {@code ObservableValue<Boolean>} will be bound bidirectionally * (meaning that the CheckBox in the cell will set/unset this property * based on user interactions, and the CheckBox will reflect the state of * the {@code ObservableValue<Boolean>}, if it changes externally). * @param converter A StringConverter that, give an object of type * {@literal TreeItem<T>}, will return a String that can be used to represent the * object visually. The default implementation in {@link #forTreeView(Callback)} * is to simply call .toString() on all non-null items (and to just * return an empty string in cases where the given item is null). * @return A {@link Callback} that will return a TreeCell that is able to * work on the type of element contained within the TreeView root, and * all of its children (recursively). */
public static <T> Callback<TreeView<T>, TreeCell<T>> forTreeView( final Callback<TreeItem<T>, ObservableValue<Boolean>> getSelectedProperty, final StringConverter<TreeItem<T>> converter) { return tree -> new CheckBoxTreeCell<T>(getSelectedProperty, converter); }
* Fields * *
/*************************************************************************** * * * Fields * * * **************************************************************************/
private final CheckBox checkBox; private ObservableValue<Boolean> booleanProperty; private BooleanProperty indeterminateProperty; /*************************************************************************** * * * Constructors * * * **************************************************************************/
Creates a default CheckBoxTreeCell that assumes the TreeView is constructed with CheckBoxTreeItem instances, rather than the default TreeItem. By using CheckBoxTreeItem, it will internally manage the selected and indeterminate state of each item in the tree.
/** * Creates a default {@link CheckBoxTreeCell} that assumes the TreeView is * constructed with {@link CheckBoxTreeItem} instances, rather than the * default {@link TreeItem}. * By using {@link CheckBoxTreeItem}, it will internally manage the selected * and indeterminate state of each item in the tree. */
public CheckBoxTreeCell() { // getSelectedProperty as anonymous inner class to deal with situation // where the user is using CheckBoxTreeItem instances in their tree this(item -> { if (item instanceof CheckBoxTreeItem<?>) { return ((CheckBoxTreeItem<?>)item).selectedProperty(); } return null; }); }
Creates a CheckBoxTreeCell for use in a TreeView control via a cell factory. Unlike CheckBoxTreeCell(), this method does not assume that all TreeItem instances in the TreeView are CheckBoxTreeItem.

To call this method, it is necessary to provide a Callback that, given an object of type TreeItem<T>, will return an ObservableValue<Boolean> that represents whether the given item is selected or not. This ObservableValue<Boolean> will be bound bidirectionally (meaning that the CheckBox in the cell will set/unset this property based on user interactions, and the CheckBox will reflect the state of the ObservableValue<Boolean>, if it changes externally).

If the items are not CheckBoxTreeItem instances, it becomes the developers responsibility to handle updating the state of parent and children TreeItems. This means that, given a TreeItem, this class will simply toggles the ObservableValue<Boolean> that is provided, and no more. Of course, this functionality can then be implemented externally by adding observers to the ObservableValue<Boolean>, and toggling the state of other properties as necessary.

Params:
  • getSelectedProperty – A Callback that will return an ObservableValue<Boolean> that represents whether the given item is selected or not.
/** * Creates a {@link CheckBoxTreeCell} for use in a TreeView control via a * cell factory. Unlike {@link CheckBoxTreeCell#CheckBoxTreeCell()}, this * method does not assume that all TreeItem instances in the TreeView are * {@link CheckBoxTreeItem}. * * <p>To call this method, it is necessary to provide a * {@link Callback} that, given an object of type {@literal TreeItem<T>}, will return * an {@code ObservableValue<Boolean>} that represents whether the given * item is selected or not. This {@code ObservableValue<Boolean>} will be * bound bidirectionally (meaning that the CheckBox in the cell will * set/unset this property based on user interactions, and the CheckBox will * reflect the state of the {@code ObservableValue<Boolean>}, if it changes * externally). * * <p>If the items are not {@link CheckBoxTreeItem} instances, it becomes * the developers responsibility to handle updating the state of parent and * children TreeItems. This means that, given a TreeItem, this class will * simply toggles the {@code ObservableValue<Boolean>} that is provided, and * no more. Of course, this functionality can then be implemented externally * by adding observers to the {@code ObservableValue<Boolean>}, and toggling * the state of other properties as necessary. * * @param getSelectedProperty A {@link Callback} that will return an * {@code ObservableValue<Boolean>} that represents whether the given * item is selected or not. */
public CheckBoxTreeCell( final Callback<TreeItem<T>, ObservableValue<Boolean>> getSelectedProperty) { this(getSelectedProperty, CellUtils.<T>defaultTreeItemStringConverter(), null); }
Creates a CheckBoxTreeCell for use in a TreeView control via a cell factory. Unlike CheckBoxTreeCell(), this method does not assume that all TreeItem instances in the TreeView are CheckBoxTreeItem.

To call this method, it is necessary to provide a Callback that, given an object of type TreeItem<T>, will return an ObservableValue<Boolean> that represents whether the given item is selected or not. This ObservableValue<Boolean> will be bound bidirectionally (meaning that the CheckBox in the cell will set/unset this property based on user interactions, and the CheckBox will reflect the state of the ObservableValue<Boolean>, if it changes externally).

If the items are not CheckBoxTreeItem instances, it becomes the developers responsibility to handle updating the state of parent and children TreeItems. This means that, given a TreeItem, this class will simply toggles the ObservableValue<Boolean> that is provided, and no more. Of course, this functionality can then be implemented externally by adding observers to the ObservableValue<Boolean>, and toggling the state of other properties as necessary.

Params:
  • getSelectedProperty – A Callback that will return an ObservableValue<Boolean> that represents whether the given item is selected or not.
  • converter – A StringConverter that, give an object of type TreeItem<T>, will return a String that can be used to represent the object visually.
/** * Creates a {@link CheckBoxTreeCell} for use in a TreeView control via a * cell factory. Unlike {@link CheckBoxTreeCell#CheckBoxTreeCell()}, this * method does not assume that all TreeItem instances in the TreeView are * {@link CheckBoxTreeItem}. * * <p>To call this method, it is necessary to provide a {@link Callback} * that, given an object of type {@literal TreeItem<T>}, will return an * {@code ObservableValue<Boolean>} that represents whether the given item * is selected or not. This {@code ObservableValue<Boolean>} will be bound * bidirectionally (meaning that the CheckBox in the cell will set/unset * this property based on user interactions, and the CheckBox will reflect * the state of the {@code ObservableValue<Boolean>}, if it changes * externally). * * <p>If the items are not {@link CheckBoxTreeItem} instances, it becomes * the developers responsibility to handle updating the state of parent and * children TreeItems. This means that, given a TreeItem, this class will * simply toggles the {@code ObservableValue<Boolean>} that is provided, and * no more. Of course, this functionality can then be implemented externally * by adding observers to the {@code ObservableValue<Boolean>}, and toggling * the state of other properties as necessary. * * @param getSelectedProperty A {@link Callback} that will return an * {@code ObservableValue<Boolean>} that represents whether the given * item is selected or not. * @param converter {@literal A StringConverter that, give an object of type * TreeItem<T>, will return a String that can be used to represent the * object visually.} */
public CheckBoxTreeCell( final Callback<TreeItem<T>, ObservableValue<Boolean>> getSelectedProperty, final StringConverter<TreeItem<T>> converter) { this(getSelectedProperty, converter, null); } private CheckBoxTreeCell( final Callback<TreeItem<T>, ObservableValue<Boolean>> getSelectedProperty, final StringConverter<TreeItem<T>> converter, final Callback<TreeItem<T>, ObservableValue<Boolean>> getIndeterminateProperty) { this.getStyleClass().add("check-box-tree-cell"); setSelectedStateCallback(getSelectedProperty); setConverter(converter); this.checkBox = new CheckBox(); this.checkBox.setAllowIndeterminate(false); // by default the graphic is null until the cell stops being empty setGraphic(null); }
* Properties * *
/*************************************************************************** * * * Properties * * * **************************************************************************/
// --- converter private ObjectProperty<StringConverter<TreeItem<T>>> converter = new SimpleObjectProperty<StringConverter<TreeItem<T>>>(this, "converter");
The StringConverter property.
Returns:the StringConverter property
/** * The {@link StringConverter} property. * @return the {@link StringConverter} property */
public final ObjectProperty<StringConverter<TreeItem<T>>> converterProperty() { return converter; }
Sets the StringConverter to be used in this cell.
Params:
/** * Sets the {@link StringConverter} to be used in this cell. * @param value the {@link StringConverter} to be used in this cell */
public final void setConverter(StringConverter<TreeItem<T>> value) { converterProperty().set(value); }
Returns the StringConverter used in this cell.
Returns:the StringConverter used in this cell
/** * Returns the {@link StringConverter} used in this cell. * @return the {@link StringConverter} used in this cell */
public final StringConverter<TreeItem<T>> getConverter() { return converterProperty().get(); } // --- selected state callback property private ObjectProperty<Callback<TreeItem<T>, ObservableValue<Boolean>>> selectedStateCallback = new SimpleObjectProperty<Callback<TreeItem<T>, ObservableValue<Boolean>>>( this, "selectedStateCallback");
Property representing the Callback that is bound to by the CheckBox shown on screen.
Returns:the property representing the Callback that is bound to by the CheckBox shown on screen
/** * Property representing the {@link Callback} that is bound to by the * CheckBox shown on screen. * @return the property representing the {@link Callback} that is bound to * by the CheckBox shown on screen */
public final ObjectProperty<Callback<TreeItem<T>, ObservableValue<Boolean>>> selectedStateCallbackProperty() { return selectedStateCallback; }
Sets the Callback that is bound to by the CheckBox shown on screen.
Params:
  • value – the Callback that is bound to by the CheckBox shown on screen
/** * Sets the {@link Callback} that is bound to by the CheckBox shown on screen. * @param value the {@link Callback} that is bound to by the CheckBox shown on screen */
public final void setSelectedStateCallback(Callback<TreeItem<T>, ObservableValue<Boolean>> value) { selectedStateCallbackProperty().set(value); }
Returns the Callback that is bound to by the CheckBox shown on screen.
Returns:the Callback that is bound to by the CheckBox shown on screen
/** * Returns the {@link Callback} that is bound to by the CheckBox shown on screen. * @return the {@link Callback} that is bound to by the CheckBox shown on screen */
public final Callback<TreeItem<T>, ObservableValue<Boolean>> getSelectedStateCallback() { return selectedStateCallbackProperty().get(); } /*************************************************************************** * * * Public API * * * **************************************************************************/
{@inheritDoc}
/** {@inheritDoc} */
@Override public void updateItem(T item, boolean empty) { super.updateItem(item, empty); if (empty) { setText(null); setGraphic(null); } else { StringConverter<TreeItem<T>> c = getConverter(); TreeItem<T> treeItem = getTreeItem(); // update the node content setText(c != null ? c.toString(treeItem) : (treeItem == null ? "" : treeItem.toString())); checkBox.setGraphic(treeItem == null ? null : treeItem.getGraphic()); setGraphic(checkBox); // uninstall bindings if (booleanProperty != null) { checkBox.selectedProperty().unbindBidirectional((BooleanProperty)booleanProperty); } if (indeterminateProperty != null) { checkBox.indeterminateProperty().unbindBidirectional(indeterminateProperty); } // install new bindings. // We special case things when the TreeItem is a CheckBoxTreeItem if (treeItem instanceof CheckBoxTreeItem) { CheckBoxTreeItem<T> cbti = (CheckBoxTreeItem<T>) treeItem; booleanProperty = cbti.selectedProperty(); checkBox.selectedProperty().bindBidirectional((BooleanProperty)booleanProperty); indeterminateProperty = cbti.indeterminateProperty(); checkBox.indeterminateProperty().bindBidirectional(indeterminateProperty); } else { Callback<TreeItem<T>, ObservableValue<Boolean>> callback = getSelectedStateCallback(); if (callback == null) { throw new NullPointerException( "The CheckBoxTreeCell selectedStateCallbackProperty can not be null"); } booleanProperty = callback.call(treeItem); if (booleanProperty != null) { checkBox.selectedProperty().bindBidirectional((BooleanProperty)booleanProperty); } } } } @Override void updateDisplay(T item, boolean empty) { // no-op // This was done to resolve RT-33603, but will impact the ability for // TreeItem.graphic to change dynamically. } }