Tree

Live Demo

The Tree component allows a natural way to represent data that has hierarchical relationships. The user can drill down in the hierarchy by expanding items by clicking on the expand arrow, and likewise collapse items. Tree is a selection component that allows selecting items. It also supports drag and drop, so you can drag items to and from a tree, and drop them in the hierarchy.

A typical use of the Tree component is for displaying a hierarchical menu, as illustrated in A Tree component as a menu, or for displaying file systems or hierarchical datasets.

A Tree component as a menu

The data is managed in a container implementing the Hierarchical interface, such as HierarchicalContainer or FilesystemContainer. You can use ContainerHierarchicalWrapper to add hierarchical capability to any other container. Tree itself implements the interface and delegates operations to the underlying container.

// A menu tree
Tree menu = new Tree();

// Couple of childless root items
menu.addItem("Mercury");
menu.setChildrenAllowed("Mercury", false);
menu.addItem("Venus");
menu.setChildrenAllowed("Venus", false);

// An item with hierarchy
menu.addItem("Earth");
menu.addItem("The Moon");
menu.setChildrenAllowed("The Moon", false);
menu.setParent("The Moon", "Earth");
menu.expandItem("Earth"); // Expand programmatically
...

The result was shown in A Tree component as a menu in a practical situation, with the Tree wrapped inside a Panel. Tree itself does not have scrollbar, but Panel can be used for the purpose.

The caption of tree items is by default the item ID. You can define how the item captions are determined with setItemCaptionMode(), as explained "Selection Component Item Captions".

Handling Selection and Clicks

Tree is a selection component, which are described in "Selection Components". You can thereby get or set the currently selected item by the value property of the tree, that is, with getValue() and setValue(). When the user selects an item, the tree will receive an ValueChangeEvent, which you can catch with a ValueChangeListener.

// Handle selection changes
menu.addValueChangeListener(event -> { // Java 8
    if (event.getProperty() != null &&
        event.getProperty().getValue() != null) {
        location.setValue("The cat is in " +
            event.getProperty().getValue());
    }
});

Tree is selectable by default; you can disallow selection with setSelectable(false).

Tree also emits ItemClickEvents when items are clicked. This way you can handle item clicks also when selection is not enabled or you want special user interaction specifically on clicks.

tree.addItemClickListener(
  new ItemClickEvent.ItemClickListener() {
    public void itemClick(ItemClickEvent event) {
        // Pick only left mouse clicks
        if (event.getButton() == ItemClickEvent.BUTTON_LEFT)
            Notification.show("Left click",
                        Notification.Type.HUMANIZED_MESSAGE);
    }
  });

Expanding and Collapsing Items

An item can have children only if the childrenAllowed property is set as true. The expand indicator is shown when and only when the property is true. The property is defined in the container and can be set with setChildrenAllowed().

Expanding an item fires an Tree.ExpandEvent and collapsing an Tree.CollapseEvent, which you can handle with respective listeners.

tree.addExpandListener(new Tree.ExpandListener() {
    public void nodeExpand(ExpandEvent event) {
        Notification.show("Expand!");
    }
});

You can expand and collapse items programmatically with expandItem() or expandItemRecursively().

// Expand all items that can be
for (Object itemId: tree.getItemIds())
    tree.expandItem(itemId);
Tip
Tree itself does not support lazy loading, which makes it impractical for huge hierarchies. You can implement one kind of lazy loading by adding items in an expand listener and removing them in a collapse listener. For more proper lazy loading, you can use TreeTable or hierarchical support extension for Grid.

CSS Style Rules

.v-tree {}
  .v-tree-node {}            /* A node (item)           */
    .v-tree-node-caption {}  /* Caption of the node     */
    .v-tree-node-children {} /* Contains child nodes    */
  .v-tree-node-root {}       /* If node is a root node  */
  .v-tree-node-leaf {}       /* If node has no children */

Generating Item Styles

You can style each tree item individually by generating a style name for them with a Tree.ItemStyleGenerator, which you assign to a tree with setItemStyleGenerator(). The generator should return a style name for each item or null.

// Show all leaf nodes as disabled
tree.setItemStyleGenerator(new Tree.ItemStyleGenerator() {
    @Override
    public String getStyle(Tree source, Object itemId) {
        if (! tree.hasChildren(itemId))
            return "disabled";
        return null;
    }
});

The style names are prefixed with v-tree-node-caption-. You could thereby define the item styling as follows:

.v-tree-node-caption-disabled {
    color: graytext;
    font-style: italic;
}