--- title: Tree order: 22 layout: page --- [[components.tree]] = [classname]#Tree# ifdef::web[] [.sampler] image:{live-demo-image}[alt="Live Demo", link="http://demo.vaadin.com/sampler/#ui/grids-and-trees/tree"] endif::web[] The [classname]#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. [classname]#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 [classname]#Tree# component is for displaying a hierarchical menu, as illustrated in <>, or for displaying file systems or hierarchical datasets. [[figure.components.tree]] .A [classname]#Tree# component as a menu image::img/tree-example1.png[width=25%, scaledwidth=50%] The data is managed in a container implementing the [interfacename]#Hierarchical# interface, such as [classname]#HierarchicalContainer# or [classname]#FilesystemContainer#. You can use [classname]#ContainerHierarchicalWrapper# to add hierarchical capability to any other container. [classname]#Tree# itself implements the interface and delegates operations to the underlying container. [source, java] ---- // 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 <> in a practical situation, with the [classname]`Tree` wrapped inside a [classname]`Panel`. [classname]`Tree` itself does not have scrollbar, but [classname]`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 [methodname]#setItemCaptionMode()#, as explained <>. [[components.tree.selection]] == Handling Selection and Clicks [classname]#Tree# is a selection component, which are described in <>. You can thereby get or set the currently selected item by the value property of the tree, that is, with [methodname]#getValue()# and [methodname]#setValue()#. When the user selects an item, the tree will receive an [classname]#ValueChangeEvent#, which you can catch with a [classname]#ValueChangeListener#. [source, Java] ---- // 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()); } }); ---- [classname]#Tree# is selectable by default; you can disallow selection with [methodname]#setSelectable(false)#. [classname]#Tree# also emits [classname]##ItemClickEvent##s 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. [source, Java] ---- 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); } }); ---- [[components.tree.expand-collapse]] == Expanding and Collapsing Items An item can have children only if the [propertyname]#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 [methodname]#setChildrenAllowed()#. Expanding an item fires an [classname]#Tree.ExpandEvent# and collapsing an [classname]#Tree.CollapseEvent#, which you can handle with respective listeners. [source, Java] ---- tree.addExpandListener(new Tree.ExpandListener() { public void nodeExpand(ExpandEvent event) { Notification.show("Expand!"); } }); ---- You can expand and collapse items programmatically with [methodname]#expandItem()# or [methodname]#expandItemRecursively()#. [source, Java] ---- // Expand all items that can be for (Object itemId: tree.getItemIds()) tree.expandItem(itemId); ---- TIP: [classname]#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 [classname]#TreeTable# or hierarchical support extension for [classname]#Grid#. [[components.tree.css]] == CSS Style Rules [source, css] ---- .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 */ ---- [[components.tree.css.itemstyles]] === Generating Item Styles You can style each tree item individually by generating a style name for them with a [interfacename]#Tree.ItemStyleGenerator#, which you assign to a tree with [methodname]#setItemStyleGenerator()#. The generator should return a style name for each item or `null`. [source, Java] ---- // 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: [source, CSS] ---- .v-tree-node-caption-disabled { color: graytext; font-style: italic; } ----