]> source.dussan.org Git - vaadin-framework.git/commitdiff
Add collapse and expand events to TreeGrid (#8889)
authorAleksi Hietanen <aleksi@vaadin.com>
Tue, 21 Mar 2017 13:53:59 +0000 (15:53 +0200)
committerHenri Sara <henri.sara@gmail.com>
Tue, 21 Mar 2017 13:53:59 +0000 (15:53 +0200)
Closes #8760

documentation/components/components-treegrid.asciidoc
server/src/main/java/com/vaadin/ui/TreeGrid.java
uitest/src/main/java/com/vaadin/tests/components/treegrid/TreeGridBasicFeatures.java
uitest/src/test/java/com/vaadin/tests/components/treegrid/TreeGridBasicFeaturesTest.java

index b0e28fee5fe420b05e9059f4604cb0845a718048..d3a431c3e91538ae2c9f54f5a6065ac9615d707a 100644 (file)
@@ -93,3 +93,16 @@ treeGrid.addColumn(Project::getHoursDone).setCaption("Hours Done");
 treeGrid.setHierarchyColumn("name");
 ----
 
+== Listening to Events
+
+In addition to supporting all the listeners of the standard [classname]#Grid#, [classname]#TreeGrid# supports listening to the expansion and collapsing of items in its hierarchy.
+The expand and collapse listeners can be added as follows:
+
+[source, java]
+----
+treeGrid.addExpandListener(event -> log("Item expanded: " + event.getExpandedItem()));
+treeGrid.addCollapseListener(event -> log("Item collapsed: " + event.getCollapsedItem()));
+----
+
+The return types of the methods `getExpandedItem` and `getCollapsedItem` are the same as the type of the [classname]#TreeGrid# the events originated from.
+Note that collapse listeners will not be triggered for any expanded subtrees of the collapsed item.
index 82c857ac86144cafcc67a8ca8b8bb97063377835..2378ff3f2b3b37213eed63e97a0c0fccb0aecd8e 100644 (file)
@@ -15,6 +15,8 @@
  */
 package com.vaadin.ui;
 
+import java.io.Serializable;
+import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
@@ -33,6 +35,7 @@ import com.vaadin.data.provider.HierarchicalDataCommunicator;
 import com.vaadin.data.provider.HierarchicalDataProvider;
 import com.vaadin.data.provider.HierarchicalQuery;
 import com.vaadin.data.provider.InMemoryHierarchicalDataProvider;
+import com.vaadin.shared.Registration;
 import com.vaadin.shared.ui.treegrid.NodeCollapseRpc;
 import com.vaadin.shared.ui.treegrid.TreeGridState;
 import com.vaadin.ui.declarative.DesignAttributeHandler;
@@ -40,7 +43,7 @@ import com.vaadin.ui.declarative.DesignContext;
 import com.vaadin.ui.declarative.DesignFormatter;
 import com.vaadin.ui.renderers.AbstractRenderer;
 import com.vaadin.ui.renderers.Renderer;
-
+import com.vaadin.util.ReflectTools;
 
 /**
  * A grid component for displaying hierarchical tabular data.
@@ -53,6 +56,123 @@ import com.vaadin.ui.renderers.Renderer;
  */
 public class TreeGrid<T> extends Grid<T> {
 
+    /**
+     * Item expand event listener.
+     * 
+     * @author Vaadin Ltd
+     * @since 8.1
+     * @param <T>
+     *            the expanded item's type
+     */
+    @FunctionalInterface
+    public interface ExpandListener<T> extends Serializable {
+
+        public static final Method EXPAND_METHOD = ReflectTools.findMethod(
+                ExpandListener.class, "itemExpand", ExpandEvent.class);
+
+        /**
+         * Callback method for when an item has been expanded.
+         * 
+         * @param event
+         *            the expand event
+         */
+        public void itemExpand(ExpandEvent<T> event);
+    }
+
+    /**
+     * Item collapse event listener.
+     * 
+     * @author Vaadin Ltd
+     * @since 8.1
+     * @param <T>
+     *            the collapsed item's type
+     */
+    @FunctionalInterface
+    public interface CollapseListener<T> extends Serializable {
+
+        public static final Method COLLAPSE_METHOD = ReflectTools.findMethod(
+                CollapseListener.class, "itemCollapse", CollapseEvent.class);
+
+        /**
+         * Callback method for when an item has been collapsed.
+         * 
+         * @param event
+         *            the collapse event
+         */
+        public void itemCollapse(CollapseEvent<T> event);
+    }
+
+    /**
+     * An event that is fired when an item is expanded.
+     * 
+     * @author Vaadin Ltd
+     * @since 8.1
+     * @param <T>
+     *            the expanded item's type
+     */
+    public static class ExpandEvent<T> extends Component.Event {
+
+        private final T expandedItem;
+
+        /**
+         * Construct an expand event.
+         * 
+         * @param source
+         *            the tree grid this event originated from
+         * @param item
+         *            the item that was expanded
+         */
+        public ExpandEvent(TreeGrid<T> source, T expandedItem) {
+            super(source);
+            this.expandedItem = expandedItem;
+        }
+
+        /**
+         * Get the expanded item that triggered this event.
+         * 
+         * @return the expanded item
+         */
+        public T getExpandedItem() {
+            return expandedItem;
+        }
+    }
+
+    /**
+     * An event that is fired when an item is collapsed. Note that expanded
+     * subtrees of the collapsed item will not trigger collapse events.
+     * 
+     * @author Vaadin Ltd
+     * @since 8.1
+     * @param <T>
+     *            collapsed item type
+     */
+    public static class CollapseEvent<T> extends Component.Event {
+
+        private final T collapsedItem;
+
+        /**
+         * Construct a collapse event.
+         * 
+         * @param source
+         *            the tree grid this event originated from
+         * @param item
+         *            the item that was collapsed
+         */
+        public CollapseEvent(TreeGrid<T> source, T collapsedItem) {
+            super(source);
+            this.collapsedItem = collapsedItem;
+        }
+
+        /**
+         * Get the collapsed item that triggered this event.
+         * 
+         * @return the collapsed item
+         */
+        public T getCollapsedItem() {
+            return collapsedItem;
+        }
+    }
+
     public TreeGrid() {
         super(new HierarchicalDataCommunicator<>());
 
@@ -62,13 +182,45 @@ public class TreeGrid<T> extends Grid<T> {
                     boolean collapse) {
                 if (collapse) {
                     getDataCommunicator().doCollapse(rowKey, rowIndex);
+                    fireCollapseEvent(
+                            getDataCommunicator().getKeyMapper().get(rowKey));
                 } else {
                     getDataCommunicator().doExpand(rowKey, rowIndex);
+                    fireExpandEvent(
+                            getDataCommunicator().getKeyMapper().get(rowKey));
                 }
             }
         });
     }
 
+    /**
+     * Adds an ExpandListener to this TreeGrid.
+     * 
+     * @see ExpandEvent
+     * 
+     * @param listener
+     *            the listener to add
+     * @return a registration for the listener
+     */
+    public Registration addExpandListener(ExpandListener<T> listener) {
+        return addListener(ExpandEvent.class, listener,
+                ExpandListener.EXPAND_METHOD);
+    }
+
+    /**
+     * Adds a CollapseListener to this TreeGrid.
+     * 
+     * @see CollapseEvent
+     * 
+     * @param listener
+     *            the listener to add
+     * @return a registration for the listener
+     */
+    public Registration addCollapseListener(CollapseListener<T> listener) {
+        return addListener(CollapseEvent.class, listener,
+                CollapseListener.COLLAPSE_METHOD);
+    }
+
     /**
      * Sets the data items of this component provided as a collection.
      * <p>
@@ -336,4 +488,24 @@ public class TreeGrid<T> extends Grid<T> {
             }
         };
     }
+
+    /**
+     * Emit an expand event.
+     * 
+     * @param item
+     *            the item that was expanded
+     */
+    private void fireExpandEvent(T item) {
+        fireEvent(new ExpandEvent<>(this, item));
+    }
+
+    /**
+     * Emit a collapse event.
+     * 
+     * @param item
+     *            the item that was collapsed
+     */
+    private void fireCollapseEvent(T item) {
+        fireEvent(new CollapseEvent<>(this, item));
+    }
 }
index 7998537a6eac538cd2f88710e54c5ea3bd6f06aa..3b58e6c75e157f38225d2dec726f2ba1a42414fc 100644 (file)
@@ -54,6 +54,7 @@ public class TreeGridBasicFeatures extends AbstractComponentTest<TreeGrid> {
 
         createDataProviderSelect();
         createHierarchyColumnSelect();
+        createListenerMenu();
     }
 
     private void initializeDataProviders() {
@@ -102,6 +103,16 @@ public class TreeGridBasicFeatures extends AbstractComponentTest<TreeGrid> {
                 (treeGrid, value, data) -> treeGrid.setHierarchyColumn(value));
     }
 
+    @SuppressWarnings("unchecked")
+    private void createListenerMenu() {
+        createListenerAction("Collapse listener", "State",
+                treeGrid -> treeGrid.addCollapseListener(event -> log(
+                        "Item collapsed: " + event.getCollapsedItem())));
+        createListenerAction("Expand listener", "State",
+                treeGrid -> treeGrid.addExpandListener(event -> log(
+                        "Item expanded: " + event.getExpandedItem())));
+    }
+
     static class HierarchicalTestBean {
 
         private final String id;
index b01a6273e251ae1488c2472bf42157931fad54c9..215bef95d24b12d44281d0876001bd0a6ecd3a65 100644 (file)
@@ -119,6 +119,34 @@ public class TreeGridBasicFeaturesTest extends MultiBrowserTest {
                 .isElementPresent(By.className("v-tree-grid-expander")));
     }
 
+    @Test
+    public void expand_and_collapse_listeners() {
+        selectMenuPath("Component", "State", "Expand listener");
+        selectMenuPath("Component", "State", "Collapse listener");
+
+        Assert.assertFalse(logContainsText("Item expanded: 0 | 0"));
+        Assert.assertFalse(logContainsText("Item collapsed: 0 | 0"));
+
+        grid.collapseWithClick(0);
+
+        Assert.assertTrue(logContainsText("Item expanded: 0 | 0"));
+        Assert.assertFalse(logContainsText("Item collapsed: 0 | 0"));
+
+        grid.collapseWithClick(0);
+
+        Assert.assertTrue(logContainsText("Item expanded: 0 | 0"));
+        Assert.assertTrue(logContainsText("Item collapsed: 0 | 0"));
+
+        selectMenuPath("Component", "State", "Expand listener");
+        selectMenuPath("Component", "State", "Collapse listener");
+
+        grid.collapseWithClick(1);
+        grid.collapseWithClick(1);
+
+        Assert.assertFalse(logContainsText("Item expanded: 0 | 1"));
+        Assert.assertFalse(logContainsText("Item collapsed: 0 | 1"));
+    }
+
     private void assertCellTexts(int startRowIndex, int cellIndex,
             String[] cellTexts) {
         int index = startRowIndex;