Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Copyright (c) 2010, 2024, 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;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.BooleanPropertyBase;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.ObjectPropertyBase;
import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
import javafx.event.Event;
import javafx.event.EventDispatchChain;
import javafx.event.EventHandler;
import javafx.event.EventTarget;
import javafx.event.EventType;
import javafx.scene.Node;
import com.sun.javafx.event.EventHandlerManager;
import java.util.Comparator;
import javafx.beans.property.ReadOnlyBooleanProperty;
import javafx.beans.property.ReadOnlyBooleanWrapper;
import javafx.beans.property.ReadOnlyObjectProperty;
import javafx.beans.property.ReadOnlyObjectWrapper;
import static javafx.scene.control.TreeSortMode.*;
/**
* The model for a single node supplying a hierarchy of values to a control such
* as {@link TreeView}. The model may be implemented such that values may be loaded in
* memory as they are needed.
*
* The model allows registration of listeners which will be notified as the
* number of items changes, their position or if the values themselves change.
* Note however that a TreeItem is not a Node, and therefore no visual
* events will be fired on the TreeItem. To get these events, it is necessary to
* add relevant observers to the TreeCell instances (via a custom cell factory -
* see the {@link Cell} class documentation for more details).
*
*
In the simplest case, TreeItem instances may be created in memory as such:
*
* TreeItem<String> root = new TreeItem<String>("Root Node");
* root.setExpanded(true);
* root.getChildren().addAll(
* new TreeItem<String>("Item 1"),
* new TreeItem<String>("Item 2"),
* new TreeItem<String>("Item 3")
* );
* TreeView<String> treeView = new TreeView<String>(root);
*
*
* This approach works well for simple tree structures, or when the data is not
* excessive (so that it can easily fit in memory). In situations where the size
* of the tree structure is unknown (and therefore potentially huge), there is
* the option of creating TreeItem instances on-demand in a memory-efficient way.
* To demonstrate this, the code below creates a file system browser:
*
*
* private TreeView buildFileSystemBrowser() {
* TreeItem<File> root = createNode(new File("/"));
* return new TreeView<File>(root);
* }
*
* // This method creates a TreeItem to represent the given File. It does this
* // by overriding the TreeItem.getChildren() and TreeItem.isLeaf() methods
* // anonymously, but this could be better abstracted by creating a
* // 'FileTreeItem' subclass of TreeItem. However, this is left as an exercise
* // for the reader.
* private TreeItem<File> createNode(final File f) {
* return new TreeItem<File>(f) {
* // We cache whether the File is a leaf or not. A File is a leaf if
* // it is not a directory and does not have any files contained within
* // it. We cache this as isLeaf() is called often, and doing the
* // actual check on File is expensive.
* private boolean isLeaf;
*
* // We do the children and leaf testing only once, and then set these
* // booleans to false so that we do not check again during this
* // run. A more complete implementation may need to handle more
* // dynamic file system situations (such as where a folder has files
* // added after the TreeView is shown). Again, this is left as an
* // exercise for the reader.
* private boolean isFirstTimeChildren = true;
* private boolean isFirstTimeLeaf = true;
*
* @Override public ObservableList<TreeItem<File>> getChildren() {
* if (isFirstTimeChildren) {
* isFirstTimeChildren = false;
*
* // First getChildren() call, so we actually go off and
* // determine the children of the File contained in this TreeItem.
* super.getChildren().setAll(buildChildren(this));
* }
* return super.getChildren();
* }
*
* @Override public boolean isLeaf() {
* if (isFirstTimeLeaf) {
* isFirstTimeLeaf = false;
* File f = (File) getValue();
* isLeaf = f.isFile();
* }
*
* return isLeaf;
* }
*
* private ObservableList<TreeItem<File>> buildChildren(TreeItem<File> TreeItem) {
* File f = TreeItem.getValue();
* if (f != null && f.isDirectory()) {
* File[] files = f.listFiles();
* if (files != null) {
* ObservableList<TreeItem<File>> children = FXCollections.observableArrayList();
*
* for (File childFile : files) {
* children.add(createNode(childFile));
* }
*
* return children;
* }
* }
*
* return FXCollections.emptyObservableList();
* }
* };
* }
*
* TreeItem Events
*
TreeItem supports the same event bubbling concept as elsewhere in the
* scenegraph. This means that it is not necessary to listen for events on all
* TreeItems (and this is certainly not encouraged!). A better, and far more low
* cost solution is to instead attach event listeners to the TreeView
* {@link TreeView#rootProperty() root} item. As long as there is a path between
* where the event occurs and the root TreeItem, the event will be bubbled to the
* root item.
*
*
It is important to note however that a TreeItem is not a
* Node, which means that only the event types defined in TreeItem will be
* delivered. To listen to general events (for example mouse interactions), it is
* necessary to add the necessary listeners to the {@link Cell cells} contained
* within the TreeView (by providing a {@link TreeView#cellFactoryProperty()
* cell factory}).
*
*
The TreeItem class defines a number of events, with a defined hierarchy. These
* are shown below (follow the links to learn more about each event type):
*
*
The indentation shown above signifies the relationship between event types.
* For example, all TreeItem event types have
* {@link TreeItem#treeNotificationEvent() treeNotificationEvent()} as their
* parent event type, and the branch
* {@link TreeItem#branchExpandedEvent() expand} /
* {@link TreeItem#branchCollapsedEvent() collapse} event types are both
* {@link TreeItem#treeNotificationEvent() treeNotificationEvent()}. For
* performance reasons, it is encouraged to listen
* to only the events you need to listen to. This means that it is encouraged
* that it is better to listen to, for example,
* {@link TreeItem#valueChangedEvent() TreeItem.valueChangedEvent()},
* rather than {@link TreeItem#treeNotificationEvent() TreeItem.treeNotificationEvent()}.
*
* @param The type of the {@link #getValue() value} property within TreeItem.
* @since JavaFX 2.0
* @see TreeView
*/
public class TreeItem implements EventTarget { //, Comparable> {
/* *************************************************************************
* *
* Static properties and methods *
* *
**************************************************************************/
/**
* The base EventType used to indicate that an event has occurred within a
* TreeItem. When an event occurs in a TreeItem, the event is fired to any
* listeners on the TreeItem that the event occurs, before it 'bubbles' up the
* TreeItem chain by following the TreeItem parent property. This repeats
* until a TreeItem whose parent TreeItem is null is reached At this point
* the event stops 'bubbling' and goes no further. This means that events
* that occur on a TreeItem can be relatively cheap, as a listener needs only
* be installed on the TreeView root node to be alerted of events happening
* at any point in the tree.
*
* @param The type of the value contained within the TreeItem.
* @return the base EventType when an event has occurred within a TreeItem
*/
@SuppressWarnings("unchecked")
public static EventType> treeNotificationEvent() {
return (EventType>) TREE_NOTIFICATION_EVENT;
}
private static final EventType> TREE_NOTIFICATION_EVENT
= new EventType<>(Event.ANY, "TreeNotificationEvent");
/**
* The general EventType used when the TreeItem receives a modification that
* results in the number of children being visible changes.
* This is normally achieved via one of the sub-types of this
* EventType (see {@link #branchExpandedEvent()},
* {@link #branchCollapsedEvent()} and {@link #childrenModificationEvent()}
* for the three sub-types).
*
* @param The type of the value contained within the TreeItem.
* @return The general EventType when the TreeItem receives a modification
* @since JavaFX 8.0
*/
@SuppressWarnings("unchecked")
public static EventType> expandedItemCountChangeEvent() {
return (EventType>) EXPANDED_ITEM_COUNT_CHANGE_EVENT;
}
private static final EventType> EXPANDED_ITEM_COUNT_CHANGE_EVENT
= new EventType<>(treeNotificationEvent(), "ExpandedItemCountChangeEvent");
/**
* An EventType used when the TreeItem receives a modification to its
* expanded property, such that the TreeItem is now in the expanded state.
*
* @param The type of the value contained within the TreeItem.
* @return The EventType used when the TreeItem receives a modification
*/
@SuppressWarnings("unchecked")
public static EventType> branchExpandedEvent() {
return (EventType>) BRANCH_EXPANDED_EVENT;
}
private static final EventType> BRANCH_EXPANDED_EVENT
= new EventType<>(expandedItemCountChangeEvent(), "BranchExpandedEvent");
/**
* An EventType used when the TreeItem receives a modification to its
* expanded property, such that the TreeItem is now in the collapsed state.
*
* @param The type of the value contained within the TreeItem.
* @return The EventType when the TreeItem receives a modification
*/
@SuppressWarnings("unchecked")
public static EventType> branchCollapsedEvent() {
return (EventType>) BRANCH_COLLAPSED_EVENT;
}
private static final EventType> BRANCH_COLLAPSED_EVENT
= new EventType<>(expandedItemCountChangeEvent(), "BranchCollapsedEvent");
/**
* An EventType used when the TreeItem receives a direct modification to its
* children list.
*
* @param The type of the value contained within the TreeItem.
* @return The EventType when the TreeItem receives a direct modification to
* its children list
*/
@SuppressWarnings("unchecked")
public static EventType> childrenModificationEvent() {
return (EventType>) CHILDREN_MODIFICATION_EVENT;
}
private static final EventType> CHILDREN_MODIFICATION_EVENT
= new EventType<>(expandedItemCountChangeEvent(), "ChildrenModificationEvent");
/**
* An EventType used when the TreeItem receives a modification to its
* value property.
*
* @param The type of the value contained within the TreeItem.
* @return The EventType when the TreeItem receives a modification to its
* value property
*/
@SuppressWarnings("unchecked")
public static EventType> valueChangedEvent() {
return (EventType>) VALUE_CHANGED_EVENT;
}
private static final EventType> VALUE_CHANGED_EVENT
= new EventType<>(treeNotificationEvent(), "ValueChangedEvent");
/**
* An EventType used when the TreeItem receives a modification to its
* graphic property.
*
* @param The type of the value contained within the TreeItem.
* @return The EventType when the TreeItem receives a modification to its
* graphic property
*/
@SuppressWarnings("unchecked")
public static EventType> graphicChangedEvent() {
return (EventType>) GRAPHIC_CHANGED_EVENT;
}
private static final EventType> GRAPHIC_CHANGED_EVENT
= new EventType<>(treeNotificationEvent(), "GraphicChangedEvent");
/* *************************************************************************
* *
* Constructors *
* *
**************************************************************************/
/**
* Creates an empty TreeItem.
*/
public TreeItem() {
this(null);
}
/**
* Creates a TreeItem with the value property set to the provided object.
*
* @param value The object to be stored as the value of this TreeItem.
*/
public TreeItem(final T value) {
this(value, (Node)null);
}
/**
* Creates a TreeItem with the value property set to the provided object, and
* the graphic set to the provided Node.
*
* @param value The object to be stored as the value of this TreeItem.
* @param graphic The Node to show in the TreeView next to this TreeItem.
*/
public TreeItem(final T value, final Node graphic) {
setValue(value);
setGraphic(graphic);
addEventHandler(TreeItem.