Browse Source

Add methods to change parent and to change child's position in hierarchical data (#9673)

Resolves #9674
tags/8.1.0.rc2
Adam Wagner 6 years ago
parent
commit
a8a6d25fe9

+ 83
- 0
server/src/main/java/com/vaadin/data/TreeData.java View File

@@ -367,6 +367,89 @@ public class TreeData<T> implements Serializable {
.unmodifiableList(itemToWrapperMap.get(item).getChildren());
}

/**
* 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.
*

+ 45
- 0
server/src/test/java/com/vaadin/data/provider/TreeDataProviderTest.java View File

@@ -80,6 +80,51 @@ public class TreeDataProviderTest
Assert.assertTrue(data.getChildren(null).contains(item));
}

@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<>();

Loading…
Cancel
Save