You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

components-tree.asciidoc 7.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. ---
  2. title: Tree
  3. order: 26
  4. layout: page
  5. ---
  6. [[components.tree]]
  7. = Tree
  8. ifdef::web[]
  9. [.sampler]
  10. image:{live-demo-image}[alt="Live Demo", link="http://demo.vaadin.com/sampler/#ui/grids-and-trees/tree"]
  11. endif::web[]
  12. [[components.tree.overview]]
  13. == Overview
  14. The [classname]#Tree# component allows a natural way to represent data that has hierarchical relationships.
  15. The user can drill down in the hierarchy by expanding items by clicking on the expand arrow, and likewise collapse items.
  16. [classname]#Tree# is a selection component that allows selecting items.
  17. It also supports drag and drop, so you can drag items to and from a tree, and drop them in the hierarchy.
  18. A typical use of the [classname]#Tree# component is for displaying a hierarchical menu, as illustrated in <<figure.components.tree>>, or for displaying file systems or hierarchical datasets.
  19. [[figure.components.tree]]
  20. .A [classname]#Tree# component
  21. image::img/tree-basic.png[width=70%, scaledwidth=100%]
  22. [[components.tree.data]]
  23. == Binding to Data
  24. [classname]#Tree# is used by binding it to a hierarchical data provider. The data provider can be based on in-memory or back end data. For in-memory data, the [classname]#TreeDataProvider# can be used, and for loading data from a back end, you need to implement three methods from the [interfacename]#HierarchicalDataProvider# interface. Usage of both data providers is described in
  25. <<dummy/../../../framework/datamodel/datamodel-hierarchical.asciidoc#datamodel.hierarchical,"Hierarchical Data">>.
  26. The [classname]#TreeData# class can be used to build the hierarchical data structure,
  27. and it can then be passed on to [classname]#TreeDataProvider#. It is simply a hierarchical
  28. collection, that the data provider uses to populate the [classname]#Tree#.
  29. The [methodname]#setItems# method in [classname]#Tree# can be used to set the root level items. Internally
  30. an [classname]#TreeDataProvider# with [classname]#TreeData# is used.
  31. [source, java]
  32. ----
  33. // An initial planet tree
  34. Tree<String> tree = new Tree<>();
  35. TreeData<String> treeData = new TreeData<>();
  36. // Couple of childless root items
  37. treeData.addItem(null,"Mercury");
  38. treeData.addItem(null,"Venus");
  39. // Items with hierarchy
  40. treeData.addItem(null,"Earth");
  41. treeData.addItem("Earth","The Moon");
  42. inMemoryDataProvider = new TreeDataProvider<>(treeData);
  43. tree.setDataProvider(inMemoryDataProvider);
  44. tree.expand("Earth"); // Expand programmatically
  45. ----
  46. If at any time you want to modify
  47. the in-memory data in the tree, you may do it as follows:
  48. [source, java]
  49. ----
  50. // Add Mars with satellites
  51. treeData.addItem(null, "Mars");
  52. treeData.addItem("Mars", "Phobos");
  53. treeData.addItem("Mars", "Deimos");
  54. inMemoryDataProvider.refreshAll();
  55. ----
  56. The result was shown in <<figure.components.tree>>.
  57. The caption and the icon of tree items is generated by the [classname]#ItemCaptionGenerator# and the
  58. [classname]#IconGenerator#, set with [methodname]#setItemCaptionGenerator()# and [methodname]#setItemIconGenerator()# respectively.
  59. [[components.tree.selection]]
  60. == Handling Selection and Clicks
  61. [classname]#Tree# supports single selection mode, you can use [methodname]#asSingleSelect()# to access the selection
  62. object, which supports selection listeners and data binding. For more details, see link:<<dummy/../../../framework/datamodel/datamodel-selection.asciidoc#datamodel.selection,"Selecting Items">>.
  63. The [classname]#Tree# also supports the shortcut method [methodname]#addSelectionListener()#.
  64. [classname]#Tree# also emits [classname]##ItemClickEvent##s when items are clicked.
  65. This way you can handle item clicks also when you want special user interaction specifically on clicks.
  66. [source, Java]
  67. ----
  68. tree.addItemClickListener(event ->
  69. Notification.show("Click",
  70. Notification.Type.HUMANIZED_MESSAGE)
  71. );
  72. ----
  73. [[components.tree.right.clicks]]
  74. === Right-clicks
  75. Right-clicks are supported similar way via `addContextClickListener()` method
  76. [source, java]
  77. ----
  78. tree.addContextClickListener(event -> Notification.show(
  79. ((TreeContextClickEvent<Person>)event).getItem() + " Clicked")
  80. );
  81. ----
  82. [[components.tree.expandcollapse]]
  83. == Expanding and Collapsing Nodes
  84. [classname]#Tree# nodes that have children can be expanded and collapsed by either user interaction or through the server-side API:
  85. [source, java]
  86. ----
  87. // Expands a child project. If the child project is not yet
  88. // in the visible hierarchy, nothing will be shown.
  89. tree.expand(childProject);
  90. // Expands the root project. If child project now becomes
  91. // visible it is also expanded into view.
  92. tree.expand(rootProject);
  93. // Collapses the child project.
  94. tree.collapse(childProject);
  95. ----
  96. To use the server-side API with a backend data provider the [methodname]#hashCode# and [methodname]#equals# methods for the node's type must be implemented so that when the desired node is retrieved from the backend it can be correctly matched with the object passed to either [methodname]#expand# or [methodname]#collapse#.
  97. The [classname]#Tree# component supports listening to the expansion and collapsing of items in its hierarchy.
  98. The expand and collapse listeners can be added as follows:
  99. [source, java]
  100. ----
  101. tree.addExpandListener(event -> log("Item expanded: " + event.getExpandedItem()));
  102. tree.addCollapseListener(event -> log("Item collapsed: " + event.getCollapsedItem()));
  103. ----
  104. The return types of the methods `getExpandedItem` and `getCollapsedItem` are the same as the type of the [classname]#Tree# the events originated from.
  105. Note that collapse listeners will not be triggered for any expanded subtrees of the collapsed item.
  106. [[components.tree.node.collapsing]]
  107. == Prevent Node Collapsing
  108. [classname]#Tree# supports setting a callback method that can allow or prevent the user from collapsing an expanded node.
  109. It can be set with [methodname]#setItemCollapseAllowedProvider# method, that takes a [interfacename]#ItemCollapseAllowedProvider#.
  110. For nodes that cannot be collapsed, the [literal]#++collapse-disabled++# class name is applied to the expansion element
  111. Avoid doing any heavy operations in the method, since it is called for each item when it is being sent to the client.
  112. Example using a predefined set of persons that can not be collapsed:
  113. [source, java]
  114. ----
  115. Set<Person> alwaysExpanded;
  116. personTree.setItemCollapseAllowedProvider(person ->
  117. !alwaysExpanded.contains(person));
  118. ----
  119. [[components.treegrid.keyboard]]
  120. == Keyboard Navigation and Focus Handling in TreeGrid
  121. The user can navigate through rows with kbd:[Up] and kbd:[Down], collapse rows with kbd:[Left],
  122. and expand them with kbd:[Right].
  123. [[components.tree.css]]
  124. == CSS Style Rules
  125. [source, css]
  126. ----
  127. .v-tree8 {
  128. .v-tree8-scroller, .v-tree8-scroller-horizontal { }
  129. .v-tree8-tablewrapper {
  130. .v-tree8-body {
  131. .v-tree8-row,
  132. .v-tree8-stripe,
  133. .v-tree8-row-focused,
  134. .v-tree8-row-has-data {
  135. .v-tree8-expander, expanded {}
  136. .v-tree8-cell-content {}
  137. }
  138. }
  139. }
  140. }
  141. ----
  142. [[components.tree.css.itemstyles]]
  143. === Generating Item Styles
  144. You can style each tree item individually by generating a style name for them with a [interfacename]#StyleGenerator#, which you assign to a tree with [methodname]#setStyleGenerator()#.
  145. The generator should return a style name for each item or `null`.
  146. [source, Java]
  147. ----
  148. // Show all leaf nodes as disabled
  149. tree.setStyleGenerator(item -> {
  150. if (!tree.getDataProvider().hasChildren(item))
  151. return "leaf";
  152. return null;
  153. }
  154. );
  155. ----
  156. [source, css]
  157. ----
  158. .leaf .v-tree8-cell-content {
  159. background-color:green
  160. }
  161. ----