< prev index next >

modules/javafx.controls/src/main/java/javafx/scene/control/cell/CheckBoxTreeCell.java

Print this page




 149     /**
 150      * Creates a cell factory for use in a TreeView control. Unlike
 151      * {@link #forTreeView()}, this method does not assume that all TreeItem
 152      * instances in the TreeView are {@link CheckBoxTreeItem} instances.
 153      *
 154      * <p>When used in a TreeView, the CheckBoxCell is rendered with a CheckBox
 155      * to the right of the 'disclosure node' (i.e. the arrow). The item stored
 156      * in {@link CheckBoxTreeItem#getValue()} will then have the StringConverter
 157      * called on it, and this text will take all remaining horizontal space.
 158      *
 159      * <p>Unlike {@link #forTreeView()}, this cell factory does not handle
 160      * updating the state of parent or children TreeItems - it simply toggles
 161      * the {@code ObservableValue<Boolean>} that is provided, and no more. Of
 162      * course, this functionality can then be implemented externally by adding
 163      * observers to the {@code ObservableValue<Boolean>}, and toggling the state
 164      * of other properties as necessary.
 165      *
 166      * @param <T> The type of the elements contained within the {@link TreeItem}
 167      *      instances.
 168      * @param getSelectedProperty A {@link Callback} that, given an object of
 169      *      type TreeItem<T>, will return an {@code ObservableValue<Boolean>}
 170      *      that represents whether the given item is selected or not. This
 171      *      {@code ObservableValue<Boolean>} will be bound bidirectionally
 172      *      (meaning that the CheckBox in the cell will set/unset this property
 173      *      based on user interactions, and the CheckBox will reflect the state
 174      *      of the {@code ObservableValue<Boolean>}, if it changes externally).
 175      * @return A {@link Callback} that will return a TreeCell that is able to
 176      *      work on the type of element contained within the TreeView root, and
 177      *      all of its children (recursively).
 178      */
 179     public static <T> Callback<TreeView<T>, TreeCell<T>> forTreeView(
 180             final Callback<TreeItem<T>,
 181             ObservableValue<Boolean>> getSelectedProperty) {
 182         return forTreeView(getSelectedProperty, CellUtils.<T>defaultTreeItemStringConverter());
 183     }
 184 
 185     /**
 186      * Creates a cell factory for use in a TreeView control. Unlike
 187      * {@link #forTreeView()}, this method does not assume that all TreeItem
 188      * instances in the TreeView are {@link CheckBoxTreeItem}.
 189      *
 190      * <p>When used in a TreeView, the CheckBoxCell is rendered with a CheckBox
 191      * to the right of the 'disclosure node' (i.e. the arrow). The item stored
 192      * in {@link TreeItem#getValue()} will then have the the StringConverter
 193      * called on it, and this text will take all remaining horizontal space.
 194      *
 195      * <p>Unlike {@link #forTreeView()}, this cell factory does not handle
 196      * updating the state of parent or children TreeItems - it simply toggles
 197      * the {@code ObservableValue<Boolean>} that is provided, and no more. Of
 198      * course, this functionality can then be implemented externally by adding
 199      * observers to the {@code ObservableValue<Boolean>}, and toggling the state
 200      * of other properties as necessary.
 201      *
 202      * @param <T> The type of the elements contained within the {@link TreeItem}
 203      *      instances.
 204      * @param getSelectedProperty A Callback that, given an object of
 205      *      type TreeItem<T>, will return an {@code ObservableValue<Boolean>}
 206      *      that represents whether the given item is selected or not. This
 207      *      {@code ObservableValue<Boolean>} will be bound bidirectionally
 208      *      (meaning that the CheckBox in the cell will set/unset this property
 209      *      based on user interactions, and the CheckBox will reflect the state of
 210      *      the {@code ObservableValue<Boolean>}, if it changes externally).
 211      * @param converter A StringConverter that, give an object of type TreeItem<T>,
 212      *      will return a String that can be used to represent the object
 213      *      visually. The default implementation in {@link #forTreeView(Callback)}
 214      *      is to simply call .toString() on all non-null items (and to just
 215      *      return an empty string in cases where the given item is null).
 216      * @return A {@link Callback} that will return a TreeCell that is able to
 217      *      work on the type of element contained within the TreeView root, and
 218      *      all of its children (recursively).
 219      */
 220     public static <T> Callback<TreeView<T>, TreeCell<T>> forTreeView(
 221             final Callback<TreeItem<T>, ObservableValue<Boolean>> getSelectedProperty,
 222             final StringConverter<TreeItem<T>> converter) {
 223         return tree -> new CheckBoxTreeCell<T>(getSelectedProperty, converter);
 224     }
 225 
 226 
 227 
 228 
 229     /***************************************************************************
 230      *                                                                         *
 231      * Fields                                                                  *
 232      *                                                                         *
 233      **************************************************************************/


 253      * and indeterminate state of each item in the tree.
 254      */
 255     public CheckBoxTreeCell() {
 256         // getSelectedProperty as anonymous inner class to deal with situation
 257         // where the user is using CheckBoxTreeItem instances in their tree
 258         this(item -> {
 259             if (item instanceof CheckBoxTreeItem<?>) {
 260                 return ((CheckBoxTreeItem<?>)item).selectedProperty();
 261             }
 262             return null;
 263         });
 264     }
 265 
 266     /**
 267      * Creates a {@link CheckBoxTreeCell} for use in a TreeView control via a
 268      * cell factory. Unlike {@link CheckBoxTreeCell#CheckBoxTreeCell()}, this
 269      * method does not assume that all TreeItem instances in the TreeView are
 270      * {@link CheckBoxTreeItem}.
 271      *
 272      * <p>To call this method, it is necessary to provide a
 273      * {@link Callback} that, given an object of type TreeItem<T>, will return
 274      * an {@code ObservableValue<Boolean>} that represents whether the given
 275      * item is selected or not. This {@code ObservableValue<Boolean>} will be
 276      * bound bidirectionally (meaning that the CheckBox in the cell will
 277      * set/unset this property based on user interactions, and the CheckBox will
 278      * reflect the state of the {@code ObservableValue<Boolean>}, if it changes
 279      * externally).
 280      *
 281      * <p>If the items are not {@link CheckBoxTreeItem} instances, it becomes
 282      * the developers responsibility to handle updating the state of parent and
 283      * children TreeItems. This means that, given a TreeItem, this class will
 284      * simply toggles the {@code ObservableValue<Boolean>} that is provided, and
 285      * no more. Of course, this functionality can then be implemented externally
 286      * by adding observers to the {@code ObservableValue<Boolean>}, and toggling
 287      * the state of other properties as necessary.
 288      *
 289      * @param getSelectedProperty A {@link Callback} that will return an
 290      *      {@code ObservableValue<Boolean>} that represents whether the given
 291      *      item is selected or not.
 292      */
 293     public CheckBoxTreeCell(
 294             final Callback<TreeItem<T>, ObservableValue<Boolean>> getSelectedProperty) {
 295         this(getSelectedProperty, CellUtils.<T>defaultTreeItemStringConverter(), null);
 296     }
 297 
 298     /**
 299      * Creates a {@link CheckBoxTreeCell} for use in a TreeView control via a
 300      * cell factory. Unlike {@link CheckBoxTreeCell#CheckBoxTreeCell()}, this
 301      * method does not assume that all TreeItem instances in the TreeView are
 302      * {@link CheckBoxTreeItem}.
 303      *
 304      * <p>To call this method, it is necessary to provide a {@link Callback}
 305      * that, given an object of type TreeItem<T>, will return an
 306      * {@code ObservableValue<Boolean>} that represents whether the given item
 307      * is selected or not. This {@code ObservableValue<Boolean>} will be bound
 308      * bidirectionally (meaning that the CheckBox in the cell will set/unset
 309      * this property based on user interactions, and the CheckBox will reflect
 310      * the state of the {@code ObservableValue<Boolean>}, if it changes
 311      * externally).
 312      *
 313      * <p>If the items are not {@link CheckBoxTreeItem} instances, it becomes
 314      * the developers responsibility to handle updating the state of parent and
 315      * children TreeItems. This means that, given a TreeItem, this class will
 316      * simply toggles the {@code ObservableValue<Boolean>} that is provided, and
 317      * no more. Of course, this functionality can then be implemented externally
 318      * by adding observers to the {@code ObservableValue<Boolean>}, and toggling
 319      * the state of other properties as necessary.
 320      *
 321      * @param getSelectedProperty A {@link Callback} that will return an
 322      *      {@code ObservableValue<Boolean>} that represents whether the given
 323      *      item is selected or not.
 324      * @param converter A StringConverter that, give an object of type TreeItem<T>, will
 325      *      return a String that can be used to represent the object visually.

 326      */
 327     public CheckBoxTreeCell(
 328             final Callback<TreeItem<T>, ObservableValue<Boolean>> getSelectedProperty,
 329             final StringConverter<TreeItem<T>> converter) {
 330         this(getSelectedProperty, converter, null);
 331     }
 332 
 333     private CheckBoxTreeCell(
 334             final Callback<TreeItem<T>, ObservableValue<Boolean>> getSelectedProperty,
 335             final StringConverter<TreeItem<T>> converter,
 336             final Callback<TreeItem<T>, ObservableValue<Boolean>> getIndeterminateProperty) {
 337         this.getStyleClass().add("check-box-tree-cell");
 338         setSelectedStateCallback(getSelectedProperty);
 339         setConverter(converter);
 340 
 341         this.checkBox = new CheckBox();
 342         this.checkBox.setAllowIndeterminate(false);
 343 
 344         // by default the graphic is null until the cell stops being empty
 345         setGraphic(null);
 346     }
 347 
 348 
 349 
 350     /***************************************************************************
 351      *                                                                         *
 352      * Properties                                                              *
 353      *                                                                         *
 354      **************************************************************************/
 355 
 356     // --- converter
 357     private ObjectProperty<StringConverter<TreeItem<T>>> converter =
 358             new SimpleObjectProperty<StringConverter<TreeItem<T>>>(this, "converter");
 359 
 360     /**
 361      * The {@link StringConverter} property.

 362      */
 363     public final ObjectProperty<StringConverter<TreeItem<T>>> converterProperty() {
 364         return converter;
 365     }
 366 
 367     /**
 368      * Sets the {@link StringConverter} to be used in this cell.

 369      */
 370     public final void setConverter(StringConverter<TreeItem<T>> value) {
 371         converterProperty().set(value);
 372     }
 373 
 374     /**
 375      * Returns the {@link StringConverter} used in this cell.

 376      */
 377     public final StringConverter<TreeItem<T>> getConverter() {
 378         return converterProperty().get();
 379     }
 380 
 381 
 382 
 383     // --- selected state callback property
 384     private ObjectProperty<Callback<TreeItem<T>, ObservableValue<Boolean>>>
 385             selectedStateCallback =
 386             new SimpleObjectProperty<Callback<TreeItem<T>, ObservableValue<Boolean>>>(
 387             this, "selectedStateCallback");
 388 
 389     /**
 390      * Property representing the {@link Callback} that is bound to by the
 391      * CheckBox shown on screen.


 392      */
 393     public final ObjectProperty<Callback<TreeItem<T>, ObservableValue<Boolean>>> selectedStateCallbackProperty() {
 394         return selectedStateCallback;
 395     }
 396 
 397     /**
 398      * Sets the {@link Callback} that is bound to by the CheckBox shown on screen.

 399      */
 400     public final void setSelectedStateCallback(Callback<TreeItem<T>, ObservableValue<Boolean>> value) {
 401         selectedStateCallbackProperty().set(value);
 402     }
 403 
 404     /**
 405      * Returns the {@link Callback} that is bound to by the CheckBox shown on screen.

 406      */
 407     public final Callback<TreeItem<T>, ObservableValue<Boolean>> getSelectedStateCallback() {
 408         return selectedStateCallbackProperty().get();
 409     }
 410 
 411 
 412 
 413     /***************************************************************************
 414      *                                                                         *
 415      * Public API                                                              *
 416      *                                                                         *
 417      **************************************************************************/
 418 
 419     /** {@inheritDoc} */
 420     @Override public void updateItem(T item, boolean empty) {
 421         super.updateItem(item, empty);
 422 
 423         if (empty) {
 424             setText(null);
 425             setGraphic(null);




 149     /**
 150      * Creates a cell factory for use in a TreeView control. Unlike
 151      * {@link #forTreeView()}, this method does not assume that all TreeItem
 152      * instances in the TreeView are {@link CheckBoxTreeItem} instances.
 153      *
 154      * <p>When used in a TreeView, the CheckBoxCell is rendered with a CheckBox
 155      * to the right of the 'disclosure node' (i.e. the arrow). The item stored
 156      * in {@link CheckBoxTreeItem#getValue()} will then have the StringConverter
 157      * called on it, and this text will take all remaining horizontal space.
 158      *
 159      * <p>Unlike {@link #forTreeView()}, this cell factory does not handle
 160      * updating the state of parent or children TreeItems - it simply toggles
 161      * the {@code ObservableValue<Boolean>} that is provided, and no more. Of
 162      * course, this functionality can then be implemented externally by adding
 163      * observers to the {@code ObservableValue<Boolean>}, and toggling the state
 164      * of other properties as necessary.
 165      *
 166      * @param <T> The type of the elements contained within the {@link TreeItem}
 167      *      instances.
 168      * @param getSelectedProperty A {@link Callback} that, given an object of
 169      *      type {@literal TreeItem<T>}, will return an {@code ObservableValue<Boolean>}
 170      *      that represents whether the given item is selected or not. This
 171      *      {@code ObservableValue<Boolean>} will be bound bidirectionally
 172      *      (meaning that the CheckBox in the cell will set/unset this property
 173      *      based on user interactions, and the CheckBox will reflect the state
 174      *      of the {@code ObservableValue<Boolean>}, if it changes externally).
 175      * @return A {@link Callback} that will return a TreeCell that is able to
 176      *      work on the type of element contained within the TreeView root, and
 177      *      all of its children (recursively).
 178      */
 179     public static <T> Callback<TreeView<T>, TreeCell<T>> forTreeView(
 180             final Callback<TreeItem<T>,
 181             ObservableValue<Boolean>> getSelectedProperty) {
 182         return forTreeView(getSelectedProperty, CellUtils.<T>defaultTreeItemStringConverter());
 183     }
 184 
 185     /**
 186      * Creates a cell factory for use in a TreeView control. Unlike
 187      * {@link #forTreeView()}, this method does not assume that all TreeItem
 188      * instances in the TreeView are {@link CheckBoxTreeItem}.
 189      *
 190      * <p>When used in a TreeView, the CheckBoxCell is rendered with a CheckBox
 191      * to the right of the 'disclosure node' (i.e. the arrow). The item stored
 192      * in {@link TreeItem#getValue()} will then have the the StringConverter
 193      * called on it, and this text will take all remaining horizontal space.
 194      *
 195      * <p>Unlike {@link #forTreeView()}, this cell factory does not handle
 196      * updating the state of parent or children TreeItems - it simply toggles
 197      * the {@code ObservableValue<Boolean>} that is provided, and no more. Of
 198      * course, this functionality can then be implemented externally by adding
 199      * observers to the {@code ObservableValue<Boolean>}, and toggling the state
 200      * of other properties as necessary.
 201      *
 202      * @param <T> The type of the elements contained within the {@link TreeItem}
 203      *      instances.
 204      * @param getSelectedProperty A Callback that, given an object of
 205      *      type {@literal TreeItem<T>}, will return an {@code ObservableValue<Boolean>}
 206      *      that represents whether the given item is selected or not. This
 207      *      {@code ObservableValue<Boolean>} will be bound bidirectionally
 208      *      (meaning that the CheckBox in the cell will set/unset this property
 209      *      based on user interactions, and the CheckBox will reflect the state of
 210      *      the {@code ObservableValue<Boolean>}, if it changes externally).
 211      * @param converter A StringConverter that, give an object of type
 212      *      {@literal TreeItem<T>}, will return a String that can be used to represent the
 213      *      object visually. The default implementation in {@link #forTreeView(Callback)}
 214      *      is to simply call .toString() on all non-null items (and to just
 215      *      return an empty string in cases where the given item is null).
 216      * @return A {@link Callback} that will return a TreeCell that is able to
 217      *      work on the type of element contained within the TreeView root, and
 218      *      all of its children (recursively).
 219      */
 220     public static <T> Callback<TreeView<T>, TreeCell<T>> forTreeView(
 221             final Callback<TreeItem<T>, ObservableValue<Boolean>> getSelectedProperty,
 222             final StringConverter<TreeItem<T>> converter) {
 223         return tree -> new CheckBoxTreeCell<T>(getSelectedProperty, converter);
 224     }
 225 
 226 
 227 
 228 
 229     /***************************************************************************
 230      *                                                                         *
 231      * Fields                                                                  *
 232      *                                                                         *
 233      **************************************************************************/


 253      * and indeterminate state of each item in the tree.
 254      */
 255     public CheckBoxTreeCell() {
 256         // getSelectedProperty as anonymous inner class to deal with situation
 257         // where the user is using CheckBoxTreeItem instances in their tree
 258         this(item -> {
 259             if (item instanceof CheckBoxTreeItem<?>) {
 260                 return ((CheckBoxTreeItem<?>)item).selectedProperty();
 261             }
 262             return null;
 263         });
 264     }
 265 
 266     /**
 267      * Creates a {@link CheckBoxTreeCell} for use in a TreeView control via a
 268      * cell factory. Unlike {@link CheckBoxTreeCell#CheckBoxTreeCell()}, this
 269      * method does not assume that all TreeItem instances in the TreeView are
 270      * {@link CheckBoxTreeItem}.
 271      *
 272      * <p>To call this method, it is necessary to provide a
 273      * {@link Callback} that, given an object of type {@literal TreeItem<T>}, will return
 274      * an {@code ObservableValue<Boolean>} that represents whether the given
 275      * item is selected or not. This {@code ObservableValue<Boolean>} will be
 276      * bound bidirectionally (meaning that the CheckBox in the cell will
 277      * set/unset this property based on user interactions, and the CheckBox will
 278      * reflect the state of the {@code ObservableValue<Boolean>}, if it changes
 279      * externally).
 280      *
 281      * <p>If the items are not {@link CheckBoxTreeItem} instances, it becomes
 282      * the developers responsibility to handle updating the state of parent and
 283      * children TreeItems. This means that, given a TreeItem, this class will
 284      * simply toggles the {@code ObservableValue<Boolean>} that is provided, and
 285      * no more. Of course, this functionality can then be implemented externally
 286      * by adding observers to the {@code ObservableValue<Boolean>}, and toggling
 287      * the state of other properties as necessary.
 288      *
 289      * @param getSelectedProperty A {@link Callback} that will return an
 290      *      {@code ObservableValue<Boolean>} that represents whether the given
 291      *      item is selected or not.
 292      */
 293     public CheckBoxTreeCell(
 294             final Callback<TreeItem<T>, ObservableValue<Boolean>> getSelectedProperty) {
 295         this(getSelectedProperty, CellUtils.<T>defaultTreeItemStringConverter(), null);
 296     }
 297 
 298     /**
 299      * Creates a {@link CheckBoxTreeCell} for use in a TreeView control via a
 300      * cell factory. Unlike {@link CheckBoxTreeCell#CheckBoxTreeCell()}, this
 301      * method does not assume that all TreeItem instances in the TreeView are
 302      * {@link CheckBoxTreeItem}.
 303      *
 304      * <p>To call this method, it is necessary to provide a {@link Callback}
 305      * that, given an object of type {@literal TreeItem<T>}, will return an
 306      * {@code ObservableValue<Boolean>} that represents whether the given item
 307      * is selected or not. This {@code ObservableValue<Boolean>} will be bound
 308      * bidirectionally (meaning that the CheckBox in the cell will set/unset
 309      * this property based on user interactions, and the CheckBox will reflect
 310      * the state of the {@code ObservableValue<Boolean>}, if it changes
 311      * externally).
 312      *
 313      * <p>If the items are not {@link CheckBoxTreeItem} instances, it becomes
 314      * the developers responsibility to handle updating the state of parent and
 315      * children TreeItems. This means that, given a TreeItem, this class will
 316      * simply toggles the {@code ObservableValue<Boolean>} that is provided, and
 317      * no more. Of course, this functionality can then be implemented externally
 318      * by adding observers to the {@code ObservableValue<Boolean>}, and toggling
 319      * the state of other properties as necessary.
 320      *
 321      * @param getSelectedProperty A {@link Callback} that will return an
 322      *      {@code ObservableValue<Boolean>} that represents whether the given
 323      *      item is selected or not.
 324      * @param converter {@literal A StringConverter that, give an object of type
 325      * TreeItem<T>, will return a String that can be used to represent the
 326      * object visually.}
 327      */
 328     public CheckBoxTreeCell(
 329             final Callback<TreeItem<T>, ObservableValue<Boolean>> getSelectedProperty,
 330             final StringConverter<TreeItem<T>> converter) {
 331         this(getSelectedProperty, converter, null);
 332     }
 333 
 334     private CheckBoxTreeCell(
 335             final Callback<TreeItem<T>, ObservableValue<Boolean>> getSelectedProperty,
 336             final StringConverter<TreeItem<T>> converter,
 337             final Callback<TreeItem<T>, ObservableValue<Boolean>> getIndeterminateProperty) {
 338         this.getStyleClass().add("check-box-tree-cell");
 339         setSelectedStateCallback(getSelectedProperty);
 340         setConverter(converter);
 341 
 342         this.checkBox = new CheckBox();
 343         this.checkBox.setAllowIndeterminate(false);
 344 
 345         // by default the graphic is null until the cell stops being empty
 346         setGraphic(null);
 347     }
 348 
 349 
 350 
 351     /***************************************************************************
 352      *                                                                         *
 353      * Properties                                                              *
 354      *                                                                         *
 355      **************************************************************************/
 356 
 357     // --- converter
 358     private ObjectProperty<StringConverter<TreeItem<T>>> converter =
 359             new SimpleObjectProperty<StringConverter<TreeItem<T>>>(this, "converter");
 360 
 361     /**
 362      * The {@link StringConverter} property.
 363      * @return the {@link StringConverter} property
 364      */
 365     public final ObjectProperty<StringConverter<TreeItem<T>>> converterProperty() {
 366         return converter;
 367     }
 368 
 369     /**
 370      * Sets the {@link StringConverter} to be used in this cell.
 371      * @param value the {@link StringConverter} to be used in this cell
 372      */
 373     public final void setConverter(StringConverter<TreeItem<T>> value) {
 374         converterProperty().set(value);
 375     }
 376 
 377     /**
 378      * Returns the {@link StringConverter} used in this cell.
 379      * @return the {@link StringConverter} used in this cell
 380      */
 381     public final StringConverter<TreeItem<T>> getConverter() {
 382         return converterProperty().get();
 383     }
 384 
 385 
 386 
 387     // --- selected state callback property
 388     private ObjectProperty<Callback<TreeItem<T>, ObservableValue<Boolean>>>
 389             selectedStateCallback =
 390             new SimpleObjectProperty<Callback<TreeItem<T>, ObservableValue<Boolean>>>(
 391             this, "selectedStateCallback");
 392 
 393     /**
 394      * Property representing the {@link Callback} that is bound to by the
 395      * CheckBox shown on screen.
 396      * @return the property representing the {@link Callback} that is bound to
 397      * by the CheckBox shown on screen
 398      */
 399     public final ObjectProperty<Callback<TreeItem<T>, ObservableValue<Boolean>>> selectedStateCallbackProperty() {
 400         return selectedStateCallback;
 401     }
 402 
 403     /**
 404      * Sets the {@link Callback} that is bound to by the CheckBox shown on screen.
 405      * @param value the {@link Callback} that is bound to by the CheckBox shown on screen
 406      */
 407     public final void setSelectedStateCallback(Callback<TreeItem<T>, ObservableValue<Boolean>> value) {
 408         selectedStateCallbackProperty().set(value);
 409     }
 410 
 411     /**
 412      * Returns the {@link Callback} that is bound to by the CheckBox shown on screen.
 413      * @return the {@link Callback} that is bound to by the CheckBox shown on screen
 414      */
 415     public final Callback<TreeItem<T>, ObservableValue<Boolean>> getSelectedStateCallback() {
 416         return selectedStateCallbackProperty().get();
 417     }
 418 
 419 
 420 
 421     /***************************************************************************
 422      *                                                                         *
 423      * Public API                                                              *
 424      *                                                                         *
 425      **************************************************************************/
 426 
 427     /** {@inheritDoc} */
 428     @Override public void updateItem(T item, boolean empty) {
 429         super.updateItem(item, empty);
 430 
 431         if (empty) {
 432             setText(null);
 433             setGraphic(null);


< prev index next >