]> source.dussan.org Git - vaadin-framework.git/commitdiff
Tree test case
authorArtur Signell <artur.signell@itmill.com>
Sun, 17 Oct 2010 18:13:33 +0000 (18:13 +0000)
committerArtur Signell <artur.signell@itmill.com>
Sun, 17 Oct 2010 18:13:33 +0000 (18:13 +0000)
svn changeset:15585/svn branch:6.4

tests/src/com/vaadin/tests/components/MenuBasedComponentTestCase.java
tests/src/com/vaadin/tests/components/select/AbstractSelectTestCase.java
tests/src/com/vaadin/tests/components/table/Tables.java
tests/src/com/vaadin/tests/components/tree/Trees.java [new file with mode: 0644]

index 5bea6f2877930734e31983a8b22f686658b801de..c8b6dd021cf3f6fc344b4fbd91cb71e1a1c9f749 100644 (file)
@@ -1,9 +1,11 @@
 package com.vaadin.tests.components;\r
 \r
+import java.util.HashMap;\r
 import java.util.HashSet;\r
 import java.util.LinkedHashMap;\r
 import java.util.List;\r
 import java.util.Locale;\r
+import java.util.Map;\r
 import java.util.Set;\r
 \r
 import com.vaadin.terminal.Resource;\r
@@ -38,6 +40,11 @@ public abstract class MenuBasedComponentTestCase<T extends AbstractComponent>
     private Set<MenuItem> parentOfSelectableMenuItem = new HashSet<MenuItem>();\r
     private MenuItem windowMenu;\r
 \r
+    /**\r
+     * Maps the category name to a menu item\r
+     */\r
+    private Map<String, MenuItem> categoryToMenuItem = new HashMap<String, MenuItem>();\r
+\r
     protected static final String CATEGORY_STATE = "State";\r
     protected static final String CATEGORY_SIZE = "Size";\r
     protected static final String CATEGORY_SELECTION = "Selection";\r
@@ -47,8 +54,11 @@ public abstract class MenuBasedComponentTestCase<T extends AbstractComponent>
 \r
     @Override\r
     protected final void setup() {\r
+        setTheme("tests-components");\r
+\r
         // Create menu here so it appears before the components\r
         menu = new MenuBar();\r
+        menu.setDebugId("menu");\r
         mainMenu = menu.addItem("Component", null);\r
         windowMenu = menu.addItem("Test", null);\r
         addComponent(menu);\r
@@ -71,6 +81,7 @@ public abstract class MenuBasedComponentTestCase<T extends AbstractComponent>
     @Override\r
     protected void initializeComponents() {\r
         component = constructComponent();\r
+        component.setDebugId("testComponent");\r
         addTestComponent(component);\r
     }\r
 \r
@@ -225,19 +236,52 @@ public abstract class MenuBasedComponentTestCase<T extends AbstractComponent>
         doCommand(caption, command, initialState, data);\r
     }\r
 \r
+    protected <DATATYPE> void createClickAction(String caption,\r
+            String category, final Command<T, DATATYPE> command, DATATYPE value) {\r
+        createClickAction(caption, category, command, value, null);\r
+    }\r
+\r
+    protected <DATATYPE> void createClickAction(String caption,\r
+            String category, final Command<T, DATATYPE> command,\r
+            DATATYPE value, Object data) {\r
+        MenuItem categoryItem = getCategoryMenuItem(category);\r
+        categoryItem.addItem(caption, menuClickCommand(command, value, data));\r
+        doCommand(caption, command, value, data);\r
+    }\r
+\r
     private MenuItem getCategoryMenuItem(String category) {\r
         if (category == null) {\r
             return getCategoryMenuItem("Misc");\r
         }\r
 \r
-        if (mainMenu.getChildren() != null) {\r
-            for (MenuItem i : mainMenu.getChildren()) {\r
-                if (i.getText().equals(category)) {\r
-                    return i;\r
-                }\r
-            }\r
+        MenuItem item = categoryToMenuItem.get(category);\r
+        if (item != null) {\r
+            return item;\r
         }\r
-        return mainMenu.addItem(category, null);\r
+\r
+        return createCategory(category, null);\r
+    }\r
+\r
+    /**\r
+     * Creates category "category" in parent category "parentCategory". Each\r
+     * category name must be globally unique.\r
+     * \r
+     * @param category\r
+     * @param parentCategory\r
+     * @return\r
+     */\r
+    protected MenuItem createCategory(String category, String parentCategory) {\r
+        if (categoryToMenuItem.containsKey(category)) {\r
+            return categoryToMenuItem.get(category);\r
+        }\r
+        MenuItem item;\r
+        if (parentCategory == null) {\r
+            item = mainMenu.addItem(category, null);\r
+        } else {\r
+            item = getCategoryMenuItem(parentCategory).addItem(category, null);\r
+        }\r
+        categoryToMenuItem.put(category, item);\r
+        return item;\r
     }\r
 \r
     private MenuBar.Command menuBooleanCommand(\r
@@ -254,6 +298,18 @@ public abstract class MenuBasedComponentTestCase<T extends AbstractComponent>
         };\r
     }\r
 \r
+    private <DATATYPE> MenuBar.Command menuClickCommand(\r
+            final com.vaadin.tests.components.ComponentTestCase.Command<T, DATATYPE> command,\r
+            final DATATYPE value, final Object data) {\r
+\r
+        return new MenuBar.Command() {\r
+            public void menuSelected(MenuItem selectedItem) {\r
+                doCommand(getText(selectedItem), command, value, data);\r
+            }\r
+\r
+        };\r
+    }\r
+\r
     protected void setSelected(MenuItem item, boolean selected) {\r
         if (selected) {\r
             item.setIcon(SELECTED_ICON);\r
@@ -323,6 +379,56 @@ public abstract class MenuBasedComponentTestCase<T extends AbstractComponent>
 \r
     }\r
 \r
+    protected <TYPE> void createMultiClickAction(\r
+            String caption,\r
+            String category,\r
+            LinkedHashMap<String, TYPE> options,\r
+            com.vaadin.tests.components.ComponentTestCase.Command<T, TYPE> command,\r
+            Object data) {\r
+\r
+        MenuItem categoryItem = getCategoryMenuItem(category);\r
+        MenuItem mainItem = categoryItem.addItem(caption, null);\r
+\r
+        for (String option : options.keySet()) {\r
+            MenuBar.Command cmd = menuClickCommand(command,\r
+                    options.get(option), data);\r
+            mainItem.addItem(option, cmd);\r
+        }\r
+    }\r
+\r
+    protected <TYPE> void createMultiToggleAction(\r
+            String caption,\r
+            String category,\r
+            LinkedHashMap<String, TYPE> options,\r
+            com.vaadin.tests.components.ComponentTestCase.Command<T, Boolean> command,\r
+            boolean defaultValue) {\r
+\r
+        LinkedHashMap<String, Boolean> defaultValues = new LinkedHashMap<String, Boolean>();\r
+\r
+        for (String option : options.keySet()) {\r
+            defaultValues.put(option, defaultValue);\r
+        }\r
+\r
+        createMultiToggleAction(caption, category, options, command,\r
+                defaultValues);\r
+    }\r
+\r
+    protected <TYPE> void createMultiToggleAction(\r
+            String caption,\r
+            String category,\r
+            LinkedHashMap<String, TYPE> options,\r
+            com.vaadin.tests.components.ComponentTestCase.Command<T, Boolean> command,\r
+            LinkedHashMap<String, Boolean> defaultValues) {\r
+\r
+        createCategory(caption, category);\r
+\r
+        for (String option : options.keySet()) {\r
+            createBooleanAction(option, caption, defaultValues.get(option),\r
+                    command, options.get(option));\r
+\r
+        }\r
+    }\r
+\r
     protected <TYPE> void createSelectAction(\r
             String caption,\r
             String category,\r
index 8d63e7243c092815df0276112ec2901e197d7fe1..50ed38d85ebf56038ce10d1f8dac296b1bbb2ab8 100644 (file)
@@ -5,20 +5,26 @@ import java.util.LinkedHashMap;
 import com.vaadin.data.Container;\r
 import com.vaadin.data.Item;\r
 import com.vaadin.data.util.IndexedContainer;\r
+import com.vaadin.event.ItemClickEvent;\r
+import com.vaadin.event.ItemClickEvent.ItemClickListener;\r
+import com.vaadin.event.ItemClickEvent.ItemClickSource;\r
 import com.vaadin.tests.components.abstractfield.AbstractFieldTestCase;\r
 import com.vaadin.ui.AbstractSelect;\r
 \r
 public abstract class AbstractSelectTestCase<T extends AbstractSelect> extends\r
-        AbstractFieldTestCase<T> {\r
+        AbstractFieldTestCase<T> implements ItemClickListener {\r
 \r
     protected static final String CATEGORY_CONTENT = "Contents";\r
 \r
+    private int items = 0;\r
+    private int properties = 0;\r
+\r
     @Override\r
     protected void createActions() {\r
         super.createActions();\r
         createNullSelectAllowedCheckbox(CATEGORY_SELECTION);\r
+        createPropertiesInContainerSelect(CATEGORY_CONTENT);\r
         createItemsInContainerSelect(CATEGORY_CONTENT);\r
-        createColumnsInContainerSelect(CATEGORY_CONTENT);\r
 \r
     }\r
 \r
@@ -40,19 +46,29 @@ public abstract class AbstractSelectTestCase<T extends AbstractSelect> extends
     }\r
 \r
     protected Container createContainer(int properties, int items) {\r
+        return createIndexedContainer(properties, items);\r
+    }\r
+\r
+    private Container createIndexedContainer(int properties, int items) {\r
         IndexedContainer c = new IndexedContainer();\r
+        populateContainer(c, properties, items);\r
+\r
+        return c;\r
+    }\r
+\r
+    protected void populateContainer(Container c, int properties, int items) {\r
+        c.removeAllItems();\r
         for (int i = 1; i <= properties; i++) {\r
-            c.addContainerProperty("Column " + i, String.class, "");\r
+            c.addContainerProperty("Property " + i, String.class, "");\r
         }\r
         for (int i = 1; i <= items; i++) {\r
             Item item = c.addItem("Item " + i);\r
             for (int j = 1; j <= properties; j++) {\r
-                item.getItemProperty("Column " + j).setValue(\r
+                item.getItemProperty("Property " + j).setValue(\r
                         "Item " + i + "," + j);\r
             }\r
         }\r
 \r
-        return c;\r
     }\r
 \r
     protected void createItemsInContainerSelect(String category) {\r
@@ -70,7 +86,7 @@ public abstract class AbstractSelectTestCase<T extends AbstractSelect> extends
                 itemsInContainerCommand);\r
     }\r
 \r
-    protected void createColumnsInContainerSelect(String category) {\r
+    protected void createPropertiesInContainerSelect(String category) {\r
         LinkedHashMap<String, Integer> options = new LinkedHashMap<String, Integer>();\r
         options.put("0", 0);\r
         for (int i = 0; i <= 10; i++) {\r
@@ -80,8 +96,13 @@ public abstract class AbstractSelectTestCase<T extends AbstractSelect> extends
         options.put("100", 100);\r
         options.put("1000", 1000);\r
 \r
-        createSelectAction("Columns in container", category, options, "10",\r
-                columnsInContainerCommand);\r
+        createSelectAction("Properties in container", category, options, "10",\r
+                propertiesInContainerCommand);\r
+    }\r
+\r
+    protected void createItemClickListener(String category) {\r
+        createBooleanAction("Item click listener", category, false,\r
+                itemClickListenerCommand);\r
     }\r
 \r
     /* COMMANDS */\r
@@ -103,19 +124,45 @@ public abstract class AbstractSelectTestCase<T extends AbstractSelect> extends
     protected Command<T, Integer> itemsInContainerCommand = new Command<T, Integer>() {\r
 \r
         public void execute(T t, Integer value, Object data) {\r
-            t.setContainerDataSource(createContainer(t.getContainerDataSource()\r
-                    .getContainerPropertyIds().size(), value));\r
+            items = value;\r
+            updateContainer();\r
         }\r
     };\r
 \r
-    protected Command<T, Integer> columnsInContainerCommand = new Command<T, Integer>() {\r
+    protected Command<T, Integer> propertiesInContainerCommand = new Command<T, Integer>() {\r
 \r
         public void execute(T t, Integer value, Object data) {\r
-            t.setContainerDataSource(createContainer(value, t\r
-                    .getContainerDataSource().size()));\r
+            properties = value;\r
+            updateContainer();\r
         }\r
     };\r
 \r
+    protected Command<T, Boolean> itemClickListenerCommand = new Command<T, Boolean>() {\r
+\r
+        public void execute(T c, Boolean value, Object data) {\r
+            if (value) {\r
+                ((ItemClickSource) c).addListener(AbstractSelectTestCase.this);\r
+            } else {\r
+                ((ItemClickSource) c)\r
+                        .removeListener(AbstractSelectTestCase.this);\r
+            }\r
+\r
+        }\r
+    };\r
+\r
+    protected void setContainer(Container newContainer) {\r
+        getComponent().setContainerDataSource(newContainer);\r
+\r
+    }\r
+\r
+    protected void updateContainer() {\r
+        setContainer(createContainer(properties, items));\r
+    }\r
+\r
     /* COMMANDS END */\r
 \r
+    public void itemClick(ItemClickEvent event) {\r
+        log("ItemClick on itemId: " + event.getItemId() + ", propertyId: "\r
+                + event.getPropertyId() + " using " + event.getButtonName());\r
+    }\r
 }\r
index 7173244c3f36a21c208caa00c915a1a8c159df58..15a273377c9f4de947e1927fa701e5d88a38033c 100644 (file)
@@ -5,7 +5,6 @@ import java.util.Arrays;
 import java.util.LinkedHashMap;\r
 import java.util.List;\r
 \r
-import com.vaadin.event.ItemClickEvent;\r
 import com.vaadin.event.ItemClickEvent.ItemClickListener;\r
 import com.vaadin.tests.components.select.AbstractSelectTestCase;\r
 import com.vaadin.ui.AbstractSelect.MultiSelectMode;\r
@@ -129,7 +128,7 @@ public class Tables extends AbstractSelectTestCase<Table> implements
 \r
         createSelectionModeSelect(CATEGORY_SELECTION);\r
 \r
-        createItemClickListenerCheckbox(CATEGORY_LISTENERS);\r
+        createItemClickListener(CATEGORY_LISTENERS);\r
         createColumnResizeListenerCheckbox(CATEGORY_LISTENERS);\r
         createHeaderClickListenerCheckbox(CATEGORY_LISTENERS);\r
         createFooterClickListenerCheckbox(CATEGORY_LISTENERS);\r
@@ -168,10 +167,13 @@ public class Tables extends AbstractSelectTestCase<Table> implements
     }\r
 \r
     private void createVisibleColumnsMultiToggle(String category) {\r
+        LinkedHashMap<String, Object> options = new LinkedHashMap<String, Object>();\r
         for (Object id : getComponent().getContainerPropertyIds()) {\r
-            createBooleanAction(id.toString() + " - visible", category, true,\r
-                    visibleColumnCommand, id);\r
+            options.put(id.toString(), id);\r
         }\r
+\r
+        createMultiToggleAction("Visible columns", category, options,\r
+                visibleColumnCommand, true);\r
     }\r
 \r
     private void createRowHeaderModeSelect(String category) {\r
@@ -229,22 +231,6 @@ public class Tables extends AbstractSelectTestCase<Table> implements
                 });\r
     }\r
 \r
-    private void createItemClickListenerCheckbox(String category) {\r
-        Command<Table, Boolean> itemClickListenerCommand = new Command<Table, Boolean>() {\r
-\r
-            public void execute(Table c, Boolean value, Object data) {\r
-                if (value) {\r
-                    c.addListener((ItemClickListener) Tables.this);\r
-                } else {\r
-                    c.removeListener((ItemClickListener) Tables.this);\r
-                }\r
-\r
-            }\r
-        };\r
-        createBooleanAction("Item click listener", category, false,\r
-                itemClickListenerCommand);\r
-    }\r
-\r
     private void createHeaderClickListenerCheckbox(String category) {\r
 \r
         createBooleanAction("Header click listener", category, false,\r
@@ -379,8 +365,4 @@ public class Tables extends AbstractSelectTestCase<Table> implements
                 + event.getButtonName());\r
     }\r
 \r
-    public void itemClick(ItemClickEvent event) {\r
-        log("ItemClick on " + event.getItemId() + "/" + event.getPropertyId()\r
-                + " using " + event.getButtonName());\r
-    }\r
 }\r
diff --git a/tests/src/com/vaadin/tests/components/tree/Trees.java b/tests/src/com/vaadin/tests/components/tree/Trees.java
new file mode 100644 (file)
index 0000000..da6eb9f
--- /dev/null
@@ -0,0 +1,353 @@
+package com.vaadin.tests.components.tree;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Iterator;\r
+import java.util.LinkedHashMap;\r
+import java.util.List;\r
+\r
+import com.vaadin.data.Container;\r
+import com.vaadin.data.Container.Hierarchical;\r
+import com.vaadin.data.util.HierarchicalContainer;\r
+import com.vaadin.tests.components.select.AbstractSelectTestCase;\r
+import com.vaadin.ui.AbstractSelect.MultiSelectMode;\r
+import com.vaadin.ui.Tree;\r
+import com.vaadin.ui.Tree.CollapseEvent;\r
+import com.vaadin.ui.Tree.CollapseListener;\r
+import com.vaadin.ui.Tree.ExpandEvent;\r
+import com.vaadin.ui.Tree.ExpandListener;\r
+import com.vaadin.ui.Tree.ItemStyleGenerator;\r
+\r
+public class Trees extends AbstractSelectTestCase<Tree> implements\r
+        ExpandListener, CollapseListener {\r
+\r
+    private int rootItemIds = 3;\r
+\r
+    private ItemStyleGenerator rootGreenSecondLevelRed = new com.vaadin.ui.Tree.ItemStyleGenerator() {\r
+\r
+        public String getStyle(Object itemId) {\r
+            Hierarchical c = (Container.Hierarchical) getComponent()\r
+                    .getContainerDataSource();\r
+            if (c.isRoot(itemId)) {\r
+                return "green";\r
+            }\r
+\r
+            Object parent = c.getParent(itemId);\r
+            if (!c.isRoot(parent)) {\r
+                return "red";\r
+            }\r
+\r
+            return null;\r
+        }\r
+\r
+        @Override\r
+        public String toString() {\r
+            return "Root green, second level red";\r
+        };\r
+\r
+    };\r
+\r
+    private ItemStyleGenerator evenItemsBold = new com.vaadin.ui.Tree.ItemStyleGenerator() {\r
+\r
+        public String getStyle(Object itemId) {\r
+            Hierarchical c = (Container.Hierarchical) getComponent()\r
+                    .getContainerDataSource();\r
+            int idx = 0;\r
+\r
+            for (Iterator<?> i = c.getItemIds().iterator(); i.hasNext();) {\r
+                Object id = i.next();\r
+                if (id == itemId) {\r
+                    if (idx % 2 == 1) {\r
+                        return "bold";\r
+                    } else {\r
+                        return null;\r
+                    }\r
+                }\r
+\r
+                idx++;\r
+            }\r
+\r
+            return null;\r
+        }\r
+\r
+        @Override\r
+        public String toString() {\r
+            return "Even items bold";\r
+        };\r
+\r
+    };\r
+\r
+    @Override\r
+    protected Class<Tree> getTestClass() {\r
+        return Tree.class;\r
+    }\r
+\r
+    @Override\r
+    protected void createActions() {\r
+        super.createActions();\r
+\r
+        // Causes container changes so doing this first..\r
+        createRootItemSelectAction(CATEGORY_CONTENT);\r
+\r
+        createExpandCollapseActions(CATEGORY_FEATURES);\r
+        createSelectionModeSelect(CATEGORY_SELECTION);\r
+        createChildrenAllowedAction(CATEGORY_CONTENT);\r
+\r
+        createListeners(CATEGORY_LISTENERS);\r
+        createItemStyleGenerator(CATEGORY_FEATURES);\r
+\r
+        // TODO: DropHandler\r
+        // TODO: DragMode\r
+        // TODO: ActionHandler\r
+\r
+    }\r
+\r
+    private void createItemStyleGenerator(String category) {\r
+\r
+        LinkedHashMap<String, com.vaadin.ui.Tree.ItemStyleGenerator> options = new LinkedHashMap<String, com.vaadin.ui.Tree.ItemStyleGenerator>();\r
+\r
+        options.put("-", null);\r
+        options.put(rootGreenSecondLevelRed.toString(), rootGreenSecondLevelRed);\r
+        options.put(evenItemsBold.toString(), evenItemsBold);\r
+\r
+        createSelectAction("Item Style generator", category, options, "-",\r
+                itemStyleGeneratorCommand);\r
+\r
+    }\r
+\r
+    private void createListeners(String category) {\r
+        createBooleanAction("Expand listener", category, false,\r
+                expandListenerCommand);\r
+        createBooleanAction("Collapse listener", category, false,\r
+                collapseListenerCommand);\r
+        createBooleanAction("Item click listener", category, false,\r
+                itemClickListenerCommand);\r
+\r
+    }\r
+\r
+    private enum SelectMode {\r
+        NONE, SINGLE, MULTI_SIMPLE, MULTI;\r
+    }\r
+\r
+    protected void createSelectionModeSelect(String category) {\r
+        LinkedHashMap<String, SelectMode> options = new LinkedHashMap<String, SelectMode>();\r
+        options.put("None", SelectMode.NONE);\r
+        options.put("Single", SelectMode.SINGLE);\r
+        options.put("Multi - simple", SelectMode.MULTI_SIMPLE);\r
+        options.put("Multi - ctrl/shift", SelectMode.MULTI);\r
+\r
+        createSelectAction("Selection Mode", category, options,\r
+                "Multi - ctrl/shift", new Command<Tree, SelectMode>() {\r
+\r
+                    public void execute(Tree t, SelectMode value, Object data) {\r
+                        switch (value) {\r
+                        case NONE:\r
+                            t.setSelectable(false);\r
+                            break;\r
+                        case SINGLE:\r
+                            t.setMultiSelect(false);\r
+                            t.setSelectable(true);\r
+                            break;\r
+                        case MULTI_SIMPLE:\r
+                            t.setSelectable(true);\r
+                            t.setMultiSelect(true);\r
+                            t.setMultiselectMode(MultiSelectMode.SIMPLE);\r
+                            break;\r
+                        case MULTI:\r
+                            t.setSelectable(true);\r
+                            t.setMultiSelect(true);\r
+                            t.setMultiselectMode(MultiSelectMode.DEFAULT);\r
+                            break;\r
+                        }\r
+                    }\r
+                });\r
+    }\r
+\r
+    @Override\r
+    protected Container createContainer(int properties, int items) {\r
+        return createHierarchicalContainer(properties, items, rootItemIds);\r
+    }\r
+\r
+    private Container.Hierarchical createHierarchicalContainer(int properties,\r
+            int items, int roots) {\r
+        Container.Hierarchical c = new HierarchicalContainer();\r
+\r
+        populateContainer(c, properties, items);\r
+\r
+        if (items <= roots) {\r
+            return c;\r
+        }\r
+\r
+        // "roots" roots, each with\r
+        // "firstLevel" children, two with no children (one with childAllowed,\r
+        // one without)\r
+        // ("firstLevel"-2)*"secondLevel" children ("secondLevel"/2 with\r
+        // childAllowed, "secondLevel"/2 without)\r
+\r
+        // N*M+N*(M-2)*C = items\r
+        // items=N(M+MC-2C)\r
+\r
+        // Using secondLevel=firstLevel/2 =>\r
+        // items = roots*(firstLevel+firstLevel*firstLevel/2-2*firstLevel/2)\r
+        // =roots*(firstLevel+firstLevel^2/2-firstLevel)\r
+        // = roots*firstLevel^2/2\r
+        // => firstLevel = sqrt(items/roots*2)\r
+\r
+        int firstLevel = (int) Math.ceil(Math.sqrt(items / roots * 2.0));\r
+        int secondLevel = firstLevel / 2;\r
+\r
+        while (roots * (1 + 2 + (firstLevel - 2) * secondLevel) < items) {\r
+            // Increase something so we get enough items\r
+            secondLevel++;\r
+        }\r
+\r
+        List<Object> itemIds = new ArrayList<Object>(c.getItemIds());\r
+\r
+        int nextItemId = roots;\r
+        for (int rootIndex = 0; rootIndex < roots; rootIndex++) {\r
+            // roots use items 0..roots-1\r
+            Object rootItemId = itemIds.get(rootIndex);\r
+\r
+            // force roots to be roots even though they automatically should be\r
+            c.setParent(rootItemId, null);\r
+\r
+            for (int firstLevelIndex = 0; firstLevelIndex < firstLevel; firstLevelIndex++) {\r
+                if (nextItemId >= items) {\r
+                    break;\r
+                }\r
+                Object firstLevelItemId = itemIds.get(nextItemId++);\r
+                c.setParent(firstLevelItemId, rootItemId);\r
+\r
+                if (firstLevelIndex < 2) {\r
+                    continue;\r
+                }\r
+\r
+                // firstLevelChildren 2.. have child nodes\r
+                for (int secondLevelIndex = 0; secondLevelIndex < secondLevel; secondLevelIndex++) {\r
+                    if (nextItemId >= items) {\r
+                        break;\r
+                    }\r
+\r
+                    Object secondLevelItemId = itemIds.get(nextItemId++);\r
+                    c.setParent(secondLevelItemId, firstLevelItemId);\r
+                }\r
+            }\r
+        }\r
+\r
+        return c;\r
+    }\r
+\r
+    private void createRootItemSelectAction(String category) {\r
+        LinkedHashMap<String, Integer> options = new LinkedHashMap<String, Integer>();\r
+        for (int i = 1; i <= 10; i++) {\r
+            options.put(String.valueOf(i), i);\r
+        }\r
+        options.put("20", 20);\r
+        options.put("50", 50);\r
+        options.put("100", 100);\r
+\r
+        createSelectAction("Number of root items", category, options, "3",\r
+                rootItemIdsCommand);\r
+    }\r
+\r
+    private void createExpandCollapseActions(String category) {\r
+        LinkedHashMap<String, Object> options = new LinkedHashMap<String, Object>();\r
+\r
+        for (Object id : getComponent().getItemIds()) {\r
+            options.put(id.toString(), id);\r
+        }\r
+        createMultiClickAction("Expand", category, options, expandItemCommand,\r
+                null);\r
+        createMultiClickAction("Expand recursively", category, options,\r
+                expandItemRecursivelyCommand, null);\r
+        createMultiClickAction("Collapse", category, options,\r
+                collapseItemCommand, null);\r
+\r
+    }\r
+\r
+    private void createChildrenAllowedAction(String category) {\r
+        LinkedHashMap<String, Object> options = new LinkedHashMap<String, Object>();\r
+\r
+        for (Object id : getComponent().getItemIds()) {\r
+            options.put(id.toString(), id);\r
+        }\r
+        createMultiToggleAction("Children allowed", category, options,\r
+                setChildrenAllowedCommand, true);\r
+\r
+    }\r
+\r
+    /*\r
+     * COMMANDS\r
+     */\r
+    private Command<Tree, Integer> rootItemIdsCommand = new Command<Tree, Integer>() {\r
+\r
+        public void execute(Tree c, Integer value, Object data) {\r
+            rootItemIds = value;\r
+            updateContainer();\r
+        }\r
+    };\r
+\r
+    private Command<Tree, Object> expandItemCommand = new Command<Tree, Object>() {\r
+\r
+        public void execute(Tree c, Object itemId, Object data) {\r
+            c.expandItem(itemId);\r
+        }\r
+    };\r
+    private Command<Tree, Object> expandItemRecursivelyCommand = new Command<Tree, Object>() {\r
+\r
+        public void execute(Tree c, Object itemId, Object data) {\r
+            c.expandItemsRecursively(itemId);\r
+        }\r
+    };\r
+\r
+    private Command<Tree, Object> collapseItemCommand = new Command<Tree, Object>() {\r
+\r
+        public void execute(Tree c, Object itemId, Object data) {\r
+            c.collapseItem(itemId);\r
+        }\r
+    };\r
+\r
+    private Command<Tree, Boolean> setChildrenAllowedCommand = new Command<Tree, Boolean>() {\r
+\r
+        public void execute(Tree c, Boolean areChildrenAllowed, Object itemId) {\r
+            c.setChildrenAllowed(itemId, areChildrenAllowed);\r
+        }\r
+    };\r
+\r
+    private Command<Tree, Boolean> expandListenerCommand = new Command<Tree, Boolean>() {\r
+        public void execute(Tree c, Boolean value, Object data) {\r
+            if (value) {\r
+                c.addListener((ExpandListener) Trees.this);\r
+            } else {\r
+                c.removeListener((ExpandListener) Trees.this);\r
+            }\r
+        }\r
+    };\r
+\r
+    private Command<Tree, Boolean> collapseListenerCommand = new Command<Tree, Boolean>() {\r
+        public void execute(Tree c, Boolean value, Object data) {\r
+            if (value) {\r
+                c.addListener((CollapseListener) Trees.this);\r
+            } else {\r
+                c.removeListener((CollapseListener) Trees.this);\r
+            }\r
+        }\r
+    };\r
+\r
+    private Command<Tree, com.vaadin.ui.Tree.ItemStyleGenerator> itemStyleGeneratorCommand = new Command<Tree, com.vaadin.ui.Tree.ItemStyleGenerator>() {\r
+\r
+        public void execute(Tree c,\r
+                com.vaadin.ui.Tree.ItemStyleGenerator value, Object data) {\r
+            c.setItemStyleGenerator(value);\r
+\r
+        }\r
+    };\r
+\r
+    public void nodeCollapse(CollapseEvent event) {\r
+        log(event.getClass().getSimpleName() + ": " + event.getItemId());\r
+    }\r
+\r
+    public void nodeExpand(ExpandEvent event) {\r
+        log(event.getClass().getSimpleName() + ": " + event.getItemId());\r
+    }\r
+\r
+}\r