aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAdam Wagner <wbadam@users.noreply.github.com>2017-07-18 13:30:33 +0200
committerHenri Sara <henri.sara@gmail.com>2017-07-18 14:30:33 +0300
commita8a6d25fe93002d8d11f958e9ddadc5c49604174 (patch)
treed6917a1f074caecbe01217e78a918aa9220cf791
parent3c5dd1fdb7e8feca8e9e28e2bdb2a0b2d7055f3f (diff)
downloadvaadin-framework-a8a6d25fe93002d8d11f958e9ddadc5c49604174.tar.gz
vaadin-framework-a8a6d25fe93002d8d11f958e9ddadc5c49604174.zip
Add methods to change parent and to change child's position in hierarchical data (#9673)
Resolves #9674
-rw-r--r--server/src/main/java/com/vaadin/data/TreeData.java83
-rw-r--r--server/src/test/java/com/vaadin/data/provider/TreeDataProviderTest.java45
2 files changed, 128 insertions, 0 deletions
diff --git a/server/src/main/java/com/vaadin/data/TreeData.java b/server/src/main/java/com/vaadin/data/TreeData.java
index b0bdcde835..bebf312614 100644
--- a/server/src/main/java/com/vaadin/data/TreeData.java
+++ b/server/src/main/java/com/vaadin/data/TreeData.java
@@ -368,6 +368,89 @@ public class TreeData<T> implements Serializable {
}
/**
+ * Moves an item to become a child of the given parent item. The new parent
+ * item must exist in the hierarchy. Setting the parent to {@code null}
+ * makes the item a root item. After making changes to the tree data, {@link
+ * TreeDataProvider#refreshAll()} should be called.
+ *
+ * @param item
+ * the item to be set as the child of {@code parent}
+ * @param parent
+ * the item to be set as parent or {@code null} to set the item as
+ * root
+ * @since 8.1
+ */
+ public void setParent(T item, T parent) {
+ if (!contains(item)) {
+ throw new IllegalArgumentException(
+ "Item '" + item + "' not in the hierarchy");
+ }
+
+ if (parent != null && !contains(parent)) {
+ throw new IllegalArgumentException(
+ "Parent needs to be added before children. "
+ + "To set as root item, call with parent as null");
+ }
+
+ if (item.equals(parent)) {
+ throw new IllegalArgumentException(
+ "Item cannot be the parent of itself");
+ }
+
+ T oldParent = itemToWrapperMap.get(item).getParent();
+
+ if (!Objects.equals(oldParent, parent)) {
+ // Remove item from old parent's children
+ itemToWrapperMap.get(oldParent).removeChild(item);
+
+ // Add item to parent's children
+ itemToWrapperMap.get(parent).addChild(item);
+
+ // Set item's new parent
+ itemToWrapperMap.get(item).setParent(parent);
+ }
+ }
+
+ /**
+ * Moves an item to the position immediately after a sibling item. The two
+ * items must have the same parent. After making changes to the tree data,
+ * {@link TreeDataProvider#refreshAll()} should be called.
+ *
+ * @param item
+ * the item to be moved
+ * @param sibling
+ * the item after which the moved item will be located
+ * @since 8.1
+ */
+ public void moveAfterSibling(T item, T sibling) {
+ if (!contains(item)) {
+ throw new IllegalArgumentException(
+ "Item '" + item + "' not in the hierarchy");
+ }
+
+ if (!contains(sibling)) {
+ throw new IllegalArgumentException(
+ "Item '" + sibling + "' not in the hierarchy");
+ }
+
+ T parent = itemToWrapperMap.get(item).getParent();
+
+ if (!Objects
+ .equals(parent, itemToWrapperMap.get(sibling).getParent())) {
+ throw new IllegalArgumentException(
+ "Items '" + item + "' and '" + sibling
+ + "' don't have the same parent");
+ }
+
+ List<T> children = itemToWrapperMap.get(parent).getChildren();
+
+ // Move item to the position after the sibling
+ // If sibling is null, item is moved to the first position
+ children.remove(item);
+ children.add(children.indexOf(sibling) + 1, item);
+ }
+
+ /**
* Check whether the given item is in this hierarchy.
*
* @param item
diff --git a/server/src/test/java/com/vaadin/data/provider/TreeDataProviderTest.java b/server/src/test/java/com/vaadin/data/provider/TreeDataProviderTest.java
index 186ed14e8a..8232d2fc45 100644
--- a/server/src/test/java/com/vaadin/data/provider/TreeDataProviderTest.java
+++ b/server/src/test/java/com/vaadin/data/provider/TreeDataProviderTest.java
@@ -81,6 +81,51 @@ public class TreeDataProviderTest
}
@Test
+ public void treeData_set_parent() {
+ StrBean item1 = rootData.get(0);
+ StrBean item2 = rootData.get(1);
+ Assert.assertEquals(0, data.getChildren(item2).size());
+ Assert.assertEquals(10, data.getRootItems().size());
+
+ // Move item1 as item2's child
+ data.setParent(item1, item2);
+ Assert.assertEquals(1, data.getChildren(item2).size());
+ Assert.assertEquals(9, data.getRootItems().size());
+ Assert.assertEquals(item1, data.getChildren(item2).get(0));
+
+ // Move back to root
+ data.setParent(item1, null);
+ Assert.assertEquals(0, data.getChildren(item2).size());
+ Assert.assertEquals(10, data.getRootItems().size());
+ }
+
+ @Test
+ public void treeData_move_after_sibling() {
+ StrBean root0 = rootData.get(0);
+ StrBean root9 = rootData.get(9);
+ Assert.assertEquals(root0, data.getRootItems().get(0));
+ Assert.assertEquals(root9, data.getRootItems().get(9));
+
+ // Move to last position
+ data.moveAfterSibling(root0, root9);
+ Assert.assertEquals(root0, data.getRootItems().get(9));
+ Assert.assertEquals(root9, data.getRootItems().get(8));
+
+ // Move back to first position
+ data.moveAfterSibling(root0, null);
+ Assert.assertEquals(root0, data.getRootItems().get(0));
+ Assert.assertEquals(root9, data.getRootItems().get(9));
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void treeData_move_after_sibling_different_parents() {
+ StrBean root0 = rootData.get(0);
+ StrBean wrongSibling = data.getChildren(root0).get(0);
+
+ data.moveAfterSibling(root0, wrongSibling);
+ }
+
+ @Test
public void treeData_root_items() {
TreeData<String> data = new TreeData<>();
TreeData<String> dataVarargs = new TreeData<>();