diff options
author | Marko Gronroos <magi@vaadin.com> | 2016-05-20 14:44:42 +0300 |
---|---|---|
committer | Marko Grönroos <magi@vaadin.com> | 2016-06-30 11:13:20 +0000 |
commit | 93767cf76b2fb14c65b758066c67fc8b48cc2eeb (patch) | |
tree | 958ddb8c45271e9a505280ef750ae07ebeda170f /documentation/components/components-tree.asciidoc | |
parent | edad7348bb8eba807225bfa72d4b0a4342426c71 (diff) | |
download | vaadin-framework-93767cf76b2fb14c65b758066c67fc8b48cc2eeb.tar.gz vaadin-framework-93767cf76b2fb14c65b758066c67fc8b48cc2eeb.zip |
Scaled images for print edition and fixed errors up to the beginning of layouts chapter (#19835). Also major revision of Tree, CustomField, and layouts overview.
Change-Id: I19f5e9511b83f953ce4707f324d81c2821ebb69d
Diffstat (limited to 'documentation/components/components-tree.asciidoc')
-rw-r--r-- | documentation/components/components-tree.asciidoc | 204 |
1 files changed, 135 insertions, 69 deletions
diff --git a/documentation/components/components-tree.asciidoc b/documentation/components/components-tree.asciidoc index abeb652f92..864dbac5d6 100644 --- a/documentation/components/components-tree.asciidoc +++ b/documentation/components/components-tree.asciidoc @@ -12,87 +12,153 @@ ifdef::web[] 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, such as filesystems or message threads. The -[classname]#Tree# component in Vaadin works much like the tree components of -most modern desktop user interface toolkits, for example in directory browsing. +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. -The typical use of the [classname]#Tree# component is for displaying a -hierachical menu, like a menu on the left side of the screen, as in -<<figure.components.tree>>, or for displaying filesystems or other hierarchical -datasets. The [parameter]#menu# style makes the appearance of the tree more -suitable for this purpose. +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. +[[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] ---- -final Object[][] planets = new Object[][]{ - new Object[]{"Mercury"}, - new Object[]{"Venus"}, - new Object[]{"Earth", "The Moon"}, - new Object[]{"Mars", "Phobos", "Deimos"}, - new Object[]{"Jupiter", "Io", "Europa", "Ganymedes", - "Callisto"}, - new Object[]{"Saturn", "Titan", "Tethys", "Dione", - "Rhea", "Iapetus"}, - new Object[]{"Uranus", "Miranda", "Ariel", "Umbriel", - "Titania", "Oberon"}, - new Object[]{"Neptune", "Triton", "Proteus", "Nereid", - "Larissa"}}; - -Tree tree = new Tree("The Planets and Major Moons"); - -/* Add planets as root items in the tree. */ -for (int i=0; i<planets.length; i++) { - String planet = (String) (planets[i][0]); - tree.addItem(planet); - - if (planets[i].length == 1) { - // The planet has no moons so make it a leaf. - tree.setChildrenAllowed(planet, false); - } else { - // Add children (moons) under the planets. - for (int j=1; j<planets[i].length; j++) { - String moon = (String) planets[i][j]; - - // Add the item as a regular item. - tree.addItem(moon); - - // Set it to be a child. - tree.setParent(moon, planet); - - // Make the moons look like leaves. - tree.setChildrenAllowed(moon, false); - } - - // Expand the subtree. - tree.expandItemsRecursively(planet); +// 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 <<figure.components.tree>> 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-selection#components.selection.captions, "Selection Component Item Captions">>. + +[[components.tree.selection]] +== Handling Selection and Clicks + +[classname]#Tree# is a selection component, which are described in <<components-selection#components.selection, "Selection Components">>. +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)#. -main.addComponent(tree); +[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); + } + }); ---- -<<figure.components.tree>> below shows the tree from the code example in a -practical situation. +[[components.tree.expand-collapse]] +== Expanding and Collapsing Items -[[figure.components.tree]] -.A [classname]#Tree# Component as a Menu -image::img/tree-example1.png[] +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 -You can read or set the currently selected item by the value property of the -[classname]#Tree# component, that is, with [methodname]#getValue()# and -[methodname]#setValue()#. When the user clicks an item on a tree, the tree will -receive an [classname]#ValueChangeEvent#, which you can catch with a -[classname]#ValueChangeListener#. To receive the event immediately after the -click, you need to set the tree as [classname]#setImmediate(true)#. +[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 */ +---- -The [classname]#Tree# component uses [classname]#Container# data sources much -like the [classname]#Table# component, with the addition that it also utilizes -hierarchy information maintained by a [classname]#HierarchicalContainer#. The -contained items can be of any item type supported by the container. The default -container and its [methodname]#addItem()# assume that the items are strings and -the string value is used as the item ID. +[[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; +} +---- |