new TreeData<T>().addItems(rootItems, childItemProvider)));
}
+ /**
+ * Sets the root data items of this component provided as a stream and
+ * recursively populates them with child items with the given value
+ * provider.
+ * <p>
+ * The provided items are wrapped into a {@link TreeDataProvider} backed by
+ * a flat {@link TreeData} structure. The data provider instance is used as
+ * a parameter for the {@link #setDataProvider(DataProvider)} method. It
+ * means that the items collection can be accessed later on via
+ * {@link #getTreeData()}:
+ *
+ * <pre>
+ * <code>
+ * Stream<Person> grandParents = getGrandParents();
+ * HasHierarchicalDataProvider<Person> treeGrid = new TreeGrid<>();
+ * treeGrid.setItems(grandParents, Person::getChildren);
+ * ...
+ *
+ * TreeData<Person> data = treeGrid.getTreeData();
+ * </code>
+ * </pre>
+ * <p>
+ * The returned {@link TreeData} instance may be used as-is to add, remove
+ * or modify items in the hierarchy. These modifications to the object are
+ * not automatically reflected back to the TreeGrid. Items modified should
+ * be refreshed with {@link HierarchicalDataProvider#refreshItem(Object)}
+ * and when adding or removing items
+ * {@link HierarchicalDataProvider#refreshAll()} should be called.
+ *
+ * @param rootItems
+ * the root items to display, not {@code null}
+ * @param childItemProvider
+ * the value provider used to recursively populate the given root
+ * items with child items, not {@code null}
+ */
+ public default void setItems(Stream<T> rootItems,
+ ValueProvider<T, Stream<T>> childItemProvider) {
+ Objects.requireNonNull(rootItems, "Given root items may not be null");
+ Objects.requireNonNull(childItemProvider,
+ "Given child item provider may not be null");
+ setDataProvider(new TreeDataProvider<>(
+ new TreeData<T>().addItems(rootItems, childItemProvider)));
+ }
+
/**
* Sets the data items of this component provided as a collection.
* <p>
import java.util.List;
import java.util.Map;
import java.util.Objects;
+import java.util.stream.Collectors;
import java.util.stream.Stream;
import com.vaadin.data.provider.TreeDataProvider;
return this;
}
+ /**
+ * Adds the given items as root items and uses the given value provider to
+ * recursively populate children of the root items.
+ *
+ * @param rootItems
+ * the root items to add
+ * @param childItemProvider
+ * the value provider used to recursively populate this TreeData
+ * from the given root items
+ * @return this
+ */
+ public TreeData<T> addItems(Stream<T> rootItems,
+ ValueProvider<T, Stream<T>> childItemProvider) {
+ // Must collect to lists since the algorithm iterates multiple times
+ return addItems(rootItems.collect(Collectors.toList()),
+ item -> childItemProvider.apply(item)
+ .collect(Collectors.toList()));
+ }
+
/**
* Remove a given item from this structure. Additionally, this will
* recursively remove any descendants of the item.
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
+import java.util.stream.Stream;
import org.junit.Assert;
import org.junit.Test;
import com.vaadin.data.TreeData;
import com.vaadin.server.SerializablePredicate;
-public class TreeDataProviderTest extends
- DataProviderTestBase<TreeDataProvider<StrBean>> {
+public class TreeDataProviderTest
+ extends DataProviderTestBase<TreeDataProvider<StrBean>> {
private TreeData<StrBean> data;
private List<StrBean> flattenedData;
@Test(expected = IllegalArgumentException.class)
public void treeData_add_item_parent_not_in_hierarchy_throws() {
- new TreeData<>().addItem(new StrBean("", 0, 0),
- new StrBean("", 0, 0));
+ new TreeData<>().addItem(new StrBean("", 0, 0), new StrBean("", 0, 0));
}
@Test(expected = NullPointerException.class)
Assert.assertEquals(stringData.getChildren("a/b"), Arrays.asList());
}
+ @Test
+ public void populate_treeData_with_stream_child_item_provider() {
+ TreeData<String> stringData = new TreeData<>();
+ Stream<String> rootItems = Stream.of("a", "b", "c");
+ stringData.addItems(rootItems, item -> {
+ if (item.length() >= 3 || item.startsWith("c")) {
+ return Stream.empty();
+ }
+ return Stream.of(item + "/a", item + "/b", item + "/c");
+ });
+ Assert.assertEquals(stringData.getChildren("a"),
+ Arrays.asList("a/a", "a/b", "a/c"));
+ Assert.assertEquals(stringData.getChildren("b"),
+ Arrays.asList("b/a", "b/b", "b/c"));
+ Assert.assertEquals(stringData.getChildren("c"), Arrays.asList());
+ Assert.assertEquals(stringData.getChildren("a/b"), Arrays.asList());
+ }
+
@Test
public void setFilter() {
getDataProvider().setFilter(item -> item.getValue().equals("Xyz")