< prev index next >

modules/javafx.controls/src/main/java/javafx/scene/control/TreeView.java

Print this page




 192  * @see TreeItem
 193  * @see TreeCell
 194  * @param <T> The type of the item contained within the {@link TreeItem} value
 195  *      property for all tree items in this TreeView.
 196  * @since JavaFX 2.0
 197  */
 198 @DefaultProperty("root")
 199 public class TreeView<T> extends Control {
 200 
 201     /***************************************************************************
 202      *                                                                         *
 203      * Static properties and methods                                           *
 204      *                                                                         *
 205      **************************************************************************/
 206 
 207     /**
 208      * An EventType that indicates some edit event has occurred. It is the parent
 209      * type of all other edit events: {@link #editStartEvent},
 210      *  {@link #editCommitEvent} and {@link #editCancelEvent}.
 211      *

 212      * @return An EventType that indicates some edit event has occurred.
 213      */
 214     @SuppressWarnings("unchecked")
 215     public static <T> EventType<EditEvent<T>> editAnyEvent() {
 216         return (EventType<EditEvent<T>>) EDIT_ANY_EVENT;
 217     }
 218     private static final EventType<?> EDIT_ANY_EVENT =
 219             new EventType<>(Event.ANY, "TREE_VIEW_EDIT");
 220 
 221     /**
 222      * An EventType used to indicate that an edit event has started within the
 223      * TreeView upon which the event was fired.
 224      *

 225      * @return An EventType used to indicate that an edit event has started.
 226      */
 227     @SuppressWarnings("unchecked")
 228     public static <T> EventType<EditEvent<T>> editStartEvent() {
 229         return (EventType<EditEvent<T>>) EDIT_START_EVENT;
 230     }
 231     private static final EventType<?> EDIT_START_EVENT =
 232             new EventType<>(editAnyEvent(), "EDIT_START");
 233 
 234     /**
 235      * An EventType used to indicate that an edit event has just been canceled
 236      * within the TreeView upon which the event was fired.
 237      *

 238      * @return An EventType used to indicate that an edit event has just been
 239      *      canceled.
 240      */
 241     @SuppressWarnings("unchecked")
 242     public static <T> EventType<EditEvent<T>> editCancelEvent() {
 243         return (EventType<EditEvent<T>>) EDIT_CANCEL_EVENT;
 244     }
 245     private static final EventType<?> EDIT_CANCEL_EVENT =
 246             new EventType<>(editAnyEvent(), "EDIT_CANCEL");
 247 
 248     /**
 249      * An EventType that is used to indicate that an edit in a TreeView has been
 250      * committed. This means that user has made changes to the data of a
 251      * TreeItem, and that the UI should be updated.
 252      *

 253      * @return An EventType that is used to indicate that an edit in a TreeView
 254      *      has been committed.
 255      */
 256     @SuppressWarnings("unchecked")
 257     public static <T> EventType<EditEvent<T>> editCommitEvent() {
 258         return (EventType<EditEvent<T>>) EDIT_COMMIT_EVENT;
 259     }
 260     private static final EventType<?> EDIT_COMMIT_EVENT =
 261             new EventType<>(editAnyEvent(), "EDIT_COMMIT");
 262 
 263     /**
 264      * Returns the number of levels of 'indentation' of the given TreeItem,
 265      * based on how many times {@link javafx.scene.control.TreeItem#getParent()}
 266      * can be recursively called. If the TreeItem does not have any parent set,
 267      * the returned value will be zero. For each time getParent() is recursively
 268      * called, the returned value is incremented by one.
 269      *
 270      * <p><strong>Important note: </strong>This method is deprecated as it does
 271      * not consider the root node. This means that this method will iterate
 272      * past the root node of the TreeView control, if the root node has a parent.


 399      * which are used to represent items in the
 400      * TreeView. The factory works identically to the cellFactory in ListView
 401      * and other complex composite controls. It is called to create a new
 402      * TreeCell only when the system has determined that it doesn't have enough
 403      * cells to represent the currently visible items. The TreeCell is reused
 404      * by the system to represent different items in the tree when possible.
 405      *
 406      * <p>Refer to the {@link Cell} class documentation for more details.
 407      *
 408      * @param value The {@link Callback} to use for generating TreeCell instances,
 409      *      or null if the default cell factory should be used.
 410      */
 411     public final void setCellFactory(Callback<TreeView<T>, TreeCell<T>> value) {
 412         cellFactoryProperty().set(value);
 413     }
 414 
 415     /**
 416      * <p>Returns the cell factory that will be used for creating TreeCells,
 417      * which are used to represent items in the TreeView, or null if no custom
 418      * cell factory has been set.

 419      */
 420     public final Callback<TreeView<T>, TreeCell<T>> getCellFactory() {
 421         return cellFactory == null ? null : cellFactory.get();
 422     }
 423 
 424     /**
 425      * Represents the cell factory that will be used for creating TreeCells,
 426      * which are used to represent items in the TreeView.

 427      */
 428     public final ObjectProperty<Callback<TreeView<T>, TreeCell<T>>> cellFactoryProperty() {
 429         if (cellFactory == null) {
 430             cellFactory = new SimpleObjectProperty<Callback<TreeView<T>, TreeCell<T>>>(this, "cellFactory");
 431         }
 432         return cellFactory;
 433     }
 434 
 435 
 436     // --- Root
 437     private ObjectProperty<TreeItem<T>> root = new SimpleObjectProperty<TreeItem<T>>(this, "root") {
 438         private WeakReference<TreeItem<T>> weakOldItem;
 439 
 440         @Override protected void invalidated() {
 441             TreeItem<T> oldTreeItem = weakOldItem == null ? null : weakOldItem.get();
 442             if (oldTreeItem != null && weakRootEventListener != null) {
 443                 oldTreeItem.removeEventHandler(TreeItem.<T>treeNotificationEvent(), weakRootEventListener);
 444             }
 445 
 446             TreeItem<T> root = getRoot();


 463      * documentation for more details.
 464      *
 465      * @param value The {@link TreeItem} that will be placed at the root of the
 466      *      TreeView.
 467      */
 468     public final void setRoot(TreeItem<T> value) {
 469         rootProperty().set(value);
 470     }
 471 
 472     /**
 473      * Returns the current root node of this TreeView, or null if no root node
 474      * is specified.
 475      * @return The current root node, or null if no root node exists.
 476      */
 477     public final TreeItem<T> getRoot() {
 478         return root == null ? null : root.get();
 479     }
 480 
 481     /**
 482      * Property representing the root node of the TreeView.

 483      */
 484     public final ObjectProperty<TreeItem<T>> rootProperty() {
 485         return root;
 486     }
 487 
 488 
 489 
 490     // --- Show Root
 491     private BooleanProperty showRoot;
 492 
 493     /**
 494      * Specifies whether the root {@code TreeItem} should be shown within this
 495      * TreeView.
 496      *
 497      * @param value If true, the root TreeItem will be shown, and if false it
 498      *      will be hidden.
 499      */
 500     public final void setShowRoot(boolean value) {
 501         showRootProperty().set(value);
 502     }
 503 
 504     /**
 505      * Returns true if the root of the TreeView should be shown, and false if
 506      * it should not. By default, the root TreeItem is visible in the TreeView.

 507      */
 508     public final boolean isShowRoot() {
 509         return showRoot == null ? true : showRoot.get();
 510     }
 511 
 512     /**
 513      * Property that represents whether or not the TreeView root node is visible.

 514      */
 515     public final BooleanProperty showRootProperty() {
 516         if (showRoot == null) {
 517             showRoot = new SimpleBooleanProperty(this, "showRoot", true) {
 518                 @Override protected void invalidated() {
 519                     updateRootExpanded();
 520                     updateExpandedItemCount(getRoot());
 521                 }
 522             };
 523         }
 524         return showRoot;
 525     }
 526 
 527 
 528     // --- Selection Model
 529     private ObjectProperty<MultipleSelectionModel<TreeItem<T>>> selectionModel;
 530 
 531     /**
 532      * Sets the {@link MultipleSelectionModel} to be used in the TreeView.
 533      * Despite a TreeView requiring a <code><b>Multiple</b>SelectionModel</code>,
 534      * it is possible to configure it to only allow single selection (see
 535      * {@link MultipleSelectionModel#setSelectionMode(javafx.scene.control.SelectionMode)}
 536      * for more information).

 537      */
 538     public final void setSelectionModel(MultipleSelectionModel<TreeItem<T>> value) {
 539         selectionModelProperty().set(value);
 540     }
 541 
 542     /**
 543      * Returns the currently installed selection model.

 544      */
 545     public final MultipleSelectionModel<TreeItem<T>> getSelectionModel() {
 546         return selectionModel == null ? null : selectionModel.get();
 547     }
 548 
 549     /**
 550      * The SelectionModel provides the API through which it is possible
 551      * to select single or multiple items within a TreeView, as  well as inspect
 552      * which rows have been selected by the user. Note that it has a generic
 553      * type that must match the type of the TreeView itself.

 554      */
 555     public final ObjectProperty<MultipleSelectionModel<TreeItem<T>>> selectionModelProperty() {
 556         if (selectionModel == null) {
 557             selectionModel = new SimpleObjectProperty<MultipleSelectionModel<TreeItem<T>>>(this, "selectionModel");
 558         }
 559         return selectionModel;
 560     }
 561 
 562 
 563     // --- Focus Model
 564     private ObjectProperty<FocusModel<TreeItem<T>>> focusModel;
 565 
 566     /**
 567      * Sets the {@link FocusModel} to be used in the TreeView.

 568      */
 569     public final void setFocusModel(FocusModel<TreeItem<T>> value) {
 570         focusModelProperty().set(value);
 571     }
 572 
 573     /**
 574      * Returns the currently installed {@link FocusModel}.

 575      */
 576     public final FocusModel<TreeItem<T>> getFocusModel() {
 577         return focusModel == null ? null : focusModel.get();
 578     }
 579 
 580     /**
 581      * The FocusModel provides the API through which it is possible
 582      * to control focus on zero or one rows of the TreeView. Generally the
 583      * default implementation should be more than sufficient.

 584      */
 585     public final ObjectProperty<FocusModel<TreeItem<T>>> focusModelProperty() {
 586         if (focusModel == null) {
 587             focusModel = new SimpleObjectProperty<FocusModel<TreeItem<T>>>(this, "focusModel");
 588         }
 589         return focusModel;
 590     }
 591 
 592 
 593     // --- Expanded node count
 594     /**
 595      * <p>Represents the number of tree nodes presently able to be visible in the
 596      * TreeView. This is essentially the count of all expanded tree items, and
 597      * their children.
 598      *
 599      * <p>For example, if just the root node is visible, the expandedItemCount will
 600      * be one. If the root had three children and the root was expanded, the value
 601      * will be four.
 602      * @since JavaFX 8.0
 603      */


 647     }
 648     /**
 649      * Specifies whether this control has cells that are a fixed height (of the
 650      * specified value). If this value is less than or equal to zero,
 651      * then all cells are individually sized and positioned. This is a slow
 652      * operation. Therefore, when performance matters and developers are not
 653      * dependent on variable cell sizes it is a good idea to set the fixed cell
 654      * size value. Generally cells are around 24px, so setting a fixed cell size
 655      * of 24 is likely to result in very little difference in visuals, but a
 656      * improvement to performance.
 657      *
 658      * <p>To set this property via CSS, use the -fx-fixed-cell-size property.
 659      * This should not be confused with the -fx-cell-size property. The difference
 660      * between these two CSS properties is that -fx-cell-size will size all
 661      * cells to the specified size, but it will not enforce that this is the
 662      * only size (thus allowing for variable cell sizes, and preventing the
 663      * performance gains from being possible). Therefore, when performance matters
 664      * use -fx-fixed-cell-size, instead of -fx-cell-size. If both properties are
 665      * specified in CSS, -fx-fixed-cell-size takes precedence.</p>
 666      *

 667      * @since JavaFX 8.0
 668      */
 669     public final DoubleProperty fixedCellSizeProperty() {
 670         if (fixedCellSize == null) {
 671             fixedCellSize = new StyleableDoubleProperty(Region.USE_COMPUTED_SIZE) {
 672                 @Override public CssMetaData<TreeView<?>,Number> getCssMetaData() {
 673                     return StyleableProperties.FIXED_CELL_SIZE;
 674                 }
 675 
 676                 @Override public Object getBean() {
 677                     return TreeView.this;
 678                 }
 679 
 680                 @Override public String getName() {
 681                     return "fixedCellSize";
 682                 }
 683             };
 684         }
 685         return fixedCellSize;
 686     }
 687 
 688 
 689     // --- Editable
 690     private BooleanProperty editable;
 691     public final void setEditable(boolean value) {
 692         editableProperty().set(value);
 693     }
 694     public final boolean isEditable() {
 695         return editable == null ? false : editable.get();
 696     }
 697     /**
 698      * Specifies whether this TreeView is editable - only if the TreeView and
 699      * the TreeCells within it are both editable will a TreeCell be able to go
 700      * into their editing state.

 701      */
 702     public final BooleanProperty editableProperty() {
 703         if (editable == null) {
 704             editable = new SimpleBooleanProperty(this, "editable", false);
 705         }
 706         return editable;
 707     }
 708 
 709 
 710     // --- Editing Item
 711     private ReadOnlyObjectWrapper<TreeItem<T>> editingItem;
 712 
 713     private void setEditingItem(TreeItem<T> value) {
 714         editingItemPropertyImpl().set(value);
 715     }
 716 
 717     /**
 718      * Returns the TreeItem that is currently being edited in the TreeView,
 719      * or null if no item is being edited.

 720      */
 721     public final TreeItem<T> getEditingItem() {
 722         return editingItem == null ? null : editingItem.get();
 723     }
 724 
 725     /**
 726      * <p>A property used to represent the TreeItem currently being edited
 727      * in the TreeView, if editing is taking place, or null if no item is being edited.
 728      *
 729      * <p>It is not possible to set the editing item, instead it is required that
 730      * you call {@link #edit(javafx.scene.control.TreeItem)}.

 731      */
 732     public final ReadOnlyObjectProperty<TreeItem<T>> editingItemProperty() {
 733         return editingItemPropertyImpl().getReadOnlyProperty();
 734     }
 735 
 736     private ReadOnlyObjectWrapper<TreeItem<T>> editingItemPropertyImpl() {
 737         if (editingItem == null) {
 738             editingItem = new ReadOnlyObjectWrapper<TreeItem<T>>(this, "editingItem");
 739         }
 740         return editingItem;
 741     }
 742 
 743 
 744     // --- On Edit Start
 745     private ObjectProperty<EventHandler<EditEvent<T>>> onEditStart;
 746 
 747     /**
 748      * Sets the {@link EventHandler} that will be called when the user begins
 749      * an edit.


 750      */
 751     public final void setOnEditStart(EventHandler<EditEvent<T>> value) {
 752         onEditStartProperty().set(value);
 753     }
 754 
 755     /**
 756      * Returns the {@link EventHandler} that will be called when the user begins
 757      * an edit.

 758      */
 759     public final EventHandler<EditEvent<T>> getOnEditStart() {
 760         return onEditStart == null ? null : onEditStart.get();
 761     }
 762 
 763     /**
 764      * This event handler will be fired when the user successfully initiates
 765      * editing.

 766      */
 767     public final ObjectProperty<EventHandler<EditEvent<T>>> onEditStartProperty() {
 768         if (onEditStart == null) {
 769             onEditStart = new SimpleObjectProperty<EventHandler<EditEvent<T>>>(this, "onEditStart") {
 770                 @Override protected void invalidated() {
 771                     setEventHandler(TreeView.<T>editStartEvent(), get());
 772                 }
 773             };
 774         }
 775         return onEditStart;
 776     }
 777 
 778 
 779     // --- On Edit Commit
 780     private ObjectProperty<EventHandler<EditEvent<T>>> onEditCommit;
 781 
 782     /**
 783      * Sets the {@link EventHandler} that will be called when the user commits
 784      * an edit.


 785      */
 786     public final void setOnEditCommit(EventHandler<EditEvent<T>> value) {
 787         onEditCommitProperty().set(value);
 788     }
 789 
 790     /**
 791      * Returns the {@link EventHandler} that will be called when the user commits
 792      * an edit.


 793      */
 794     public final EventHandler<EditEvent<T>> getOnEditCommit() {
 795         return onEditCommit == null ? null : onEditCommit.get();
 796     }
 797 
 798     /**
 799      * <p>This property is used when the user performs an action that should
 800      * result in their editing input being persisted.</p>
 801      *
 802      * <p>The EventHandler in this property should not be called directly -
 803      * instead call {@link TreeCell#commitEdit(java.lang.Object)} from within
 804      * your custom TreeCell. This will handle firing this event, updating the
 805      * view, and switching out of the editing state.</p>


 806      */
 807     public final ObjectProperty<EventHandler<EditEvent<T>>> onEditCommitProperty() {
 808         if (onEditCommit == null) {
 809             onEditCommit = new SimpleObjectProperty<EventHandler<EditEvent<T>>>(this, "onEditCommit") {
 810                 @Override protected void invalidated() {
 811                     setEventHandler(TreeView.<T>editCommitEvent(), get());
 812                 }
 813             };
 814         }
 815         return onEditCommit;
 816     }
 817 
 818 
 819     // --- On Edit Cancel
 820     private ObjectProperty<EventHandler<EditEvent<T>>> onEditCancel;
 821 
 822     /**
 823      * Sets the {@link EventHandler} that will be called when the user cancels
 824      * an edit.


 825      */
 826     public final void setOnEditCancel(EventHandler<EditEvent<T>> value) {
 827         onEditCancelProperty().set(value);
 828     }
 829 
 830     /**
 831      * Returns the {@link EventHandler} that will be called when the user cancels
 832      * an edit.


 833      */
 834     public final EventHandler<EditEvent<T>> getOnEditCancel() {
 835         return onEditCancel == null ? null : onEditCancel.get();
 836     }
 837 
 838     /**
 839      * This event handler will be fired when the user cancels editing a cell.


 840      */
 841     public final ObjectProperty<EventHandler<EditEvent<T>>> onEditCancelProperty() {
 842         if (onEditCancel == null) {
 843             onEditCancel = new SimpleObjectProperty<EventHandler<EditEvent<T>>>(this, "onEditCancel") {
 844                 @Override protected void invalidated() {
 845                     setEventHandler(TreeView.<T>editCancelEvent(), get());
 846                 }
 847             };
 848         }
 849         return onEditCancel;
 850     }
 851 
 852 
 853 
 854     /***************************************************************************
 855      *                                                                         *
 856      * Public API                                                              *
 857      *                                                                         *
 858      **************************************************************************/
 859 


1161      * @since JavaFX 2.0
1162      */
1163     public static class EditEvent<T> extends Event {
1164         private static final long serialVersionUID = -4437033058917528976L;
1165 
1166         /**
1167          * Common supertype for all edit event types.
1168          * @since JavaFX 8.0
1169          */
1170         public static final EventType<?> ANY = EDIT_ANY_EVENT;
1171 
1172         private final TreeView<T> source;
1173         private final T oldValue;
1174         private final T newValue;
1175         private transient final TreeItem<T> treeItem;
1176 
1177         /**
1178          * Creates a new EditEvent instance to represent an edit event. This
1179          * event is used for {@link #EDIT_START_EVENT},
1180          * {@link #EDIT_COMMIT_EVENT} and {@link #EDIT_CANCEL_EVENT} types.





1181          */
1182         public EditEvent(TreeView<T> source,
1183                          EventType<? extends EditEvent> eventType,
1184                          TreeItem<T> treeItem, T oldValue, T newValue) {
1185             super(source, Event.NULL_SOURCE_TARGET, eventType);
1186             this.source = source;
1187             this.oldValue = oldValue;
1188             this.newValue = newValue;
1189             this.treeItem = treeItem;
1190         }
1191 
1192         /**
1193          * Returns the TreeView upon which the edit took place.
1194          */
1195         @Override public TreeView<T> getSource() {
1196             return source;
1197         }
1198 
1199         /**
1200          * Returns the {@link TreeItem} upon which the edit took place.

1201          */
1202         public TreeItem<T> getTreeItem() {
1203             return treeItem;
1204         }
1205 
1206         /**
1207          * Returns the new value input into the TreeItem by the end user.

1208          */
1209         public T getNewValue() {
1210             return newValue;
1211         }
1212 
1213         /**
1214          * Returns the old value that existed in the TreeItem prior to the current
1215          * edit event.


1216          */
1217         public T getOldValue() {
1218             return oldValue;
1219         }
1220     }
1221 
1222 
1223 
1224 
1225 
1226 
1227 
1228     // package for testing
1229     static class TreeViewBitSetSelectionModel<T> extends MultipleSelectionModelBase<TreeItem<T>> {
1230 
1231         /***********************************************************************
1232          *                                                                     *
1233          * Internal fields                                                     *
1234          *                                                                     *
1235          **********************************************************************/




 192  * @see TreeItem
 193  * @see TreeCell
 194  * @param <T> The type of the item contained within the {@link TreeItem} value
 195  *      property for all tree items in this TreeView.
 196  * @since JavaFX 2.0
 197  */
 198 @DefaultProperty("root")
 199 public class TreeView<T> extends Control {
 200 
 201     /***************************************************************************
 202      *                                                                         *
 203      * Static properties and methods                                           *
 204      *                                                                         *
 205      **************************************************************************/
 206 
 207     /**
 208      * An EventType that indicates some edit event has occurred. It is the parent
 209      * type of all other edit events: {@link #editStartEvent},
 210      *  {@link #editCommitEvent} and {@link #editCancelEvent}.
 211      *
 212      * @param <T> the type of edit event
 213      * @return An EventType that indicates some edit event has occurred.
 214      */
 215     @SuppressWarnings("unchecked")
 216     public static <T> EventType<EditEvent<T>> editAnyEvent() {
 217         return (EventType<EditEvent<T>>) EDIT_ANY_EVENT;
 218     }
 219     private static final EventType<?> EDIT_ANY_EVENT =
 220             new EventType<>(Event.ANY, "TREE_VIEW_EDIT");
 221 
 222     /**
 223      * An EventType used to indicate that an edit event has started within the
 224      * TreeView upon which the event was fired.
 225      *
 226      * @param <T> the type of edit event
 227      * @return An EventType used to indicate that an edit event has started.
 228      */
 229     @SuppressWarnings("unchecked")
 230     public static <T> EventType<EditEvent<T>> editStartEvent() {
 231         return (EventType<EditEvent<T>>) EDIT_START_EVENT;
 232     }
 233     private static final EventType<?> EDIT_START_EVENT =
 234             new EventType<>(editAnyEvent(), "EDIT_START");
 235 
 236     /**
 237      * An EventType used to indicate that an edit event has just been canceled
 238      * within the TreeView upon which the event was fired.
 239      *
 240      * @param <T> the type of edit event
 241      * @return An EventType used to indicate that an edit event has just been
 242      *      canceled.
 243      */
 244     @SuppressWarnings("unchecked")
 245     public static <T> EventType<EditEvent<T>> editCancelEvent() {
 246         return (EventType<EditEvent<T>>) EDIT_CANCEL_EVENT;
 247     }
 248     private static final EventType<?> EDIT_CANCEL_EVENT =
 249             new EventType<>(editAnyEvent(), "EDIT_CANCEL");
 250 
 251     /**
 252      * An EventType that is used to indicate that an edit in a TreeView has been
 253      * committed. This means that user has made changes to the data of a
 254      * TreeItem, and that the UI should be updated.
 255      *
 256      * @param <T> the type of edit event
 257      * @return An EventType that is used to indicate that an edit in a TreeView
 258      *      has been committed.
 259      */
 260     @SuppressWarnings("unchecked")
 261     public static <T> EventType<EditEvent<T>> editCommitEvent() {
 262         return (EventType<EditEvent<T>>) EDIT_COMMIT_EVENT;
 263     }
 264     private static final EventType<?> EDIT_COMMIT_EVENT =
 265             new EventType<>(editAnyEvent(), "EDIT_COMMIT");
 266 
 267     /**
 268      * Returns the number of levels of 'indentation' of the given TreeItem,
 269      * based on how many times {@link javafx.scene.control.TreeItem#getParent()}
 270      * can be recursively called. If the TreeItem does not have any parent set,
 271      * the returned value will be zero. For each time getParent() is recursively
 272      * called, the returned value is incremented by one.
 273      *
 274      * <p><strong>Important note: </strong>This method is deprecated as it does
 275      * not consider the root node. This means that this method will iterate
 276      * past the root node of the TreeView control, if the root node has a parent.


 403      * which are used to represent items in the
 404      * TreeView. The factory works identically to the cellFactory in ListView
 405      * and other complex composite controls. It is called to create a new
 406      * TreeCell only when the system has determined that it doesn't have enough
 407      * cells to represent the currently visible items. The TreeCell is reused
 408      * by the system to represent different items in the tree when possible.
 409      *
 410      * <p>Refer to the {@link Cell} class documentation for more details.
 411      *
 412      * @param value The {@link Callback} to use for generating TreeCell instances,
 413      *      or null if the default cell factory should be used.
 414      */
 415     public final void setCellFactory(Callback<TreeView<T>, TreeCell<T>> value) {
 416         cellFactoryProperty().set(value);
 417     }
 418 
 419     /**
 420      * <p>Returns the cell factory that will be used for creating TreeCells,
 421      * which are used to represent items in the TreeView, or null if no custom
 422      * cell factory has been set.
 423      * @return the cell factory
 424      */
 425     public final Callback<TreeView<T>, TreeCell<T>> getCellFactory() {
 426         return cellFactory == null ? null : cellFactory.get();
 427     }
 428 
 429     /**
 430      * Represents the cell factory that will be used for creating TreeCells,
 431      * which are used to represent items in the TreeView.
 432      * @return the cell factory property
 433      */
 434     public final ObjectProperty<Callback<TreeView<T>, TreeCell<T>>> cellFactoryProperty() {
 435         if (cellFactory == null) {
 436             cellFactory = new SimpleObjectProperty<Callback<TreeView<T>, TreeCell<T>>>(this, "cellFactory");
 437         }
 438         return cellFactory;
 439     }
 440 
 441 
 442     // --- Root
 443     private ObjectProperty<TreeItem<T>> root = new SimpleObjectProperty<TreeItem<T>>(this, "root") {
 444         private WeakReference<TreeItem<T>> weakOldItem;
 445 
 446         @Override protected void invalidated() {
 447             TreeItem<T> oldTreeItem = weakOldItem == null ? null : weakOldItem.get();
 448             if (oldTreeItem != null && weakRootEventListener != null) {
 449                 oldTreeItem.removeEventHandler(TreeItem.<T>treeNotificationEvent(), weakRootEventListener);
 450             }
 451 
 452             TreeItem<T> root = getRoot();


 469      * documentation for more details.
 470      *
 471      * @param value The {@link TreeItem} that will be placed at the root of the
 472      *      TreeView.
 473      */
 474     public final void setRoot(TreeItem<T> value) {
 475         rootProperty().set(value);
 476     }
 477 
 478     /**
 479      * Returns the current root node of this TreeView, or null if no root node
 480      * is specified.
 481      * @return The current root node, or null if no root node exists.
 482      */
 483     public final TreeItem<T> getRoot() {
 484         return root == null ? null : root.get();
 485     }
 486 
 487     /**
 488      * Property representing the root node of the TreeView.
 489      * @return the root node property
 490      */
 491     public final ObjectProperty<TreeItem<T>> rootProperty() {
 492         return root;
 493     }
 494 
 495 
 496 
 497     // --- Show Root
 498     private BooleanProperty showRoot;
 499 
 500     /**
 501      * Specifies whether the root {@code TreeItem} should be shown within this
 502      * TreeView.
 503      *
 504      * @param value If true, the root TreeItem will be shown, and if false it
 505      *      will be hidden.
 506      */
 507     public final void setShowRoot(boolean value) {
 508         showRootProperty().set(value);
 509     }
 510 
 511     /**
 512      * Returns true if the root of the TreeView should be shown, and false if
 513      * it should not. By default, the root TreeItem is visible in the TreeView.
 514      * @return true if the root of the TreeView should be shown
 515      */
 516     public final boolean isShowRoot() {
 517         return showRoot == null ? true : showRoot.get();
 518     }
 519 
 520     /**
 521      * Property that represents whether or not the TreeView root node is visible.
 522      * @return the show root property
 523      */
 524     public final BooleanProperty showRootProperty() {
 525         if (showRoot == null) {
 526             showRoot = new SimpleBooleanProperty(this, "showRoot", true) {
 527                 @Override protected void invalidated() {
 528                     updateRootExpanded();
 529                     updateExpandedItemCount(getRoot());
 530                 }
 531             };
 532         }
 533         return showRoot;
 534     }
 535 
 536 
 537     // --- Selection Model
 538     private ObjectProperty<MultipleSelectionModel<TreeItem<T>>> selectionModel;
 539 
 540     /**
 541      * Sets the {@link MultipleSelectionModel} to be used in the TreeView.
 542      * Despite a TreeView requiring a <code><b>Multiple</b>SelectionModel</code>,
 543      * it is possible to configure it to only allow single selection (see
 544      * {@link MultipleSelectionModel#setSelectionMode(javafx.scene.control.SelectionMode)}
 545      * for more information).
 546      * @param value the {@link MultipleSelectionModel} to be used
 547      */
 548     public final void setSelectionModel(MultipleSelectionModel<TreeItem<T>> value) {
 549         selectionModelProperty().set(value);
 550     }
 551 
 552     /**
 553      * Returns the currently installed selection model.
 554      * @return the currently installed selection model
 555      */
 556     public final MultipleSelectionModel<TreeItem<T>> getSelectionModel() {
 557         return selectionModel == null ? null : selectionModel.get();
 558     }
 559 
 560     /**
 561      * The SelectionModel provides the API through which it is possible
 562      * to select single or multiple items within a TreeView, as  well as inspect
 563      * which rows have been selected by the user. Note that it has a generic
 564      * type that must match the type of the TreeView itself.
 565      * @return the selection model property
 566      */
 567     public final ObjectProperty<MultipleSelectionModel<TreeItem<T>>> selectionModelProperty() {
 568         if (selectionModel == null) {
 569             selectionModel = new SimpleObjectProperty<MultipleSelectionModel<TreeItem<T>>>(this, "selectionModel");
 570         }
 571         return selectionModel;
 572     }
 573 
 574 
 575     // --- Focus Model
 576     private ObjectProperty<FocusModel<TreeItem<T>>> focusModel;
 577 
 578     /**
 579      * Sets the {@link FocusModel} to be used in the TreeView.
 580      * @param value the {@link FocusModel} to be used
 581      */
 582     public final void setFocusModel(FocusModel<TreeItem<T>> value) {
 583         focusModelProperty().set(value);
 584     }
 585 
 586     /**
 587      * Returns the currently installed {@link FocusModel}.
 588      * @return the currently installed {@link FocusModel}
 589      */
 590     public final FocusModel<TreeItem<T>> getFocusModel() {
 591         return focusModel == null ? null : focusModel.get();
 592     }
 593 
 594     /**
 595      * The FocusModel provides the API through which it is possible
 596      * to control focus on zero or one rows of the TreeView. Generally the
 597      * default implementation should be more than sufficient.
 598      * @return the focus model property
 599      */
 600     public final ObjectProperty<FocusModel<TreeItem<T>>> focusModelProperty() {
 601         if (focusModel == null) {
 602             focusModel = new SimpleObjectProperty<FocusModel<TreeItem<T>>>(this, "focusModel");
 603         }
 604         return focusModel;
 605     }
 606 
 607 
 608     // --- Expanded node count
 609     /**
 610      * <p>Represents the number of tree nodes presently able to be visible in the
 611      * TreeView. This is essentially the count of all expanded tree items, and
 612      * their children.
 613      *
 614      * <p>For example, if just the root node is visible, the expandedItemCount will
 615      * be one. If the root had three children and the root was expanded, the value
 616      * will be four.
 617      * @since JavaFX 8.0
 618      */


 662     }
 663     /**
 664      * Specifies whether this control has cells that are a fixed height (of the
 665      * specified value). If this value is less than or equal to zero,
 666      * then all cells are individually sized and positioned. This is a slow
 667      * operation. Therefore, when performance matters and developers are not
 668      * dependent on variable cell sizes it is a good idea to set the fixed cell
 669      * size value. Generally cells are around 24px, so setting a fixed cell size
 670      * of 24 is likely to result in very little difference in visuals, but a
 671      * improvement to performance.
 672      *
 673      * <p>To set this property via CSS, use the -fx-fixed-cell-size property.
 674      * This should not be confused with the -fx-cell-size property. The difference
 675      * between these two CSS properties is that -fx-cell-size will size all
 676      * cells to the specified size, but it will not enforce that this is the
 677      * only size (thus allowing for variable cell sizes, and preventing the
 678      * performance gains from being possible). Therefore, when performance matters
 679      * use -fx-fixed-cell-size, instead of -fx-cell-size. If both properties are
 680      * specified in CSS, -fx-fixed-cell-size takes precedence.</p>
 681      *
 682      * @return the fixed cell size property
 683      * @since JavaFX 8.0
 684      */
 685     public final DoubleProperty fixedCellSizeProperty() {
 686         if (fixedCellSize == null) {
 687             fixedCellSize = new StyleableDoubleProperty(Region.USE_COMPUTED_SIZE) {
 688                 @Override public CssMetaData<TreeView<?>,Number> getCssMetaData() {
 689                     return StyleableProperties.FIXED_CELL_SIZE;
 690                 }
 691 
 692                 @Override public Object getBean() {
 693                     return TreeView.this;
 694                 }
 695 
 696                 @Override public String getName() {
 697                     return "fixedCellSize";
 698                 }
 699             };
 700         }
 701         return fixedCellSize;
 702     }
 703 
 704 
 705     // --- Editable
 706     private BooleanProperty editable;
 707     public final void setEditable(boolean value) {
 708         editableProperty().set(value);
 709     }
 710     public final boolean isEditable() {
 711         return editable == null ? false : editable.get();
 712     }
 713     /**
 714      * Specifies whether this TreeView is editable - only if the TreeView and
 715      * the TreeCells within it are both editable will a TreeCell be able to go
 716      * into their editing state.
 717      * @return the editable property
 718      */
 719     public final BooleanProperty editableProperty() {
 720         if (editable == null) {
 721             editable = new SimpleBooleanProperty(this, "editable", false);
 722         }
 723         return editable;
 724     }
 725 
 726 
 727     // --- Editing Item
 728     private ReadOnlyObjectWrapper<TreeItem<T>> editingItem;
 729 
 730     private void setEditingItem(TreeItem<T> value) {
 731         editingItemPropertyImpl().set(value);
 732     }
 733 
 734     /**
 735      * Returns the TreeItem that is currently being edited in the TreeView,
 736      * or null if no item is being edited.
 737      * @return the TreeItem that is currently being edited in the TreeView
 738      */
 739     public final TreeItem<T> getEditingItem() {
 740         return editingItem == null ? null : editingItem.get();
 741     }
 742 
 743     /**
 744      * <p>A property used to represent the TreeItem currently being edited
 745      * in the TreeView, if editing is taking place, or null if no item is being edited.
 746      *
 747      * <p>It is not possible to set the editing item, instead it is required that
 748      * you call {@link #edit(javafx.scene.control.TreeItem)}.
 749      * @return the editing item property
 750      */
 751     public final ReadOnlyObjectProperty<TreeItem<T>> editingItemProperty() {
 752         return editingItemPropertyImpl().getReadOnlyProperty();
 753     }
 754 
 755     private ReadOnlyObjectWrapper<TreeItem<T>> editingItemPropertyImpl() {
 756         if (editingItem == null) {
 757             editingItem = new ReadOnlyObjectWrapper<TreeItem<T>>(this, "editingItem");
 758         }
 759         return editingItem;
 760     }
 761 
 762 
 763     // --- On Edit Start
 764     private ObjectProperty<EventHandler<EditEvent<T>>> onEditStart;
 765 
 766     /**
 767      * Sets the {@link EventHandler} that will be called when the user begins
 768      * an edit.
 769      * @param value the {@link EventHandler} that will be called when the user
 770      * begins an edit
 771      */
 772     public final void setOnEditStart(EventHandler<EditEvent<T>> value) {
 773         onEditStartProperty().set(value);
 774     }
 775 
 776     /**
 777      * Returns the {@link EventHandler} that will be called when the user begins
 778      * an edit.
 779      * @return the {@link EventHandler} when the user begins an edit
 780      */
 781     public final EventHandler<EditEvent<T>> getOnEditStart() {
 782         return onEditStart == null ? null : onEditStart.get();
 783     }
 784 
 785     /**
 786      * This event handler will be fired when the user successfully initiates
 787      * editing.
 788      * @return the event handler when the user successfully initiates editing
 789      */
 790     public final ObjectProperty<EventHandler<EditEvent<T>>> onEditStartProperty() {
 791         if (onEditStart == null) {
 792             onEditStart = new SimpleObjectProperty<EventHandler<EditEvent<T>>>(this, "onEditStart") {
 793                 @Override protected void invalidated() {
 794                     setEventHandler(TreeView.<T>editStartEvent(), get());
 795                 }
 796             };
 797         }
 798         return onEditStart;
 799     }
 800 
 801 
 802     // --- On Edit Commit
 803     private ObjectProperty<EventHandler<EditEvent<T>>> onEditCommit;
 804 
 805     /**
 806      * Sets the {@link EventHandler} that will be called when the user commits
 807      * an edit.
 808      * @param value the {@link EventHandler} that will be called when the user
 809      * commits an edit
 810      */
 811     public final void setOnEditCommit(EventHandler<EditEvent<T>> value) {
 812         onEditCommitProperty().set(value);
 813     }
 814 
 815     /**
 816      * Returns the {@link EventHandler} that will be called when the user commits
 817      * an edit.
 818      * @return the {@link EventHandler} that will be called when the user commits
 819      * an edit
 820      */
 821     public final EventHandler<EditEvent<T>> getOnEditCommit() {
 822         return onEditCommit == null ? null : onEditCommit.get();
 823     }
 824 
 825     /**
 826      * <p>This property is used when the user performs an action that should
 827      * result in their editing input being persisted.</p>
 828      *
 829      * <p>The EventHandler in this property should not be called directly -
 830      * instead call {@link TreeCell#commitEdit(java.lang.Object)} from within
 831      * your custom TreeCell. This will handle firing this event, updating the
 832      * view, and switching out of the editing state.</p>
 833      * @return the event handler when the user performs an action that result in
 834      * their editing input being persisted
 835      */
 836     public final ObjectProperty<EventHandler<EditEvent<T>>> onEditCommitProperty() {
 837         if (onEditCommit == null) {
 838             onEditCommit = new SimpleObjectProperty<EventHandler<EditEvent<T>>>(this, "onEditCommit") {
 839                 @Override protected void invalidated() {
 840                     setEventHandler(TreeView.<T>editCommitEvent(), get());
 841                 }
 842             };
 843         }
 844         return onEditCommit;
 845     }
 846 
 847 
 848     // --- On Edit Cancel
 849     private ObjectProperty<EventHandler<EditEvent<T>>> onEditCancel;
 850 
 851     /**
 852      * Sets the {@link EventHandler} that will be called when the user cancels
 853      * an edit.
 854      * @param value the {@link EventHandler} that will be called when the user
 855      * cancels an edit
 856      */
 857     public final void setOnEditCancel(EventHandler<EditEvent<T>> value) {
 858         onEditCancelProperty().set(value);
 859     }
 860 
 861     /**
 862      * Returns the {@link EventHandler} that will be called when the user cancels
 863      * an edit.
 864      * @return the {@link EventHandler} that will be called when the user cancels
 865      * an edit
 866      */
 867     public final EventHandler<EditEvent<T>> getOnEditCancel() {
 868         return onEditCancel == null ? null : onEditCancel.get();
 869     }
 870 
 871     /**
 872      * This event handler will be fired when the user cancels editing a cell.
 873      * @return the event handler will be fired when the user cancels editing a
 874      * cell
 875      */
 876     public final ObjectProperty<EventHandler<EditEvent<T>>> onEditCancelProperty() {
 877         if (onEditCancel == null) {
 878             onEditCancel = new SimpleObjectProperty<EventHandler<EditEvent<T>>>(this, "onEditCancel") {
 879                 @Override protected void invalidated() {
 880                     setEventHandler(TreeView.<T>editCancelEvent(), get());
 881                 }
 882             };
 883         }
 884         return onEditCancel;
 885     }
 886 
 887 
 888 
 889     /***************************************************************************
 890      *                                                                         *
 891      * Public API                                                              *
 892      *                                                                         *
 893      **************************************************************************/
 894 


1196      * @since JavaFX 2.0
1197      */
1198     public static class EditEvent<T> extends Event {
1199         private static final long serialVersionUID = -4437033058917528976L;
1200 
1201         /**
1202          * Common supertype for all edit event types.
1203          * @since JavaFX 8.0
1204          */
1205         public static final EventType<?> ANY = EDIT_ANY_EVENT;
1206 
1207         private final TreeView<T> source;
1208         private final T oldValue;
1209         private final T newValue;
1210         private transient final TreeItem<T> treeItem;
1211 
1212         /**
1213          * Creates a new EditEvent instance to represent an edit event. This
1214          * event is used for {@link #EDIT_START_EVENT},
1215          * {@link #EDIT_COMMIT_EVENT} and {@link #EDIT_CANCEL_EVENT} types.
1216          * @param source the source
1217          * @param eventType the eventType
1218          * @param treeItem the treeItem
1219          * @param oldValue the oldValue
1220          * @param newValue the newValue
1221          */
1222         public EditEvent(TreeView<T> source,
1223                          EventType<? extends EditEvent> eventType,
1224                          TreeItem<T> treeItem, T oldValue, T newValue) {
1225             super(source, Event.NULL_SOURCE_TARGET, eventType);
1226             this.source = source;
1227             this.oldValue = oldValue;
1228             this.newValue = newValue;
1229             this.treeItem = treeItem;
1230         }
1231 
1232         /**
1233          * Returns the TreeView upon which the edit took place.
1234          */
1235         @Override public TreeView<T> getSource() {
1236             return source;
1237         }
1238 
1239         /**
1240          * Returns the {@link TreeItem} upon which the edit took place.
1241          * @return the {@link TreeItem} upon which the edit took place
1242          */
1243         public TreeItem<T> getTreeItem() {
1244             return treeItem;
1245         }
1246 
1247         /**
1248          * Returns the new value input into the TreeItem by the end user.
1249          * @return the new value input into the TreeItem by the end user
1250          */
1251         public T getNewValue() {
1252             return newValue;
1253         }
1254 
1255         /**
1256          * Returns the old value that existed in the TreeItem prior to the current
1257          * edit event.
1258          * @return the old value that existed in the TreeItem prior to the current
1259          * edit event
1260          */
1261         public T getOldValue() {
1262             return oldValue;
1263         }
1264     }
1265 
1266 
1267 
1268 
1269 
1270 
1271 
1272     // package for testing
1273     static class TreeViewBitSetSelectionModel<T> extends MultipleSelectionModelBase<TreeItem<T>> {
1274 
1275         /***********************************************************************
1276          *                                                                     *
1277          * Internal fields                                                     *
1278          *                                                                     *
1279          **********************************************************************/


< prev index next >