diff options
author | Teemu Suo-Anttila <tsuoanttila@users.noreply.github.com> | 2017-05-02 18:26:11 +0300 |
---|---|---|
committer | Henri Sara <henri.sara@gmail.com> | 2017-05-02 18:26:11 +0300 |
commit | bb43a537e05d9d60ef82f1acac41cea6343c8cbb (patch) | |
tree | 12617ba2c0b076dbf33d4aa4399061487616e112 /uitest/src/main/java/com/vaadin/v7 | |
parent | d5c7d4b68a2befa3ec874eae8a456614d0333233 (diff) | |
download | vaadin-framework-bb43a537e05d9d60ef82f1acac41cea6343c8cbb.tar.gz vaadin-framework-bb43a537e05d9d60ef82f1acac41cea6343c8cbb.zip |
Add an initial version of Tree component (#9212)
This patch introduces a Tree component, implemented as a Composite
using TreeGrid. As initial version of the component, some functionality
of the old Tree component has been left out for now.
Partly addresses #8617
Diffstat (limited to 'uitest/src/main/java/com/vaadin/v7')
29 files changed, 2530 insertions, 0 deletions
diff --git a/uitest/src/main/java/com/vaadin/v7/tests/components/tree/CtrlShiftMultiselect.java b/uitest/src/main/java/com/vaadin/v7/tests/components/tree/CtrlShiftMultiselect.java new file mode 100644 index 0000000000..ca80a31e51 --- /dev/null +++ b/uitest/src/main/java/com/vaadin/v7/tests/components/tree/CtrlShiftMultiselect.java @@ -0,0 +1,120 @@ +package com.vaadin.v7.tests.components.tree; + +import java.util.Set; + +import com.vaadin.tests.components.TestBase; +import com.vaadin.ui.Label; +import com.vaadin.v7.data.Item; +import com.vaadin.v7.data.Property; +import com.vaadin.v7.data.Property.ValueChangeEvent; +import com.vaadin.v7.data.util.HierarchicalContainer; +import com.vaadin.v7.ui.Tree; + +public class CtrlShiftMultiselect extends TestBase { + + private final Tree tree = new Tree(); + private final Label valueLbl = new Label("No selection"); + + @Override + protected void setup() { + + getLayout().setSpacing(true); + + tree.setContainerDataSource(createContainer()); + tree.setItemCaptionPropertyId("name"); + tree.setWidth("300px"); + tree.setImmediate(true); + tree.setSelectable(true); + tree.setMultiSelect(true); + tree.expandItemsRecursively("Item 1"); + tree.expandItemsRecursively("Item 4"); + + tree.addListener(new Property.ValueChangeListener() { + @Override + public void valueChange(ValueChangeEvent event) { + if (tree.getValue() instanceof Set) { + @SuppressWarnings("unchecked") + // safe cast after instanceof check + Set<Object> itemIds = (Set<Object>) tree.getValue(); + if (itemIds.size() == 0) { + valueLbl.setValue("No selection"); + } else { + valueLbl.setValue(itemIds.toString()); + } + } else { + valueLbl.setValue(tree.getValue().toString()); + } + } + }); + + addComponent(tree); + + valueLbl.setWidth("300px"); + valueLbl.setHeight("600px"); + addComponent(valueLbl); + + } + + @Override + protected String getDescription() { + return "Add ctlr+shift multi selection in Tree"; + } + + @Override + protected Integer getTicketNumber() { + return 4259; + } + + private HierarchicalContainer createContainer() { + HierarchicalContainer cont = new HierarchicalContainer(); + cont.addContainerProperty("name", String.class, ""); + + for (int i = 0; i < 20; i++) { + Item item = cont.addItem("Item " + i); + item.getItemProperty("name").setValue("Item " + i); + cont.setChildrenAllowed("Item " + i, false); + + if (i == 1 || i == 4) { + cont.setChildrenAllowed("Item " + i, true); + } + + // Add three items to item 1 + if (i > 1 && i < 4) { + cont.setParent("Item " + i, "Item 1"); + } + + // Add 5 items to item 4 + if (i > 4 && i < 10) { + cont.setChildrenAllowed("Item " + i, true); + + if (i == 7) { + item = cont.addItem("Item 71"); + item.getItemProperty("name").setValue("Item 71"); + cont.setParent("Item 71", "Item " + i); + cont.setChildrenAllowed("Item 71", false); + + item = cont.addItem("Item 72"); + item.getItemProperty("name").setValue("Item 72"); + cont.setParent("Item 72", "Item " + i); + cont.setChildrenAllowed("Item 72", true); + + item = cont.addItem("Item 73"); + item.getItemProperty("name").setValue("Item 73"); + cont.setParent("Item 73", "Item 72"); + cont.setChildrenAllowed("Item 73", true); + + item = cont.addItem("Item 74"); + item.getItemProperty("name").setValue("Item 74"); + cont.setParent("Item 74", "Item " + i); + cont.setChildrenAllowed("Item 74", true); + } + + cont.setParent("Item " + i, "Item " + (i - 1)); + + } + } + + return cont; + } + +} diff --git a/uitest/src/main/java/com/vaadin/v7/tests/components/tree/DndTreeTargetDetails.java b/uitest/src/main/java/com/vaadin/v7/tests/components/tree/DndTreeTargetDetails.java new file mode 100644 index 0000000000..14a31e2c5a --- /dev/null +++ b/uitest/src/main/java/com/vaadin/v7/tests/components/tree/DndTreeTargetDetails.java @@ -0,0 +1,47 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.v7.tests.components.tree; + +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.table.DndTableTargetDetails; +import com.vaadin.v7.ui.Tree; + +/** + * Test UI for tree as a drop target: AbstractSelectTargetDetails should provide + * getMouseEvent() method. + * + * @author Vaadin Ltd + */ +public class DndTreeTargetDetails extends DndTableTargetDetails { + + @Override + protected void setup(VaadinRequest request) { + createSourceTable(); + + Tree target = new Tree(); + target.addStyleName("target"); + target.setWidth(100, Unit.PERCENTAGE); + target.addItem("treeItem"); + target.setDropHandler(new TestDropHandler()); + addComponent(target); + } + + @Override + protected String getTestDescription() { + return "Mouse details should be available for AbstractSelectTargetDetails DnD when tree is a target"; + } + +} diff --git a/uitest/src/main/java/com/vaadin/v7/tests/components/tree/ExpandCollapseTree.java b/uitest/src/main/java/com/vaadin/v7/tests/components/tree/ExpandCollapseTree.java new file mode 100644 index 0000000000..85765384c0 --- /dev/null +++ b/uitest/src/main/java/com/vaadin/v7/tests/components/tree/ExpandCollapseTree.java @@ -0,0 +1,120 @@ +package com.vaadin.v7.tests.components.tree; + +import java.util.Set; + +import com.vaadin.tests.components.TestBase; +import com.vaadin.ui.Label; +import com.vaadin.v7.data.Item; +import com.vaadin.v7.data.Property; +import com.vaadin.v7.data.Property.ValueChangeEvent; +import com.vaadin.v7.data.util.HierarchicalContainer; +import com.vaadin.v7.ui.Tree; + +public class ExpandCollapseTree extends TestBase { + + private final Tree tree = new Tree(); + private final Label valueLbl = new Label("No selection"); + + @Override + protected void setup() { + + getLayout().setSpacing(true); + + tree.setContainerDataSource(createContainer()); + tree.setItemCaptionPropertyId("name"); + tree.setWidth("300px"); + tree.setImmediate(true); + tree.setSelectable(true); + tree.setMultiSelect(true); + tree.expandItemsRecursively("Item 1"); + tree.expandItemsRecursively("Item 4"); + + tree.addListener(new Property.ValueChangeListener() { + @Override + public void valueChange(ValueChangeEvent event) { + if (tree.getValue() instanceof Set) { + @SuppressWarnings("unchecked") + // safe cast after instanceof check + Set<Object> itemIds = (Set<Object>) tree.getValue(); + if (itemIds.size() == 0) { + valueLbl.setValue("No selection"); + } else { + valueLbl.setValue(itemIds.toString()); + } + } else { + valueLbl.setValue(tree.getValue().toString()); + } + } + }); + + addComponent(tree); + + valueLbl.setWidth("300px"); + valueLbl.setHeight("600px"); + addComponent(valueLbl); + + } + + @Override + protected String getDescription() { + return "Test collapsing and expansion of tree nodes"; + } + + @Override + protected Integer getTicketNumber() { + return 5439; + } + + private HierarchicalContainer createContainer() { + HierarchicalContainer cont = new HierarchicalContainer(); + cont.addContainerProperty("name", String.class, ""); + + for (int i = 0; i < 20; i++) { + Item item = cont.addItem("Item " + i); + item.getItemProperty("name").setValue("Item " + i); + cont.setChildrenAllowed("Item " + i, false); + + if (i == 1 || i == 4) { + cont.setChildrenAllowed("Item " + i, true); + } + + // Add three items to item 1 + if (i > 1 && i < 4) { + cont.setParent("Item " + i, "Item 1"); + } + + // Add 5 items to item 4 + if (i > 4 && i < 10) { + cont.setChildrenAllowed("Item " + i, true); + + if (i == 7) { + item = cont.addItem("Item 71"); + item.getItemProperty("name").setValue("Item 71"); + cont.setParent("Item 71", "Item " + i); + cont.setChildrenAllowed("Item 71", false); + + item = cont.addItem("Item 72"); + item.getItemProperty("name").setValue("Item 72"); + cont.setParent("Item 72", "Item " + i); + cont.setChildrenAllowed("Item 72", true); + + item = cont.addItem("Item 73"); + item.getItemProperty("name").setValue("Item 73"); + cont.setParent("Item 73", "Item 72"); + cont.setChildrenAllowed("Item 73", true); + + item = cont.addItem("Item 74"); + item.getItemProperty("name").setValue("Item 74"); + cont.setParent("Item 74", "Item " + i); + cont.setChildrenAllowed("Item 74", true); + } + + cont.setParent("Item " + i, "Item " + (i - 1)); + + } + } + + return cont; + } + +} diff --git a/uitest/src/main/java/com/vaadin/v7/tests/components/tree/ItemStyleGenerator.java b/uitest/src/main/java/com/vaadin/v7/tests/components/tree/ItemStyleGenerator.java new file mode 100644 index 0000000000..1bd2decea6 --- /dev/null +++ b/uitest/src/main/java/com/vaadin/v7/tests/components/tree/ItemStyleGenerator.java @@ -0,0 +1,53 @@ +package com.vaadin.v7.tests.components.tree; + +import com.vaadin.tests.components.TestBase; +import com.vaadin.ui.Component; +import com.vaadin.ui.CustomLayout; +import com.vaadin.v7.ui.Tree; + +public class ItemStyleGenerator extends TestBase { + + private Component styles; + private String css = "<style type=\"text/css\">" + + ".v-tree-node-red {color: red;}" + + ".v-tree-node-green {color: green;}" + + ".v-tree-node-caption-blue {color:blue;}" // + + "</style>"; + + @Override + protected String getDescription() { + return "Item Style generator can be used to style items."; + } + + @Override + protected Integer getTicketNumber() { + return 3070; + } + + @Override + protected void setup() { + styles = new CustomLayout(css); + addComponent(styles); + + Tree tree = new Tree(); + + tree.setItemStyleGenerator(new Tree.ItemStyleGenerator() { + @Override + public String getStyle(Tree source, Object itemId) { + // simple return itemId as css style name + return itemId.toString(); + } + }); + + tree.addItem("red"); + tree.setChildrenAllowed("red", false); + tree.addItem("green"); + tree.addItem("green children"); + tree.setParent("green children", "green"); + tree.addItem("blue"); + tree.addItem("non-blue-childnode"); + tree.setParent("non-blue-childnode", "blue"); + + addComponent(tree); + } +} diff --git a/uitest/src/main/java/com/vaadin/v7/tests/components/tree/PreselectedTreeVisible.java b/uitest/src/main/java/com/vaadin/v7/tests/components/tree/PreselectedTreeVisible.java new file mode 100644 index 0000000000..efe46daf88 --- /dev/null +++ b/uitest/src/main/java/com/vaadin/v7/tests/components/tree/PreselectedTreeVisible.java @@ -0,0 +1,36 @@ +package com.vaadin.v7.tests.components.tree; + +import com.vaadin.tests.components.TestBase; +import com.vaadin.v7.ui.Tree; + +@SuppressWarnings("serial") +public class PreselectedTreeVisible extends TestBase { + + @Override + protected void setup() { + + String itemId1 = "Item 1"; + String itemId2 = "Item 2"; + + Tree tree = new Tree(); + + tree.addItem(itemId1); + tree.addItem(itemId2); + + // Removing this line causes the tree to show normally in Firefox + tree.select(itemId1); + addComponent(tree); + + } + + @Override + protected String getDescription() { + return "Tree should be visible when a item has been selected."; + } + + @Override + protected Integer getTicketNumber() { + return 5396; + } + +} diff --git a/uitest/src/main/java/com/vaadin/v7/tests/components/tree/SelectItemAfterRemove.java b/uitest/src/main/java/com/vaadin/v7/tests/components/tree/SelectItemAfterRemove.java new file mode 100644 index 0000000000..ef63ab20a5 --- /dev/null +++ b/uitest/src/main/java/com/vaadin/v7/tests/components/tree/SelectItemAfterRemove.java @@ -0,0 +1,43 @@ +package com.vaadin.v7.tests.components.tree; + +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractReindeerTestUI; +import com.vaadin.v7.event.ItemClickEvent; +import com.vaadin.v7.ui.Tree; + +public class SelectItemAfterRemove extends AbstractReindeerTestUI { + + @Override + protected void setup(VaadinRequest request) { + final Tree tree = new Tree(); + + tree.setImmediate(true); + tree.addItemClickListener(new ItemClickEvent.ItemClickListener() { + @Override + public void itemClick(ItemClickEvent event) { + + tree.removeItem(tree.getValue()); + tree.select(event.getItemId()); + } + }); + + tree.addItem("first"); + tree.addItem("second"); + tree.addItem("third"); + + tree.select("first"); + + addComponent(tree); + } + + @Override + protected String getTestDescription() { + return "Clicking on an item should select the clicked item and remove " + + "the previously selected item."; + } + + @Override + protected Integer getTicketNumber() { + return 15181; + } +} diff --git a/uitest/src/main/java/com/vaadin/v7/tests/components/tree/SimpleTree.java b/uitest/src/main/java/com/vaadin/v7/tests/components/tree/SimpleTree.java new file mode 100644 index 0000000000..49b790e85a --- /dev/null +++ b/uitest/src/main/java/com/vaadin/v7/tests/components/tree/SimpleTree.java @@ -0,0 +1,135 @@ +package com.vaadin.v7.tests.components.tree; + +import java.util.Date; + +import com.vaadin.event.Action; +import com.vaadin.server.ThemeResource; +import com.vaadin.tests.components.TestBase; +import com.vaadin.ui.Component; +import com.vaadin.v7.data.Item; +import com.vaadin.v7.data.util.HierarchicalContainer; +import com.vaadin.v7.ui.AbstractSelect; +import com.vaadin.v7.ui.AbstractSelect.ItemDescriptionGenerator; +import com.vaadin.v7.ui.Tree; + +public class SimpleTree extends TestBase implements Action.Handler { + private static final String[][] hardware = { // + { "Desktops", "Dell OptiPlex GX240", "Dell OptiPlex GX260", + "Dell OptiPlex GX280" }, + { "Monitors", "Benq T190HD", "Benq T220HD", "Benq T240HD" }, + { "Laptops", "IBM ThinkPad T40", "IBM ThinkPad T43", + "IBM ThinkPad T60" } }; + + ThemeResource notCachedFolderIconLargeOther = new ThemeResource( + "../runo/icons/16/ok.png?" + new Date().getTime()); + ThemeResource notCachedFolderIconLarge = new ThemeResource( + "../runo/icons/16/folder.png?" + new Date().getTime()); + + // Actions for the context menu + private static final Action ACTION_ADD = new Action("Add child item"); + private static final Action ACTION_DELETE = new Action("Delete"); + private static final Action[] ACTIONS = new Action[] { ACTION_ADD, + ACTION_DELETE }; + + private Tree tree; + + @Override + public void setup() { + // Create the Tree,a dd to layout + tree = new Tree("Hardware Inventory"); + addComponent(tree); + + // Contents from a (prefilled example) hierarchical container: + tree.setContainerDataSource(getHardwareContainer()); + + // Add actions (context menu) + tree.addActionHandler(this); + + // Cause valueChange immediately when the user selects + tree.setImmediate(true); + + // Set tree to show the 'name' property as caption for items + tree.setItemCaptionPropertyId("name"); + tree.setItemCaptionMode(AbstractSelect.ITEM_CAPTION_MODE_PROPERTY); + + tree.setItemIcon(9, notCachedFolderIconLargeOther, "First Choice"); + tree.setItemIcon(11, notCachedFolderIconLarge); + + tree.setItemDescriptionGenerator(new ItemDescriptionGenerator() { + @Override + public String generateDescription(Component source, Object itemId, + Object propertyId) { + if ((Integer) itemId == 3) { + return "tree item tooltip"; + } + return ""; + } + }); + + // Expand whole tree + for (Object id : tree.rootItemIds()) { + tree.expandItemsRecursively(id); + } + } + + public static HierarchicalContainer getHardwareContainer() { + Item item = null; + int itemId = 0; // Increasing numbering for itemId:s + + // Create new container + HierarchicalContainer hwContainer = new HierarchicalContainer(); + // Create containerproperty for name + hwContainer.addContainerProperty("name", String.class, null); + // Create containerproperty for icon + hwContainer.addContainerProperty("icon", ThemeResource.class, + new ThemeResource("../runo/icons/16/document.png")); + for (int i = 0; i < hardware.length; i++) { + // Add new item + item = hwContainer.addItem(itemId); + // Add name property for item + item.getItemProperty("name").setValue(hardware[i][0]); + // Allow children + hwContainer.setChildrenAllowed(itemId, true); + itemId++; + for (int j = 1; j < hardware[i].length; j++) { + if (j == 1) { + item.getItemProperty("icon").setValue( + new ThemeResource("../runo/icons/16/folder.png")); + } + + // Add child items + item = hwContainer.addItem(itemId); + item.getItemProperty("name").setValue(hardware[i][j]); + hwContainer.setParent(itemId, itemId - j); + + hwContainer.setChildrenAllowed(itemId, false); + if (j == 2) { + hwContainer.setChildrenAllowed(itemId, true); + } + + itemId++; + } + } + return hwContainer; + } + + @Override + protected String getDescription() { + return "Sample Tree for testing WAI-ARIA functionality"; + } + + @Override + protected Integer getTicketNumber() { + return 0; + } + + @Override + public Action[] getActions(Object target, Object sender) { + return ACTIONS; + } + + @Override + public void handleAction(Action action, Object sender, Object target) { + System.out.println("Action: " + action.getCaption()); + } +} diff --git a/uitest/src/main/java/com/vaadin/v7/tests/components/tree/TreeConnectors.java b/uitest/src/main/java/com/vaadin/v7/tests/components/tree/TreeConnectors.java new file mode 100644 index 0000000000..e44d89fd88 --- /dev/null +++ b/uitest/src/main/java/com/vaadin/v7/tests/components/tree/TreeConnectors.java @@ -0,0 +1,135 @@ +package com.vaadin.v7.tests.components.tree; + +import com.vaadin.event.dd.DragAndDropEvent; +import com.vaadin.event.dd.DropHandler; +import com.vaadin.event.dd.acceptcriteria.AcceptAll; +import com.vaadin.event.dd.acceptcriteria.AcceptCriterion; +import com.vaadin.server.ThemeResource; +import com.vaadin.tests.components.TestBase; +import com.vaadin.ui.CheckBox; +import com.vaadin.v7.data.Item; +import com.vaadin.v7.data.util.HierarchicalContainer; +import com.vaadin.v7.ui.Tree; +import com.vaadin.v7.ui.Tree.TreeDragMode; +import com.vaadin.v7.ui.themes.BaseTheme; + +@SuppressWarnings("serial") +public class TreeConnectors extends TestBase { + + private Tree tree = createTree(); + + @Override + protected void setup() { + CheckBox cb = new CheckBox("Connectors"); + cb.setValue(false); + cb.addValueChangeListener(event -> { + if (event.getValue()) { + tree.addStyleName(BaseTheme.TREE_CONNECTORS); + } else { + tree.removeStyleName(BaseTheme.TREE_CONNECTORS); + } + }); + addComponent(cb); + addComponent(tree); + } + + private Tree createTree() { + final Tree tree = new Tree(null, createContainer()); + tree.setWidth("300px"); + for (Object rootItems : tree.rootItemIds()) { + tree.expandItemsRecursively(rootItems); + } + tree.setChildrenAllowed("Item 73", false); + + tree.setDragMode(TreeDragMode.NODE); + tree.setDropHandler(new DropHandler() { + + @Override + public void drop(DragAndDropEvent event) { + // TODO Auto-generated method stub + + } + + @Override + public AcceptCriterion getAcceptCriterion() { + return AcceptAll.get(); + } + + }); + + tree.setItemIcon("Item 1", + new ThemeResource("../runo/icons/32/folder.png")); + tree.setItemIcon("Item 3", + new ThemeResource("../runo/icons/32/document.png")); + tree.setItemIcon("Item 13", + new ThemeResource("../runo/icons/64/user.png")); + tree.setItemIcon("Item 72", + new ThemeResource("../runo/icons/64/users.png")); + tree.setItemIcon("Item 17", + new ThemeResource("../runo/icons/16/document-pdf.png")); + + return tree; + } + + @Override + protected String getDescription() { + return "The second tree's nodes should be connected with lines indicating the hierarchy. The first tree should be without connectors."; + } + + @Override + protected Integer getTicketNumber() { + return 6745; + } + + private HierarchicalContainer createContainer() { + HierarchicalContainer cont = new HierarchicalContainer(); + cont.addContainerProperty("name", String.class, ""); + + for (int i = 0; i < 20; i++) { + Item item = cont.addItem("Item " + i); + item.getItemProperty("name").setValue("Item " + i); + cont.setChildrenAllowed("Item " + i, false); + + if (i == 1 || i == 4) { + cont.setChildrenAllowed("Item " + i, true); + } + + // Add three items to item 1 + if (i > 1 && i < 4) { + cont.setParent("Item " + i, "Item 1"); + } + + // Add 5 items to item 4 + if (i > 4 && i < 10) { + cont.setChildrenAllowed("Item " + i, true); + + if (i == 7) { + item = cont.addItem("Item 71"); + item.getItemProperty("name").setValue("Item 71"); + cont.setParent("Item 71", "Item " + i); + cont.setChildrenAllowed("Item 71", false); + + item = cont.addItem("Item 72"); + item.getItemProperty("name").setValue("Item 72"); + cont.setParent("Item 72", "Item " + i); + cont.setChildrenAllowed("Item 72", true); + + item = cont.addItem("Item 73"); + item.getItemProperty("name").setValue("Item 73"); + cont.setParent("Item 73", "Item 72"); + cont.setChildrenAllowed("Item 73", true); + + item = cont.addItem("Item 74"); + item.getItemProperty("name").setValue("Item 74"); + cont.setParent("Item 74", "Item " + i); + cont.setChildrenAllowed("Item 74", true); + } + + cont.setParent("Item " + i, "Item " + (i - 1)); + + } + } + + return cont; + } +} diff --git a/uitest/src/main/java/com/vaadin/v7/tests/components/tree/TreeContainerChange.java b/uitest/src/main/java/com/vaadin/v7/tests/components/tree/TreeContainerChange.java new file mode 100644 index 0000000000..6d9de4c412 --- /dev/null +++ b/uitest/src/main/java/com/vaadin/v7/tests/components/tree/TreeContainerChange.java @@ -0,0 +1,105 @@ +package com.vaadin.v7.tests.components.tree; + +import com.vaadin.tests.components.TestBase; +import com.vaadin.ui.Button; +import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.HorizontalLayout; +import com.vaadin.ui.Label; +import com.vaadin.v7.data.Property; +import com.vaadin.v7.data.Property.ValueChangeEvent; +import com.vaadin.v7.data.util.IndexedContainer; +import com.vaadin.v7.ui.Table; +import com.vaadin.v7.ui.Tree; + +@SuppressWarnings("serial") +public class TreeContainerChange extends TestBase { + + private Tree tree; + + @Override + protected void setup() { + final IndexedContainer ds1 = new IndexedContainer(); + // ds1.addContainerProperty("caption", String.class, ""); + for (int i = 0; i < 32; i++) { + ds1.addItem("ds1-" + i); + } + + final IndexedContainer ds2 = new IndexedContainer(); + // ds2.addContainerProperty("caption", String.class, ""); + for (int i = 0; i < 32; i++) { + ds2.addItem("ds2-" + i); + } + + HorizontalLayout hl = new HorizontalLayout(); + hl.setWidth("100%"); + + tree = new Tree(); + tree.setImmediate(true); + hl.addComponent(tree); + HorizontalLayout state = new HorizontalLayout(); + state.setSpacing(true); + hl.addComponent(state); + + final Label currentValue = new Label(); + currentValue.setCaption("Current Value:"); + currentValue.setSizeUndefined(); + final Label currentDS = new Label(); + currentDS.setCaption("Current DS:"); + currentDS.setSizeUndefined(); + state.addComponent(currentValue); + state.addComponent(currentDS); + + Table t = new Table("ds1"); + t.setRowHeaderMode(Table.ROW_HEADER_MODE_ID); + t.setContainerDataSource(ds1); + state.addComponent(t); + + Button b = new Button("Use ds1"); + b.addClickListener(new Button.ClickListener() { + + @Override + public void buttonClick(ClickEvent event) { + tree.setContainerDataSource(ds1); + currentDS.setValue("ds1"); + } + }); + state.addComponent(b); + + t = new Table("ds2"); + t.setContainerDataSource(ds2); + t.setRowHeaderMode(Table.ROW_HEADER_MODE_ID); + state.addComponent(t); + + b = new Button("Use ds2"); + b.addClickListener(new Button.ClickListener() { + + @Override + public void buttonClick(ClickEvent event) { + tree.setContainerDataSource(ds2); + currentDS.setValue("ds2"); + } + }); + state.addComponent(b); + + addComponent(hl); + + tree.addListener(new Property.ValueChangeListener() { + @Override + public void valueChange(ValueChangeEvent event) { + currentValue + .setValue(event.getProperty().getValue().toString()); + } + }); + } + + @Override + protected String getDescription() { + return "A test for tree and its container changes. Value should be cleared on container change."; + } + + @Override + protected Integer getTicketNumber() { + return 5281; + } + +} diff --git a/uitest/src/main/java/com/vaadin/v7/tests/components/tree/TreeDragAndDropFromTable.java b/uitest/src/main/java/com/vaadin/v7/tests/components/tree/TreeDragAndDropFromTable.java new file mode 100644 index 0000000000..90110d39f6 --- /dev/null +++ b/uitest/src/main/java/com/vaadin/v7/tests/components/tree/TreeDragAndDropFromTable.java @@ -0,0 +1,120 @@ +package com.vaadin.v7.tests.components.tree; + +import com.vaadin.event.dd.DragAndDropEvent; +import com.vaadin.event.dd.DropHandler; +import com.vaadin.event.dd.acceptcriteria.AcceptCriterion; +import com.vaadin.tests.components.TestBase; +import com.vaadin.ui.HorizontalLayout; +import com.vaadin.v7.data.Container; +import com.vaadin.v7.event.DataBoundTransferable; +import com.vaadin.v7.ui.AbstractSelect.AbstractSelectTargetDetails; +import com.vaadin.v7.ui.Table; +import com.vaadin.v7.ui.Table.TableDragMode; +import com.vaadin.v7.ui.Tree; +import com.vaadin.v7.ui.Tree.TargetItemAllowsChildren; + +public class TreeDragAndDropFromTable extends TestBase { + + @Override + protected void setup() { + + HorizontalLayout h = new HorizontalLayout(); + addComponent(h); + + Table table = new Table(); + table.addContainerProperty("Column 1", String.class, "Row"); + table.setDragMode(TableDragMode.ROW); + + table.addItem("Row 1"); + table.addItem("Row 2"); + table.addItem("Row 3"); + table.addItem("Row 4"); + table.addItem("Row 5"); + table.addItem("Row 6"); + table.addItem("Row 7"); + + h.addComponent(table); + + final Tree tree = new Tree(); + tree.setDropHandler(new DropHandler() { + + @Override + public AcceptCriterion getAcceptCriterion() { + return TargetItemAllowsChildren.get(); + } + + @Override + public void drop(DragAndDropEvent dropEvent) { + // criteria verify that this is safe + DataBoundTransferable t = (DataBoundTransferable) dropEvent + .getTransferable(); + Container sourceContainer = t.getSourceContainer(); + Object sourceItemId = t.getItemId(); + System.out.println(sourceItemId); + + AbstractSelectTargetDetails dropData = ((AbstractSelectTargetDetails) dropEvent + .getTargetDetails()); + Object targetItemId = dropData.getItemIdOver(); + + // move item from table to category' + tree.addItem(sourceItemId); + tree.setParent(sourceItemId, targetItemId); + tree.setChildrenAllowed(sourceItemId, false); + sourceContainer.removeItem(sourceItemId); + + } + }); + + tree.addItem("Item 1"); + tree.addItem("Item 11"); + tree.setChildrenAllowed("Item 11", false); + tree.setParent("Item 11", "Item 1"); + tree.addItem("Item 12"); + tree.setChildrenAllowed("Item 12", false); + tree.setParent("Item 12", "Item 1"); + tree.addItem("Item 13"); + tree.setChildrenAllowed("Item 13", false); + tree.setParent("Item 13", "Item 1"); + + tree.addItem("Item 2"); + tree.addItem("Item 21"); + tree.setChildrenAllowed("Item 21", false); + tree.setParent("Item 21", "Item 2"); + tree.addItem("Item 22"); + tree.setChildrenAllowed("Item 22", false); + tree.setParent("Item 22", "Item 2"); + tree.addItem("Item 23"); + tree.setChildrenAllowed("Item 23", false); + tree.setParent("Item 23", "Item 2"); + + tree.addItem("Item 3"); + tree.addItem("Item 31"); + tree.setChildrenAllowed("Item 31", false); + tree.setParent("Item 31", "Item 3"); + tree.addItem("Item 32"); + tree.setChildrenAllowed("Item 32", false); + tree.setParent("Item 32", "Item 3"); + tree.addItem("Item 33"); + tree.setChildrenAllowed("Item 33", false); + tree.setParent("Item 33", "Item 3"); + + tree.expandItemsRecursively("Item 1"); + tree.expandItemsRecursively("Item 2"); + tree.expandItemsRecursively("Item 3"); + + h.addComponent(tree); + } + + @Override + protected String getDescription() { + return "Test that childred can be dragged " + + "from the Table to the tree and that TargetItemAllowsChildren limits " + + "the drops to nodes which allows children"; + } + + @Override + protected Integer getTicketNumber() { + return 7687; + } + +} diff --git a/uitest/src/main/java/com/vaadin/v7/tests/components/tree/TreeFiltering.java b/uitest/src/main/java/com/vaadin/v7/tests/components/tree/TreeFiltering.java new file mode 100644 index 0000000000..e4a39494d1 --- /dev/null +++ b/uitest/src/main/java/com/vaadin/v7/tests/components/tree/TreeFiltering.java @@ -0,0 +1,126 @@ +package com.vaadin.v7.tests.components.tree; + +import com.vaadin.tests.components.TestBase; +import com.vaadin.ui.Button; +import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.Button.ClickListener; +import com.vaadin.ui.CheckBox; +import com.vaadin.v7.data.Item; +import com.vaadin.v7.data.util.HierarchicalContainer; +import com.vaadin.v7.ui.Tree; + +public class TreeFiltering extends TestBase { + + @Override + public void setup() { + + final Tree ccTree = new Tree(); + addComponent(ccTree); + final HierarchicalContainer cont = new HierarchicalContainer(); + cont.addContainerProperty("caption", String.class, ""); + + Item item; + for (int i = 0; i < 5; i++) { + item = cont.addItem(i); + item.getItemProperty("caption").setValue("Number " + i); + cont.setParent(i, i - 1); + } + + for (int i = 0; i < 5; i++) { + Object id = cont.addItem(); + item = cont.getItem(id); + item.getItemProperty("caption").setValue("0-" + i); + cont.setParent(id, 0); + } + + ccTree.setContainerDataSource(cont); + ccTree.setItemCaptionPropertyId("caption"); + + for (final Object o : ccTree.getItemIds()) { + ccTree.expandItem(o); + } + + final CheckBox filterType = new CheckBox( + "Include parent when filtering", true); + filterType.addValueChangeListener(event -> { + cont.setIncludeParentsWhenFiltering(event.getValue()); + ccTree.markAsDirty(); + }); + addComponent(filterType); + + final Button b = new Button("Add filter 'foo'", new ClickListener() { + @Override + public void buttonClick(final ClickEvent event) { + cont.addContainerFilter("caption", "foo", true, false); + + } + }); + addComponent(b); + final Button b2 = new Button("Add filter 'Num'", new ClickListener() { + @Override + public void buttonClick(final ClickEvent event) { + cont.addContainerFilter("caption", "Num", true, false); + + } + }); + + addComponent(b2); + final Button num = new Button("Add filter '0'", new ClickListener() { + @Override + public void buttonClick(final ClickEvent event) { + cont.addContainerFilter("caption", "0", true, false); + + } + }); + + addComponent(num); + final Button num2 = new Button("Add filter '0-'", new ClickListener() { + @Override + public void buttonClick(final ClickEvent event) { + cont.addContainerFilter("caption", "0-", true, false); + + } + }); + + addComponent(num2); + final Button num3 = new Button("Add filter 'Number 4'", + new ClickListener() { + @Override + public void buttonClick(final ClickEvent event) { + cont.addContainerFilter("caption", "Number 4", true, + false); + + } + }); + + addComponent(num3); + final Button p1 = new Button("Set Number 3 parent to Number 0", + new ClickListener() { + @Override + public void buttonClick(final ClickEvent event) { + cont.setParent(3, 0); + + } + }); + addComponent(p1); + final Button r = new Button("Remove filters", new ClickListener() { + @Override + public void buttonClick(final ClickEvent event) { + cont.removeAllContainerFilters(); + + } + }); + addComponent(r); + } + + @Override + protected String getDescription() { + return "Filtering in a tree should work as expected. Roots and their children which match the filter should be shown. Other nodes should be hidden"; + } + + @Override + protected Integer getTicketNumber() { + return 4192; + } + +} diff --git a/uitest/src/main/java/com/vaadin/v7/tests/components/tree/TreeFocusGaining.java b/uitest/src/main/java/com/vaadin/v7/tests/components/tree/TreeFocusGaining.java new file mode 100644 index 0000000000..9dcc21d6dd --- /dev/null +++ b/uitest/src/main/java/com/vaadin/v7/tests/components/tree/TreeFocusGaining.java @@ -0,0 +1,65 @@ +package com.vaadin.v7.tests.components.tree; + +import com.vaadin.tests.components.TestBase; +import com.vaadin.tests.util.Log; +import com.vaadin.v7.data.Property; +import com.vaadin.v7.data.Property.ValueChangeEvent; +import com.vaadin.v7.event.ItemClickEvent; +import com.vaadin.v7.ui.TextField; +import com.vaadin.v7.ui.Tree; + +@SuppressWarnings("serial") +public class TreeFocusGaining extends TestBase { + + @Override + protected void setup() { + final Log log = new Log(5); + + TextField textField = new TextField( + "My value should get to server when tree is clicked"); + addComponent(textField); + textField.addListener(new Property.ValueChangeListener() { + + @Override + public void valueChange(ValueChangeEvent event) { + log.log("TF value now:" + event.getProperty().getValue()); + } + }); + + Tree tree = new Tree("Simple selectable tree (immediate)"); + tree.addItem("Item1"); + addComponent(tree); + tree.addListener(new Property.ValueChangeListener() { + + @Override + public void valueChange(ValueChangeEvent event) { + log.log("Tree value now:" + event.getProperty().getValue()); + } + }); + tree.setImmediate(true); + + tree = new Tree("Simple tree with itemm click listener"); + tree.addItem("Item1"); + tree.addListener(new ItemClickEvent.ItemClickListener() { + @Override + public void itemClick(ItemClickEvent event) { + log.log("Item click event"); + } + }); + addComponent(tree); + + addComponent(log); + + } + + @Override + protected String getDescription() { + return "Tree should get focus before sending variables to server."; + } + + @Override + protected Integer getTicketNumber() { + return 6374; + } + +} diff --git a/uitest/src/main/java/com/vaadin/v7/tests/components/tree/TreeHorizontalResize.java b/uitest/src/main/java/com/vaadin/v7/tests/components/tree/TreeHorizontalResize.java new file mode 100644 index 0000000000..cb948b789e --- /dev/null +++ b/uitest/src/main/java/com/vaadin/v7/tests/components/tree/TreeHorizontalResize.java @@ -0,0 +1,90 @@ +package com.vaadin.v7.tests.components.tree; + +import java.util.Iterator; + +import com.vaadin.server.ThemeResource; +import com.vaadin.tests.components.TestBase; +import com.vaadin.ui.Panel; +import com.vaadin.ui.VerticalLayout; +import com.vaadin.v7.data.Item; +import com.vaadin.v7.data.util.HierarchicalContainer; +import com.vaadin.v7.ui.Tree; + +public class TreeHorizontalResize extends TestBase { + + // copied from Sampler to eliminate dependency + public static final Object hw_PROPERTY_NAME = "name"; + public static final Object hw_PROPERTY_ICON = "icon"; + private static final String[][] hardware = { // + { "Desktops", "Dell OptiPlex GX240", "Dell OptiPlex GX260", + "Dell OptiPlex GX280" }, + { "Monitors", "Benq T190HD", "Benq T220HD", "Benq T240HD" }, + { "Laptops", "IBM ThinkPad T40", "IBM ThinkPad T43", + "IBM ThinkPad T60" } }; + + @Override + protected void setup() { + VerticalLayout treeLayout = new VerticalLayout(); + treeLayout.setMargin(true); + treeLayout.setSizeUndefined(); + Panel treePanel = new Panel(treeLayout); + treePanel.setHeight("500px"); + treePanel.setWidth(null); + addComponent(treePanel); + + Tree tree = new Tree(); + tree.setContainerDataSource(getHardwareContainer()); + tree.setItemCaptionPropertyId(hw_PROPERTY_NAME); + for (Iterator<?> it = tree.rootItemIds().iterator(); it.hasNext();) { + tree.expandItemsRecursively(it.next()); + } + treeLayout.addComponent(tree); + } + + @Override + protected String getDescription() { + return "The Tree should be properly resized horizontally when collapsing/expanding nodes. The height is fixed to 500px."; + } + + @Override + protected Integer getTicketNumber() { + return 6230; + } + + public static HierarchicalContainer getHardwareContainer() { + Item item = null; + int itemId = 0; // Increasing numbering for itemId:s + + // Create new container + HierarchicalContainer hwContainer = new HierarchicalContainer(); + // Create containerproperty for name + hwContainer.addContainerProperty(hw_PROPERTY_NAME, String.class, null); + // Create containerproperty for icon + hwContainer.addContainerProperty(hw_PROPERTY_ICON, ThemeResource.class, + new ThemeResource("../runo/icons/16/document.png")); + for (int i = 0; i < hardware.length; i++) { + // Add new item + item = hwContainer.addItem(itemId); + // Add name property for item + item.getItemProperty(hw_PROPERTY_NAME).setValue(hardware[i][0]); + // Allow children + hwContainer.setChildrenAllowed(itemId, true); + itemId++; + for (int j = 1; j < hardware[i].length; j++) { + if (j == 1) { + item.getItemProperty(hw_PROPERTY_ICON).setValue( + new ThemeResource("../runo/icons/16/folder.png")); + } + // Add child items + item = hwContainer.addItem(itemId); + item.getItemProperty(hw_PROPERTY_NAME).setValue(hardware[i][j]); + hwContainer.setParent(itemId, itemId - j); + hwContainer.setChildrenAllowed(itemId, false); + + itemId++; + } + } + return hwContainer; + } + +} diff --git a/uitest/src/main/java/com/vaadin/v7/tests/components/tree/TreeHtmlContentAllowed.java b/uitest/src/main/java/com/vaadin/v7/tests/components/tree/TreeHtmlContentAllowed.java new file mode 100644 index 0000000000..8b5ceaab27 --- /dev/null +++ b/uitest/src/main/java/com/vaadin/v7/tests/components/tree/TreeHtmlContentAllowed.java @@ -0,0 +1,54 @@ +/* + * Copyright 2000-2016 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.v7.tests.components.tree; + +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractReindeerTestUI; +import com.vaadin.ui.CheckBox; +import com.vaadin.v7.ui.Tree; + +public class TreeHtmlContentAllowed extends AbstractReindeerTestUI { + + @Override + protected void setup(VaadinRequest request) { + String textParent = "Just text"; + String htmlParent = "Some <b>html</b>"; + String textChild = "Child text"; + String htmlChild = "Child <i>html</i>"; + String htmlElementChild = "Child <span id='my-html-element'>element html</span>"; + + final Tree tree = new Tree("A tree"); + tree.addItem(textParent); + tree.addItem(htmlParent); + tree.addItem(textChild); + tree.addItem(htmlChild); + tree.addItem(htmlElementChild); + tree.setParent(textChild, textParent); + tree.setParent(htmlChild, htmlParent); + + tree.setChildrenAllowed(textChild, false); + tree.setChildrenAllowed(htmlChild, false); + tree.setChildrenAllowed(htmlElementChild, false); + + final CheckBox toggle = new CheckBox("HTML content allowed", + tree.isHtmlContentAllowed()); + toggle.addValueChangeListener(event -> tree + .setHtmlContentAllowed(toggle.getValue().booleanValue())); + + addComponents(tree, toggle); + } + +} diff --git a/uitest/src/main/java/com/vaadin/v7/tests/components/tree/TreeIconUpdate.java b/uitest/src/main/java/com/vaadin/v7/tests/components/tree/TreeIconUpdate.java new file mode 100644 index 0000000000..fc8f6c5726 --- /dev/null +++ b/uitest/src/main/java/com/vaadin/v7/tests/components/tree/TreeIconUpdate.java @@ -0,0 +1,73 @@ +package com.vaadin.v7.tests.components.tree; + +import com.vaadin.server.Resource; +import com.vaadin.server.ThemeResource; +import com.vaadin.tests.components.TestBase; +import com.vaadin.ui.Button; +import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.Button.ClickListener; +import com.vaadin.v7.data.Item; +import com.vaadin.v7.data.util.HierarchicalContainer; +import com.vaadin.v7.ui.Tree; + +public class TreeIconUpdate extends TestBase { + + private static final Resource ICON1 = new ThemeResource( + "../runo/icons/16/folder.png"); + private static final Resource ICON2 = new ThemeResource( + "../runo/icons/16/ok.png"); + + @Override + protected void setup() { + HierarchicalContainer container = new HierarchicalContainer(); + container.addContainerProperty("name", String.class, null); + container.addContainerProperty("icon", Resource.class, null); + final Tree tree = new Tree(); + tree.setContainerDataSource(container); + tree.setItemIconPropertyId("icon"); + tree.setItemCaptionPropertyId("name"); + + for (int i = 0; i < 20; i++) { + Item bar = container.addItem("bar" + i); + bar.getItemProperty("name").setValue("Bar" + i); + bar.getItemProperty("icon").setValue(ICON1); + + if (i > 3) { + container.setParent("bar" + i, "bar" + (i - 1)); + } + } + + addComponent(tree); + + Button button = new Button("Change icon", new ClickListener() { + + @Override + public void buttonClick(ClickEvent event) { + tree.getItem("bar0").getItemProperty("icon").setValue(ICON2); + } + }); + + addComponent(button); + button = new Button("Change caption", new ClickListener() { + + @Override + public void buttonClick(ClickEvent event) { + tree.getItem("bar0").getItemProperty("name").setValue("foo"); + } + }); + + addComponent(button); + + } + + @Override + protected String getDescription() { + return "Click the button to change the icon. The tree should be updated"; + } + + @Override + protected Integer getTicketNumber() { + return 9663; + } + +} diff --git a/uitest/src/main/java/com/vaadin/v7/tests/components/tree/TreeItemClickListening.java b/uitest/src/main/java/com/vaadin/v7/tests/components/tree/TreeItemClickListening.java new file mode 100644 index 0000000000..8ba84d84db --- /dev/null +++ b/uitest/src/main/java/com/vaadin/v7/tests/components/tree/TreeItemClickListening.java @@ -0,0 +1,55 @@ +package com.vaadin.v7.tests.components.tree; + +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUIWithLog; +import com.vaadin.v7.event.ItemClickEvent; +import com.vaadin.v7.ui.Tree; + +public class TreeItemClickListening extends AbstractTestUIWithLog { + + private int clickCounter = 0; + + @Override + protected void setup(VaadinRequest request) { + + Tree tree = new Tree(); + tree.setImmediate(true); + + tree.addContainerProperty("caption", String.class, ""); + for (int i = 1; i <= 2; i++) { + String item = "Node " + i; + tree.addItem(item); + tree.getContainerProperty(item, "caption").setValue("Caption " + i); + tree.setChildrenAllowed(item, false); + } + tree.setItemCaptionMode(Tree.ITEM_CAPTION_MODE_PROPERTY); + tree.setItemCaptionPropertyId("caption"); + + tree.addListener(new ItemClickEvent.ItemClickListener() { + @Override + public void itemClick(ItemClickEvent event) { + clickCounter++; + switch (event.getButton()) { + case LEFT: + log.log("Left Click"); + break; + case RIGHT: + log.log("Right Click"); + break; + } + } + }); + + addComponent(tree); + } + + @Override + protected String getTestDescription() { + return "Item click event should be triggered from all mouse button clicks"; + } + + @Override + protected Integer getTicketNumber() { + return 6845; + } +} diff --git a/uitest/src/main/java/com/vaadin/v7/tests/components/tree/TreeItemDoubleClick.java b/uitest/src/main/java/com/vaadin/v7/tests/components/tree/TreeItemDoubleClick.java new file mode 100644 index 0000000000..490e857a09 --- /dev/null +++ b/uitest/src/main/java/com/vaadin/v7/tests/components/tree/TreeItemDoubleClick.java @@ -0,0 +1,58 @@ +package com.vaadin.v7.tests.components.tree; + +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUIWithLog; +import com.vaadin.ui.Button; +import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.v7.event.ItemClickEvent; +import com.vaadin.v7.ui.Tree; + +public class TreeItemDoubleClick extends AbstractTestUIWithLog { + + @Override + protected void setup(VaadinRequest request) { + final Tree tree = new Tree("Immediate With ItemClickListener"); + tree.setImmediate(true); + tree.setNullSelectionAllowed(false); + + for (int i = 1; i < 6; i++) { + tree.addItem("Tree Item " + i); + } + + ItemClickEvent.ItemClickListener listener = new ItemClickEvent.ItemClickListener() { + @Override + public void itemClick(ItemClickEvent event) { + if (event.isDoubleClick()) { + log.log("Double Click " + event.getItemId()); + } + } + }; + + tree.addItemClickListener(listener); + + addComponent(tree); + + addButton("Change immediate flag", new Button.ClickListener() { + + @Override + public void buttonClick(ClickEvent event) { + // this wouldn't work if tree had a value change listener + tree.setImmediate(!tree.isImmediate()); + log.log("tree.isImmediate() is now " + tree.isImmediate()); + } + + }); + + } + + @Override + protected String getTestDescription() { + return "Tests that double click is fired"; + } + + @Override + protected Integer getTicketNumber() { + return 14745; + } + +} diff --git a/uitest/src/main/java/com/vaadin/v7/tests/components/tree/TreeItemSelectionWithoutImmediate.java b/uitest/src/main/java/com/vaadin/v7/tests/components/tree/TreeItemSelectionWithoutImmediate.java new file mode 100644 index 0000000000..98c9a8364a --- /dev/null +++ b/uitest/src/main/java/com/vaadin/v7/tests/components/tree/TreeItemSelectionWithoutImmediate.java @@ -0,0 +1,46 @@ +package com.vaadin.v7.tests.components.tree; + +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUIWithLog; +import com.vaadin.v7.event.ItemClickEvent; +import com.vaadin.v7.ui.Tree; + +@SuppressWarnings("serial") +public class TreeItemSelectionWithoutImmediate extends AbstractTestUIWithLog { + + protected static final String TREE_ID = "TreeId"; + + protected static final String MENU_ITEM_TEMPLATE = "Menu Item %d"; + + @Override + protected void setup(VaadinRequest request) { + Tree tree = new Tree("With ItemClickListener not Immediate"); + tree.setId(TREE_ID); + tree.setImmediate(false); + + for (int i = 1; i <= 4; i++) { + tree.addItem(String.format(MENU_ITEM_TEMPLATE, i)); + } + + tree.addItemClickListener(new ItemClickEvent.ItemClickListener() { + + @Override + public void itemClick(ItemClickEvent event) { + log("ItemClickEvent = " + event.getItemId()); + } + }); + + addComponent(tree); + } + + @Override + protected String getTestDescription() { + return "Test for ensuring that selection of tree items works correctly if immediate == false " + + "and ItemClickListener is added to Tree"; + } + + @Override + protected Integer getTicketNumber() { + return 14388; + } +} diff --git a/uitest/src/main/java/com/vaadin/v7/tests/components/tree/TreeKeyboardNavigationScrolls.java b/uitest/src/main/java/com/vaadin/v7/tests/components/tree/TreeKeyboardNavigationScrolls.java new file mode 100644 index 0000000000..e6fc574c4e --- /dev/null +++ b/uitest/src/main/java/com/vaadin/v7/tests/components/tree/TreeKeyboardNavigationScrolls.java @@ -0,0 +1,66 @@ +/* + * Copyright 2000-2016 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.v7.tests.components.tree; + +import com.vaadin.tests.components.TestBase; +import com.vaadin.tests.util.AlwaysFailValidator; +import com.vaadin.v7.data.Container; +import com.vaadin.v7.data.util.HierarchicalContainer; +import com.vaadin.v7.ui.Tree; + +public class TreeKeyboardNavigationScrolls extends TestBase { + + @Override + protected void setup() { + Tree tree = new Tree(); + tree.setContainerDataSource(generateHierarchicalContainer()); + tree.setImmediate(true); + tree.addValidator(new AlwaysFailValidator("failed")); + addComponent(tree); + } + + private Container generateHierarchicalContainer() { + HierarchicalContainer cont = new HierarchicalContainer(); + for (int i = 1; i < 6; i++) { + cont.addItem(i); + for (int j = 1; j < 3; j++) { + String id = i + + " foo bar baz make this node really wide so that we don't have to fiddle with resizing the browser window -> " + + "what would you do if you had one of your legs on backwards? it's legs time! everybody get your legs! " + + "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore " + + "et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut " + + "aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum " + + "dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui " + + "officia deserunt mollit anim id est laborum." + j; + cont.addItem(id); + cont.setChildrenAllowed(id, false); + cont.setParent(id, i); + } + } + return cont; + } + + @Override + protected String getDescription() { + return "The tree scrolls right if the focused node is too wide when navigating with the keyboard"; + } + + @Override + protected Integer getTicketNumber() { + return 7230; + } + +} diff --git a/uitest/src/main/java/com/vaadin/v7/tests/components/tree/TreeKeyboardNavigationToNone.java b/uitest/src/main/java/com/vaadin/v7/tests/components/tree/TreeKeyboardNavigationToNone.java new file mode 100644 index 0000000000..cacf3ec2e1 --- /dev/null +++ b/uitest/src/main/java/com/vaadin/v7/tests/components/tree/TreeKeyboardNavigationToNone.java @@ -0,0 +1,64 @@ +/* + * Copyright 2000-2016 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.v7.tests.components.tree; + +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractReindeerTestUI; +import com.vaadin.ui.Button; +import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.v7.ui.Tree; + +/** + * Test UI for keyboard navigation for first and last tree item. + * + * @author Vaadin Ltd + */ +public class TreeKeyboardNavigationToNone extends AbstractReindeerTestUI { + + @Override + protected void setup(VaadinRequest request) { + final Tree tree = new Tree(); + tree.addItem("a"); + tree.addItem("b"); + + tree.select("a"); + addComponents(tree); + tree.focus(); + + Button button = new Button("Select last item", + new Button.ClickListener() { + + @Override + public void buttonClick(ClickEvent event) { + tree.select("b"); + tree.focus(); + } + }); + addComponent(button); + } + + @Override + protected Integer getTicketNumber() { + return 15343; + } + + @Override + protected String getTestDescription() { + return "Keyboard navigation should not throw client side exception " + + "when there are no items to navigate."; + } + +} diff --git a/uitest/src/main/java/com/vaadin/v7/tests/components/tree/TreeKeyboardNavigationValidators.java b/uitest/src/main/java/com/vaadin/v7/tests/components/tree/TreeKeyboardNavigationValidators.java new file mode 100644 index 0000000000..d33683d2bb --- /dev/null +++ b/uitest/src/main/java/com/vaadin/v7/tests/components/tree/TreeKeyboardNavigationValidators.java @@ -0,0 +1,49 @@ +package com.vaadin.v7.tests.components.tree; + +import com.vaadin.tests.components.TestBase; +import com.vaadin.tests.util.AlwaysFailValidator; +import com.vaadin.v7.data.Container; +import com.vaadin.v7.data.util.HierarchicalContainer; +import com.vaadin.v7.ui.Tree; + +public class TreeKeyboardNavigationValidators extends TestBase { + + @Override + protected void setup() { + addComponent(getTree()); + } + + private Tree getTree() { + Tree tree = new Tree(); + tree.setSizeFull(); + tree.setContainerDataSource(generateHierarchicalContainer()); + tree.setImmediate(true); + tree.addValidator(new AlwaysFailValidator("failed")); + return tree; + } + + private Container generateHierarchicalContainer() { + HierarchicalContainer cont = new HierarchicalContainer(); + for (int i = 1; i < 6; i++) { + cont.addItem(i); + for (int j = 1; j < 3; j++) { + String id = i + " -> " + j; + cont.addItem(id); + cont.setChildrenAllowed(id, false); + cont.setParent(id, i); + } + } + return cont; + } + + @Override + protected String getDescription() { + return "Keyboard navigation should still work in a tree with validators."; + } + + @Override + protected Integer getTicketNumber() { + return 7057; + } + +} diff --git a/uitest/src/main/java/com/vaadin/v7/tests/components/tree/TreeNodeCaptionWrapping.java b/uitest/src/main/java/com/vaadin/v7/tests/components/tree/TreeNodeCaptionWrapping.java new file mode 100644 index 0000000000..01b9685215 --- /dev/null +++ b/uitest/src/main/java/com/vaadin/v7/tests/components/tree/TreeNodeCaptionWrapping.java @@ -0,0 +1,44 @@ +package com.vaadin.v7.tests.components.tree; + +import com.vaadin.server.ThemeResource; +import com.vaadin.tests.components.TestBase; +import com.vaadin.v7.ui.Tree; + +public class TreeNodeCaptionWrapping extends TestBase { + + @Override + protected String getDescription() { + return "The text should not wrap to the following line but instead be cut off when there is too little horizontal space."; + } + + @Override + protected Integer getTicketNumber() { + return 3098; + } + + @Override + protected void setup() { + setTheme("runo"); + Tree tree = new Tree(); + tree.setWidth("100px"); + + tree.addItem("1"); + tree.setItemIcon("1", new ThemeResource("../runo/icons/16/ok.png")); + + String mainItem = "A very long item that should not wrap"; + String subItem = "Subitem - also long"; + + tree.addItem(mainItem); + tree.setItemIcon(mainItem, + new ThemeResource("../runo/icons/16/error.png")); + + tree.addItem(subItem); + tree.setParent(subItem, mainItem); + + tree.expandItem("1"); + tree.expandItem(mainItem); + tree.expandItem(subItem); + + addComponent(tree); + } +} diff --git a/uitest/src/main/java/com/vaadin/v7/tests/components/tree/TreePerformanceTest.java b/uitest/src/main/java/com/vaadin/v7/tests/components/tree/TreePerformanceTest.java new file mode 100644 index 0000000000..d1aa841544 --- /dev/null +++ b/uitest/src/main/java/com/vaadin/v7/tests/components/tree/TreePerformanceTest.java @@ -0,0 +1,75 @@ +package com.vaadin.v7.tests.components.tree; + +import com.vaadin.tests.components.AbstractTestCase; +import com.vaadin.ui.Layout; +import com.vaadin.ui.LegacyWindow; +import com.vaadin.ui.VerticalLayout; +import com.vaadin.v7.ui.Tree; + +public class TreePerformanceTest extends AbstractTestCase { + + @Override + protected String getDescription() { + return "Trees rendering type may become slow escpecially with FF and big tree in a deep component tree."; + } + + @Override + protected Integer getTicketNumber() { + return null; + } + + @Override + public void init() { + LegacyWindow w = new LegacyWindow(); + setMainWindow(w); + + Layout layout = null; + + for (int i = 0; i < getLayoutCount(); i++) { + Layout newlayout = createLayout(); + // newlayout.setHeight("100%"); + if (i == 0) { + w.setContent(newlayout); + } else { + layout.addComponent(newlayout); + } + layout = newlayout; + } + + Tree tree = new Tree(); + + for (int i = 0; i < getItemCount(); i++) { + String text = "ITEM " + i; + tree.addItem(text); + for (int j = 0; j < getSubItemCount(); j++) { + String subtext = " SUBITEM " + j + " for " + text; + tree.addItem(subtext); + tree.setParent(subtext, text); + } + tree.expandItemsRecursively(text); + } + + // One can test that the slugginesh is actually verticallayout issue + // Table testTable = TestForTablesInitialColumnWidthLogicRendering + // .getTestTable(12, 60); + // testTable.setPageLength(0); + layout.addComponent(tree); + + } + + private Layout createLayout() { + return new VerticalLayout(); + } + + private int getLayoutCount() { + return 10; + } + + private int getSubItemCount() { + return 3; + } + + private int getItemCount() { + return 200; + } +} diff --git a/uitest/src/main/java/com/vaadin/v7/tests/components/tree/TreeScrolling.java b/uitest/src/main/java/com/vaadin/v7/tests/components/tree/TreeScrolling.java new file mode 100644 index 0000000000..b893238c66 --- /dev/null +++ b/uitest/src/main/java/com/vaadin/v7/tests/components/tree/TreeScrolling.java @@ -0,0 +1,54 @@ +package com.vaadin.v7.tests.components.tree; + +import com.vaadin.tests.components.AbstractTestCase; +import com.vaadin.ui.LegacyWindow; +import com.vaadin.ui.RichTextArea; +import com.vaadin.ui.VerticalLayout; +import com.vaadin.v7.ui.TextField; +import com.vaadin.v7.ui.Tree; + +public class TreeScrolling extends AbstractTestCase { + + @Override + public void init() { + VerticalLayout layout = new VerticalLayout(); + layout.setSizeUndefined(); + LegacyWindow w = new LegacyWindow("", layout); + setMainWindow(w); + + TextField filler1 = new TextField(); + RichTextArea filler2 = new RichTextArea(); + Tree tree = new Tree(); + for (int i = 0; i < 20; i++) { + String parentId = "Item " + i; + // Item parentItem = + tree.addItem(parentId); + for (int j = 0; j < 20; j++) { + String subId = "Item " + i + " - " + j; + // Item subItem = + tree.addItem(subId); + tree.setParent(subId, parentId); + } + + } + + for (Object id : tree.rootItemIds()) { + tree.expandItemsRecursively(id); + } + + layout.addComponent(filler1); + layout.addComponent(filler2); + layout.addComponent(tree); + } + + @Override + protected String getDescription() { + return "Tests what happens when a tree is partly out of view when an item is selected"; + } + + @Override + protected Integer getTicketNumber() { + return 5400; + } + +} diff --git a/uitest/src/main/java/com/vaadin/v7/tests/components/tree/TreeScrollingOnRightClick.java b/uitest/src/main/java/com/vaadin/v7/tests/components/tree/TreeScrollingOnRightClick.java new file mode 100644 index 0000000000..4253d3b0d3 --- /dev/null +++ b/uitest/src/main/java/com/vaadin/v7/tests/components/tree/TreeScrollingOnRightClick.java @@ -0,0 +1,53 @@ +package com.vaadin.v7.tests.components.tree; + +import com.vaadin.event.MouseEvents; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractReindeerTestUI; +import com.vaadin.v7.event.ItemClickEvent; +import com.vaadin.v7.ui.Tree; + +/** + * Test for #12618: Trying to select item with right click in Tree causes focus + * issues. + */ +@SuppressWarnings("serial") +public class TreeScrollingOnRightClick extends AbstractReindeerTestUI { + + public static final String TREE_ID = "my-tree"; + + @Override + protected void setup(VaadinRequest request) { + final Tree tree = new Tree(); + tree.setId(TREE_ID); + tree.setSizeUndefined(); + + // Add item click listener for right click selection + tree.addItemClickListener(new ItemClickEvent.ItemClickListener() { + @SuppressWarnings("deprecation") + @Override + public void itemClick(ItemClickEvent event) { + if (event.getButton() == MouseEvents.ClickEvent.BUTTON_RIGHT) { + tree.select(event.getItemId()); + } + } + }); + + // Add some items + for (int i = 0; i < 200; i++) { + tree.addItem(String.format("Node %s", i)); + } + + addComponent(tree); + } + + @Override + protected String getTestDescription() { + return "Right clicking on items should not scroll Tree."; + } + + @Override + protected Integer getTicketNumber() { + return 12618; + } + +} diff --git a/uitest/src/main/java/com/vaadin/v7/tests/components/tree/TreeScrollingOnSelection.java b/uitest/src/main/java/com/vaadin/v7/tests/components/tree/TreeScrollingOnSelection.java new file mode 100644 index 0000000000..100cbd8e5d --- /dev/null +++ b/uitest/src/main/java/com/vaadin/v7/tests/components/tree/TreeScrollingOnSelection.java @@ -0,0 +1,75 @@ +package com.vaadin.v7.tests.components.tree; + +import com.vaadin.tests.components.TestBase; +import com.vaadin.ui.Label; +import com.vaadin.ui.Panel; +import com.vaadin.ui.VerticalLayout; +import com.vaadin.v7.data.util.HierarchicalContainer; +import com.vaadin.v7.event.ItemClickEvent; +import com.vaadin.v7.event.ItemClickEvent.ItemClickListener; +import com.vaadin.v7.ui.Tree; + +public class TreeScrollingOnSelection extends TestBase { + private static final long serialVersionUID = 4082075610259697145L; + + private static final String GREEK_ALPHABET = "greek alphabet"; + + private static final String[] ALPHABET = { "Alpha", "Beta", "Gamma", + "Delta", "Epsilon", "Zeta", "Eta", "Theta", "Iota", "Kappa", + "Lambda", "My", "Ny", "Xi", "Omikron", "Pi", "Rho", "Sigma", "Tau", + "Ypsilon", "Phi", "Chi", "Psi", "Omega" }; + + @Override + public void setup() { + final Label charLabel = new Label(); + charLabel.setWidth("200px"); + + Tree tree = new Tree("alphabets", getContainer()); + tree.expandItem(GREEK_ALPHABET); + tree.addListener(new ItemClickListener() { + + private static final long serialVersionUID = 5955518276555388126L; + + @Override + public void itemClick(ItemClickEvent event) { + charLabel.setValue(event.getItemId().toString()); + } + }); + tree.setImmediate(true); + + VerticalLayout panelLayout = new VerticalLayout(); + panelLayout.setMargin(true); + Panel panel = new Panel(panelLayout); + panelLayout.addComponent(tree); + panel.setWidth("200px"); + panel.setHeight("300px"); + + addComponent(panel); + + addComponent(charLabel); + } + + private HierarchicalContainer getContainer() { + HierarchicalContainer container = new HierarchicalContainer(); + + container.addItem(GREEK_ALPHABET); + + for (String character : ALPHABET) { + container.addItem(character); + container.setChildrenAllowed(character, false); + container.setParent(character, GREEK_ALPHABET); + } + + return container; + } + + @Override + protected String getDescription() { + return "Selecting an item in the tree inside the Panel should not cause the panel scroll position to change."; + } + + @Override + protected Integer getTicketNumber() { + return 6731; + } +} diff --git a/uitest/src/main/java/com/vaadin/v7/tests/components/tree/TreeToolTips.java b/uitest/src/main/java/com/vaadin/v7/tests/components/tree/TreeToolTips.java new file mode 100644 index 0000000000..58fffc82d1 --- /dev/null +++ b/uitest/src/main/java/com/vaadin/v7/tests/components/tree/TreeToolTips.java @@ -0,0 +1,92 @@ +package com.vaadin.v7.tests.components.tree; + +import com.vaadin.tests.components.TestBase; +import com.vaadin.ui.Component; +import com.vaadin.v7.data.Item; +import com.vaadin.v7.data.util.HierarchicalContainer; +import com.vaadin.v7.ui.AbstractSelect; +import com.vaadin.v7.ui.Tree; + +public class TreeToolTips extends TestBase { + + @Override + protected void setup() { + final Tree tree = new Tree(null, createContainer()); + tree.setItemDescriptionGenerator( + new AbstractSelect.ItemDescriptionGenerator() { + @Override + public String generateDescription(Component source, + Object itemId, Object propertyId) { + return "This is a tooltip for item id '" + itemId + "'"; + } + }); + + for (Object rootItems : tree.rootItemIds()) { + tree.expandItemsRecursively(rootItems); + } + + addComponent(tree); + } + + @Override + protected String getDescription() { + return "Tree items should have tooltips"; + } + + @Override + protected Integer getTicketNumber() { + return 6637; + } + + private HierarchicalContainer createContainer() { + HierarchicalContainer cont = new HierarchicalContainer(); + cont.addContainerProperty("name", String.class, ""); + + for (int i = 0; i < 20; i++) { + Item item = cont.addItem("Item " + i); + item.getItemProperty("name").setValue("Item " + i); + cont.setChildrenAllowed("Item " + i, false); + + if (i == 1 || i == 4) { + cont.setChildrenAllowed("Item " + i, true); + } + + // Add three items to item 1 + if (i > 1 && i < 4) { + cont.setParent("Item " + i, "Item 1"); + } + + // Add 5 items to item 4 + if (i > 4 && i < 10) { + cont.setChildrenAllowed("Item " + i, true); + + if (i == 7) { + item = cont.addItem("Item 71"); + item.getItemProperty("name").setValue("Item 71"); + cont.setParent("Item 71", "Item " + i); + cont.setChildrenAllowed("Item 71", false); + + item = cont.addItem("Item 72"); + item.getItemProperty("name").setValue("Item 72"); + cont.setParent("Item 72", "Item " + i); + cont.setChildrenAllowed("Item 72", true); + + item = cont.addItem("Item 73"); + item.getItemProperty("name").setValue("Item 73"); + cont.setParent("Item 73", "Item 72"); + cont.setChildrenAllowed("Item 73", true); + + item = cont.addItem("Item 74"); + item.getItemProperty("name").setValue("Item 74"); + cont.setParent("Item 74", "Item " + i); + cont.setChildrenAllowed("Item 74", true); + } + + cont.setParent("Item " + i, "Item " + (i - 1)); + + } + } + + return cont; + } +} diff --git a/uitest/src/main/java/com/vaadin/v7/tests/components/tree/TreeWithIcons.java b/uitest/src/main/java/com/vaadin/v7/tests/components/tree/TreeWithIcons.java new file mode 100644 index 0000000000..d11140c6e8 --- /dev/null +++ b/uitest/src/main/java/com/vaadin/v7/tests/components/tree/TreeWithIcons.java @@ -0,0 +1,69 @@ +package com.vaadin.v7.tests.components.tree; + +import java.util.Date; + +import com.vaadin.server.Sizeable; +import com.vaadin.server.ThemeResource; +import com.vaadin.tests.components.TestBase; +import com.vaadin.tests.util.LoremIpsum; +import com.vaadin.ui.HorizontalLayout; +import com.vaadin.ui.Panel; +import com.vaadin.v7.ui.Tree; +import com.vaadin.v7.ui.themes.Reindeer; + +public class TreeWithIcons extends TestBase { + + @Override + protected void setup() { + ThemeResource notCachedFolderIconHuge = new ThemeResource( + "../runo/icons/64/folder.png?" + new Date().getTime()); + ThemeResource notCachedFolderIconLarge = new ThemeResource( + "../runo/icons/32/folder.png?" + new Date().getTime()); + ThemeResource notCachedFolderIconLargeOther = new ThemeResource( + "../runo/icons/32/ok.png?" + new Date().getTime()); + Tree t = new Tree(); + t.setImmediate(true); + + t.addItem("Root 1"); + t.addItem("Root 11"); + t.addItem("Root 111"); + t.addItem("Root 1111"); + t.addItem("Sub 1"); + t.setItemIcon("Sub 1", notCachedFolderIconLargeOther); + t.setParent("Sub 1", "Root 1"); + String longItemId = LoremIpsum.get(50); + t.addItem(longItemId); + t.setItemIcon(longItemId, notCachedFolderIconHuge); + t.setParent(longItemId, "Root 11"); + t.addItem("abcdefghijklmn"); + + String first = "abcdefghijklmnop"; + String second = "abcdefghijklmnopqrst"; + t.addItem(first); + t.addItem(second); + t.setParent(second, first); + t.setItemIcon(first, notCachedFolderIconLarge); + + HorizontalLayout hlay = new HorizontalLayout(); + hlay.setStyleName(Reindeer.LAYOUT_BLUE); + hlay.addComponent(t); + hlay.setWidth(-1, Sizeable.UNITS_PIXELS); + + Panel p = new Panel(); + p.setSizeUndefined(); + p.setContent(hlay); + + addComponent(p); + } + + @Override + protected String getDescription() { + return "A tree with icons should resize itself correctly so the nodes are not cut either horizontally or vertically."; + } + + @Override + protected Integer getTicketNumber() { + return 3529; + } + +} diff --git a/uitest/src/main/java/com/vaadin/v7/tests/components/tree/Trees.java b/uitest/src/main/java/com/vaadin/v7/tests/components/tree/Trees.java new file mode 100644 index 0000000000..b53c125be3 --- /dev/null +++ b/uitest/src/main/java/com/vaadin/v7/tests/components/tree/Trees.java @@ -0,0 +1,408 @@ +package com.vaadin.v7.tests.components.tree; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.List; + +import com.vaadin.event.Action; +import com.vaadin.event.Action.Handler; +import com.vaadin.shared.ui.MultiSelectMode; +import com.vaadin.tests.components.select.AbstractSelectTestCase; +import com.vaadin.v7.data.Container; +import com.vaadin.v7.data.Container.Hierarchical; +import com.vaadin.v7.data.util.HierarchicalContainer; +import com.vaadin.v7.ui.Tree; +import com.vaadin.v7.ui.Tree.CollapseEvent; +import com.vaadin.v7.ui.Tree.CollapseListener; +import com.vaadin.v7.ui.Tree.ExpandEvent; +import com.vaadin.v7.ui.Tree.ExpandListener; +import com.vaadin.v7.ui.Tree.ItemStyleGenerator; + +public class Trees extends AbstractSelectTestCase<Tree> + implements ExpandListener, CollapseListener { + + private int rootItemIds = 3; + + private ItemStyleGenerator rootGreenSecondLevelRed = new com.vaadin.v7.ui.Tree.ItemStyleGenerator() { + + @Override + public String getStyle(Tree source, Object itemId) { + Hierarchical c = (Container.Hierarchical) getComponent() + .getContainerDataSource(); + if (c.isRoot(itemId)) { + return "green"; + } + + Object parent = c.getParent(itemId); + if (!c.isRoot(parent)) { + return "red"; + } + + return null; + } + + @Override + public String toString() { + return "Root green, second level red"; + } + + }; + + private ItemStyleGenerator evenItemsBold = new com.vaadin.v7.ui.Tree.ItemStyleGenerator() { + + @Override + public String getStyle(Tree source, Object itemId) { + Hierarchical c = (Container.Hierarchical) getComponent() + .getContainerDataSource(); + int idx = 0; + + for (Iterator<?> i = c.getItemIds().iterator(); i.hasNext();) { + Object id = i.next(); + if (id == itemId) { + if (idx % 2 == 1) { + return "bold"; + } else { + return null; + } + } + + idx++; + } + + return null; + } + + @Override + public String toString() { + return "Even items bold"; + } + + }; + + private Command<Tree, ContextMenu> contextMenuCommand = new Command<Tree, ContextMenu>() { + + @Override + public void execute(Tree c, final ContextMenu value, Object data) { + c.removeAllActionHandlers(); + if (value != null) { + c.addActionHandler(new Handler() { + + @Override + public void handleAction(Action action, Object sender, + Object target) { + log("Action " + action.getCaption() + " performed on " + + target); + } + + @Override + public Action[] getActions(Object target, Object sender) { + return value.getActions(target, sender); + } + }); + } + } + }; + + @Override + protected Class<Tree> getTestClass() { + return Tree.class; + } + + @Override + protected void createActions() { + super.createActions(); + + // Causes container changes so doing this first.. + createRootItemSelectAction(CATEGORY_DATA_SOURCE); + + createExpandCollapseActions(CATEGORY_FEATURES); + createSelectionModeSelect(CATEGORY_SELECTION); + createChildrenAllowedAction(CATEGORY_DATA_SOURCE); + + createListeners(CATEGORY_LISTENERS); + createItemStyleGenerator(CATEGORY_FEATURES); + createContextMenuAction(CATEGORY_FEATURES); + // TODO: DropHandler + // TODO: DragMode + // TODO: ActionHandler + + } + + private void createContextMenuAction(String category) { + LinkedHashMap<String, ContextMenu> options = new LinkedHashMap<>(); + options.put("None", null); + options.put("Item without icon", new ContextMenu("No icon", null)); + ContextMenu cm = new ContextMenu(); + cm.addItem("Caption only", null); + cm.addItem("Has icon", ICON_16_USER_PNG_UNCACHEABLE); + options.put("With and without icon", cm); + options.put("Only one large icon", + new ContextMenu("Icon", ICON_64_EMAIL_REPLY_PNG_UNCACHEABLE)); + + createSelectAction("Context menu", category, options, "None", + contextMenuCommand, true); + } + + private void createItemStyleGenerator(String category) { + + LinkedHashMap<String, com.vaadin.v7.ui.Tree.ItemStyleGenerator> options = new LinkedHashMap<>(); + + options.put("-", null); + options.put(rootGreenSecondLevelRed.toString(), + rootGreenSecondLevelRed); + options.put(evenItemsBold.toString(), evenItemsBold); + + createSelectAction("Item Style generator", category, options, "-", + itemStyleGeneratorCommand); + + } + + private void createListeners(String category) { + createBooleanAction("Expand listener", category, false, + expandListenerCommand); + createBooleanAction("Collapse listener", category, false, + collapseListenerCommand); + createBooleanAction("Item click listener", category, false, + itemClickListenerCommand); + + } + + private enum SelectMode { + NONE, SINGLE, MULTI_SIMPLE, MULTI; + } + + protected void createSelectionModeSelect(String category) { + LinkedHashMap<String, SelectMode> options = new LinkedHashMap<>(); + options.put("None", SelectMode.NONE); + options.put("Single", SelectMode.SINGLE); + options.put("Multi - simple", SelectMode.MULTI_SIMPLE); + options.put("Multi - ctrl/shift", SelectMode.MULTI); + + createSelectAction("Selection Mode", category, options, + "Multi - ctrl/shift", new Command<Tree, SelectMode>() { + + @Override + public void execute(Tree t, SelectMode value, Object data) { + switch (value) { + case NONE: + t.setSelectable(false); + break; + case SINGLE: + t.setMultiSelect(false); + t.setSelectable(true); + break; + case MULTI_SIMPLE: + t.setSelectable(true); + t.setMultiSelect(true); + t.setMultiselectMode(MultiSelectMode.SIMPLE); + break; + case MULTI: + t.setSelectable(true); + t.setMultiSelect(true); + t.setMultiselectMode(MultiSelectMode.DEFAULT); + break; + } + } + }); + } + + @Override + protected Container createContainer(int properties, int items) { + return createHierarchicalContainer(properties, items, rootItemIds); + } + + private Container.Hierarchical createHierarchicalContainer(int properties, + int items, int roots) { + Container.Hierarchical c = new HierarchicalContainer(); + + populateContainer(c, properties, items); + + if (items <= roots) { + return c; + } + + // "roots" roots, each with + // "firstLevel" children, two with no children (one with childAllowed, + // one without) + // ("firstLevel"-2)*"secondLevel" children ("secondLevel"/2 with + // childAllowed, "secondLevel"/2 without) + + // N*M+N*(M-2)*C = items + // items=N(M+MC-2C) + + // Using secondLevel=firstLevel/2 => + // items = roots*(firstLevel+firstLevel*firstLevel/2-2*firstLevel/2) + // =roots*(firstLevel+firstLevel^2/2-firstLevel) + // = roots*firstLevel^2/2 + // => firstLevel = sqrt(items/roots*2) + + int firstLevel = (int) Math.ceil(Math.sqrt(items / roots * 2.0)); + int secondLevel = firstLevel / 2; + + while (roots * (1 + 2 + (firstLevel - 2) * secondLevel) < items) { + // Increase something so we get enough items + secondLevel++; + } + + List<Object> itemIds = new ArrayList<>(c.getItemIds()); + + int nextItemId = roots; + for (int rootIndex = 0; rootIndex < roots; rootIndex++) { + // roots use items 0..roots-1 + Object rootItemId = itemIds.get(rootIndex); + + // force roots to be roots even though they automatically should be + c.setParent(rootItemId, null); + + for (int firstLevelIndex = 0; firstLevelIndex < firstLevel; firstLevelIndex++) { + if (nextItemId >= items) { + break; + } + Object firstLevelItemId = itemIds.get(nextItemId++); + c.setParent(firstLevelItemId, rootItemId); + + if (firstLevelIndex < 2) { + continue; + } + + // firstLevelChildren 2.. have child nodes + for (int secondLevelIndex = 0; secondLevelIndex < secondLevel; secondLevelIndex++) { + if (nextItemId >= items) { + break; + } + + Object secondLevelItemId = itemIds.get(nextItemId++); + c.setParent(secondLevelItemId, firstLevelItemId); + } + } + } + + return c; + } + + private void createRootItemSelectAction(String category) { + LinkedHashMap<String, Integer> options = new LinkedHashMap<>(); + for (int i = 1; i <= 10; i++) { + options.put(String.valueOf(i), i); + } + options.put("20", 20); + options.put("50", 50); + options.put("100", 100); + + createSelectAction("Number of root items", category, options, "3", + rootItemIdsCommand); + } + + private void createExpandCollapseActions(String category) { + LinkedHashMap<String, Object> options = new LinkedHashMap<>(); + + for (Object id : getComponent().getItemIds()) { + options.put(id.toString(), id); + } + createMultiClickAction("Expand", category, options, expandItemCommand, + null); + createMultiClickAction("Expand recursively", category, options, + expandItemRecursivelyCommand, null); + createMultiClickAction("Collapse", category, options, + collapseItemCommand, null); + + } + + private void createChildrenAllowedAction(String category) { + LinkedHashMap<String, Object> options = new LinkedHashMap<>(); + + for (Object id : getComponent().getItemIds()) { + options.put(id.toString(), id); + } + createMultiToggleAction("Children allowed", category, options, + setChildrenAllowedCommand, true); + + } + + /* + * COMMANDS + */ + private Command<Tree, Integer> rootItemIdsCommand = new Command<Tree, Integer>() { + + @Override + public void execute(Tree c, Integer value, Object data) { + rootItemIds = value; + updateContainer(); + } + }; + + private Command<Tree, Object> expandItemCommand = new Command<Tree, Object>() { + + @Override + public void execute(Tree c, Object itemId, Object data) { + c.expandItem(itemId); + } + }; + private Command<Tree, Object> expandItemRecursivelyCommand = new Command<Tree, Object>() { + + @Override + public void execute(Tree c, Object itemId, Object data) { + c.expandItemsRecursively(itemId); + } + }; + + private Command<Tree, Object> collapseItemCommand = new Command<Tree, Object>() { + + @Override + public void execute(Tree c, Object itemId, Object data) { + c.collapseItem(itemId); + } + }; + + private Command<Tree, Boolean> setChildrenAllowedCommand = new Command<Tree, Boolean>() { + + @Override + public void execute(Tree c, Boolean areChildrenAllowed, Object itemId) { + c.setChildrenAllowed(itemId, areChildrenAllowed); + } + }; + + private Command<Tree, Boolean> expandListenerCommand = new Command<Tree, Boolean>() { + @Override + public void execute(Tree c, Boolean value, Object data) { + if (value) { + c.addListener((ExpandListener) Trees.this); + } else { + c.removeListener((ExpandListener) Trees.this); + } + } + }; + + private Command<Tree, Boolean> collapseListenerCommand = new Command<Tree, Boolean>() { + @Override + public void execute(Tree c, Boolean value, Object data) { + if (value) { + c.addListener((CollapseListener) Trees.this); + } else { + c.removeListener((CollapseListener) Trees.this); + } + } + }; + + private Command<Tree, com.vaadin.v7.ui.Tree.ItemStyleGenerator> itemStyleGeneratorCommand = new Command<Tree, com.vaadin.v7.ui.Tree.ItemStyleGenerator>() { + + @Override + public void execute(Tree c, + com.vaadin.v7.ui.Tree.ItemStyleGenerator value, Object data) { + c.setItemStyleGenerator(value); + + } + }; + + @Override + public void nodeCollapse(CollapseEvent event) { + log(event.getClass().getSimpleName() + ": " + event.getItemId()); + } + + @Override + public void nodeExpand(ExpandEvent event) { + log(event.getClass().getSimpleName() + ": " + event.getItemId()); + } + +} |