diff options
author | Aleksi Hietanen <aleksi@vaadin.com> | 2017-02-23 09:34:59 +0200 |
---|---|---|
committer | Pekka Hyvönen <pekka@vaadin.com> | 2017-02-23 09:34:59 +0200 |
commit | 6783bca88d4cf0c8944e84a0fef0a219c0b9a4d0 (patch) | |
tree | 4fe5a5752482f73c902beb4b5e05e647a2b6203b /server | |
parent | 813a99cfeff9d9cd70d77bd5d9ae75f5fa7b2ff5 (diff) | |
download | vaadin-framework-6783bca88d4cf0c8944e84a0fef0a219c0b9a4d0.tar.gz vaadin-framework-6783bca88d4cf0c8944e84a0fef0a219c0b9a4d0.zip |
Add initial implementation of TreeGrid (#8572)
* Add initial implementation of TreeGrid
* Refactor TreeGrid and related classes
* Fix potential class cast exception in TreeGrid#getDataProvider
* Add smoke tests for TreeGrid
* Add communication constants for TreeGrid
Use shared constant values for hierarchy data serialization and deserialization
* Fix event ordering in TreeGrid, add javadocs, keyboard navigation test
* TreeGrid improvements
* Add TreeGrid.getDataProvider to StateGetDoesNotMarkDirtyTest exclude list
* Merge remote-tracking branch 'github/master' into tree-grid
* Remove getEscalator override from TreeGrid
Diffstat (limited to 'server')
4 files changed, 205 insertions, 1 deletions
diff --git a/server/src/main/java/com/vaadin/data/provider/HierarchicalDataProvider.java b/server/src/main/java/com/vaadin/data/provider/HierarchicalDataProvider.java new file mode 100644 index 0000000000..ec54a3a138 --- /dev/null +++ b/server/src/main/java/com/vaadin/data/provider/HierarchicalDataProvider.java @@ -0,0 +1,39 @@ +/* + * 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.data.provider; + +/** + * + * @author Vaadin Ltd + * @since 8.1 + * + * @param <T> + * @param <F> + */ +public interface HierarchicalDataProvider<T, F> extends DataProvider<T, F> { + + public int getDepth(T item); + + public boolean isRoot(T item); + + public T getParent(T item); + + public boolean isCollapsed(T item); + + public boolean hasChildren(T item); + + public void setCollapsed(T item, boolean b); +} diff --git a/server/src/main/java/com/vaadin/ui/Grid.java b/server/src/main/java/com/vaadin/ui/Grid.java index 186be328f4..c3456075c3 100644 --- a/server/src/main/java/com/vaadin/ui/Grid.java +++ b/server/src/main/java/com/vaadin/ui/Grid.java @@ -646,7 +646,7 @@ public class Grid<T> extends AbstractListing<T> implements HasComponents, Type type = null; try { type = getState(false).getClass() - .getDeclaredField(diffStateKey).getGenericType(); + .getField(diffStateKey).getGenericType(); } catch (NoSuchFieldException | SecurityException e) { e.printStackTrace(); } diff --git a/server/src/main/java/com/vaadin/ui/TreeGrid.java b/server/src/main/java/com/vaadin/ui/TreeGrid.java new file mode 100644 index 0000000000..f438df4e8f --- /dev/null +++ b/server/src/main/java/com/vaadin/ui/TreeGrid.java @@ -0,0 +1,164 @@ +/* + * 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.ui; + +import java.util.Collection; +import java.util.Objects; +import java.util.stream.Stream; + +import com.vaadin.data.provider.DataProvider; +import com.vaadin.data.provider.HierarchicalDataProvider; +import com.vaadin.shared.ui.treegrid.NodeCollapseRpc; +import com.vaadin.shared.ui.treegrid.TreeGridCommunicationConstants; +import com.vaadin.shared.ui.treegrid.TreeGridState; + +import elemental.json.Json; +import elemental.json.JsonObject; + +/** + * A grid component for displaying hierarchical tabular data. + * + * @author Vaadin Ltd + * @since 8.1 + * + * @param <T> + * the grid bean type + */ +public class TreeGrid<T> extends Grid<T> { + + public TreeGrid() { + super(); + + // Attaches hierarchy data to the row + addDataGenerator((item, rowData) -> { + + JsonObject hierarchyData = Json.createObject(); + hierarchyData.put(TreeGridCommunicationConstants.ROW_DEPTH, + getDataProvider().getDepth(item)); + + boolean isLeaf = !getDataProvider().hasChildren(item); + if (isLeaf) { + hierarchyData.put(TreeGridCommunicationConstants.ROW_LEAF, + true); + } else { + hierarchyData.put(TreeGridCommunicationConstants.ROW_COLLAPSED, + getDataProvider().isCollapsed(item)); + hierarchyData.put(TreeGridCommunicationConstants.ROW_LEAF, + false); + } + + // add hierarchy information to row as metadata + rowData.put( + TreeGridCommunicationConstants.ROW_HIERARCHY_DESCRIPTION, + hierarchyData); + }); + + registerRpc(new NodeCollapseRpc() { + @Override + public void toggleCollapse(String rowKey) { + T item = getDataCommunicator().getKeyMapper().get(rowKey); + TreeGrid.this.toggleCollapse(item); + } + }); + } + + // TODO: construct a "flat" in memory hierarchical data provider? + @Override + public void setItems(Collection<T> items) { + throw new UnsupportedOperationException("Not implemented"); + } + + @Override + public void setItems(Stream<T> items) { + throw new UnsupportedOperationException("Not implemented"); + } + + @Override + public void setItems(T... items) { + throw new UnsupportedOperationException("Not implemented"); + } + + @Override + public void setDataProvider(DataProvider<T, ?> dataProvider) { + if (!(dataProvider instanceof HierarchicalDataProvider)) { + throw new IllegalArgumentException( + "TreeGrid only accepts hierarchical data providers"); + } + super.setDataProvider(dataProvider); + } + + /** + * Set the column that displays the hierarchy of this grid's data. By + * default the hierarchy will be displayed in the first column. + * <p> + * Setting a hierarchy column by calling this method also sets the column to + * be visible and not hidable. + * + * @see Column#setId(String) + * + * @param id + * id of the column to use for displaying hierarchy + */ + public void setHierarchyColumn(String id) { + Objects.requireNonNull(id, "id may not be null"); + if (getColumn(id) == null) { + throw new IllegalArgumentException("No column found for given id"); + } + getColumn(id).setHidden(false); + getColumn(id).setHidable(false); + getState().hierarchyColumnId = getInternalIdForColumn(getColumn(id)); + } + + @Override + protected TreeGridState getState() { + return (TreeGridState) super.getState(); + } + + @Override + protected TreeGridState getState(boolean markAsDirty) { + return (TreeGridState) super.getState(markAsDirty); + } + + /** + * Toggle the expansion of an item in this grid. If the item is already + * expanded, it will be collapsed. + * <p> + * Toggling expansion on a leaf item in the hierarchy will have no effect. + * + * @param item + * the item to toggle expansion for + */ + public void toggleCollapse(T item) { + getDataProvider().setCollapsed(item, + !getDataProvider().isCollapsed(item)); + getDataCommunicator().reset(); + } + + @Override + public HierarchicalDataProvider<T, ?> getDataProvider() { + DataProvider<T, ?> dataProvider = super.getDataProvider(); + // FIXME DataCommunicator by default has a CallbackDataProvider if no + // DataProvider is set, resulting in a class cast exception if we don't + // check it here. + + // Once fixed, remove this method from the exclude list in + // StateGetDoesNotMarkDirtyTest + if (!(dataProvider instanceof HierarchicalDataProvider)) { + throw new IllegalStateException("No data provider has been set."); + } + return (HierarchicalDataProvider<T, ?>) dataProvider; + } +} diff --git a/server/src/test/java/com/vaadin/tests/server/component/StateGetDoesNotMarkDirtyTest.java b/server/src/test/java/com/vaadin/tests/server/component/StateGetDoesNotMarkDirtyTest.java index 7a11cf4df6..3b4c2413f9 100644 --- a/server/src/test/java/com/vaadin/tests/server/component/StateGetDoesNotMarkDirtyTest.java +++ b/server/src/test/java/com/vaadin/tests/server/component/StateGetDoesNotMarkDirtyTest.java @@ -31,6 +31,7 @@ public class StateGetDoesNotMarkDirtyTest { excludedMethods.add("getConnectorId"); excludedMethods.add("getContent"); excludedMethods.add("com.vaadin.ui.Grid:getSelectAllCheckBoxVisible"); + excludedMethods.add("com.vaadin.ui.TreeGrid:getDataProvider"); } @Test |