From 5cf5f5c6a88e870e768200cfb4629c058f51c67c Mon Sep 17 00:00:00 2001 From: Florian Hoelzl <hoelzl@fortiss.org> Date: Tue, 28 Jan 2020 14:20:31 +0100 Subject: [PATCH] Kernel: DynamicTreeTableUIProvider filter base implementation. Issue-Ref: 3907 Issue-Url: https://af3-developer.fortiss.org/issues/3907 Signed-off-by: Florian Hoelzl <hoelzl@fortiss.org> --- .../ui/javafx/control/treetableview/.ratings | 6 +-- .../DynamicTreeContentProviderBase.java | 29 ++++++++++--- .../treetableview/DynamicTreeItem.java | 17 ++++++-- .../treetableview/DynamicTreeTableViewer.java | 41 ++++++++++++++++--- 4 files changed, 75 insertions(+), 18 deletions(-) diff --git a/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/.ratings b/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/.ratings index d804a3a10..15f383373 100644 --- a/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/.ratings +++ b/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/.ratings @@ -1,7 +1,7 @@ -DynamicTreeContentProviderBase.java dff437afeaf7486af05460fa54eca4fa61d7eae6 GREEN -DynamicTreeItem.java afc105cf5acf3d2506d89e0892555100c234ce5b GREEN +DynamicTreeContentProviderBase.java 767a518dc8f4ea755aeff0858d06db41c8721c0d YELLOW +DynamicTreeItem.java f68e85125aecdb2e588450b7652ffa57c4dc9088 YELLOW DynamicTreeTableUIProviderBase.java 7bfc1395283d3dc10026aff5e2e65df88d25f3a7 YELLOW -DynamicTreeTableViewer.java 41bfddb704b5fd7ba546d574103ad01192072d2a YELLOW +DynamicTreeTableViewer.java 3b8850f097093230401aee834fe61a16250c215c YELLOW DynamicTreeUIProviderBase.java 56fe4df4577b35f1e5e6e4c4be189b706c852d52 GREEN DynamicTreeViewer.java da5e24ae57777a482d8e12c8262513d8143bfa93 GREEN DynamicTreeViewerBase.java 47124c847de322a0ae26eb7a114f85ce4bd02d7e GREEN diff --git a/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/DynamicTreeContentProviderBase.java b/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/DynamicTreeContentProviderBase.java index dff437afe..767a518dc 100644 --- a/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/DynamicTreeContentProviderBase.java +++ b/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/DynamicTreeContentProviderBase.java @@ -30,23 +30,42 @@ public abstract class DynamicTreeContentProviderBase<T> { /** Returns the children of the given parent in the tree. */ protected abstract Collection<? extends T> getChildren(T parent); - /** Returns the filer predicate. */ - protected Predicate<Object> getFilterPredicate() { + /** Returns whether the filter input should be enabled. */ + protected boolean enableFiltering() { + return false; + } + + /** + * Returns the filter predicate for the given filter value. The default checks if the object's + * toString() contains the filter value. Sub-classes may override or implement + * {@link #filter(Object, String)}. + */ + protected Predicate<T> getFilterPredicate(String filterValue) { + if(filterValue != null && !"".equals(filterValue.trim())) { + return (o) -> { + return filter(o, filterValue); + }; + } return (o) -> true; } + /** Sub-classes may override to implement simple filter behavior. */ + protected boolean filter(T element, String filterValue) { + return element != null && element.toString().contains(filterValue); + } + /** Returns the sorter comparator. */ - protected Comparator<Object> getSortingComparator() { + protected Comparator<T> getSortingComparator() { return (o1, o2) -> 0; } /** Returns the filtered children of the given element. */ - public final Collection<? extends T> getFilteredSortedChildren(T parent) { + public final Collection<? extends T> getFilteredSortedChildren(T parent, String filterValue) { Collection<? extends T> l = getChildren(parent); if(l == null) { return emptyList(); } - return l.stream().filter(getFilterPredicate()).sorted(getSortingComparator()) + return l.stream().filter(getFilterPredicate(filterValue)).sorted(getSortingComparator()) .collect(toList()); } } diff --git a/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/DynamicTreeItem.java b/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/DynamicTreeItem.java index afc105cf5..f68e85125 100644 --- a/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/DynamicTreeItem.java +++ b/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/DynamicTreeItem.java @@ -21,8 +21,8 @@ import java.util.HashMap; import javafx.scene.control.TreeItem; /** - * {@link TreeItem} with support for dynamic children using the {@link DynamicTreeItem#update()} - * method. + * {@link TreeItem} with support for dynamic children using the + * {@link DynamicTreeItem#update(String)} method. */ public class DynamicTreeItem<T> extends TreeItem<T> { /** The viewer. */ @@ -36,6 +36,14 @@ public class DynamicTreeItem<T> extends TreeItem<T> { /** Updates the children of this item from the underlying content model. */ public void update() { + update(null); + } + + /** + * Updates the children of this item from the underlying content model using the given filter + * value. + */ + public void update(String filterValue) { // remember expanded state of children HashMap<T, TreeItem<T>> expanded = new HashMap<>(); for(TreeItem<T> c : getChildren()) { @@ -45,7 +53,8 @@ public class DynamicTreeItem<T> extends TreeItem<T> { } // get list of children and create tree items getChildren().clear(); - for(T element : viewer.getContentProvider().getFilteredSortedChildren(getValue())) { + DynamicTreeContentProviderBase<T> cp = viewer.getContentProvider(); + for(T element : cp.getFilteredSortedChildren(getValue(), filterValue)) { DynamicTreeItem<T> dti; if(expanded.containsKey(element)) { dti = (DynamicTreeItem<T>)expanded.get(element); @@ -53,7 +62,7 @@ public class DynamicTreeItem<T> extends TreeItem<T> { dti = new DynamicTreeItem<T>(element, viewer); } getChildren().add(dti); - dti.update(); + dti.update(filterValue); } } diff --git a/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/DynamicTreeTableViewer.java b/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/DynamicTreeTableViewer.java index 41bfddb70..3b8850f09 100644 --- a/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/DynamicTreeTableViewer.java +++ b/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/DynamicTreeTableViewer.java @@ -16,17 +16,19 @@ package org.fortiss.tooling.common.ui.javafx.control.treetableview; import javafx.beans.property.SimpleObjectProperty; +import javafx.scene.Parent; import javafx.scene.control.SelectionMode; +import javafx.scene.control.TextField; import javafx.scene.control.TreeItem; import javafx.scene.control.TreeTableColumn; import javafx.scene.control.TreeTableView; import javafx.scene.control.TreeTableView.TreeTableViewSelectionModel; +import javafx.scene.layout.BorderPane; /** - * A JavaFX {@link TreeTableView} based on an {@link DynamicTreeContentProviderBase}, - * {@link DynamicTreeTableUIProviderBase}, and {@link DynamicTreeTableEditingSupportBase}. This - * class is intended to be used as a wrapper for {@link TreeTableView} and its rather complex expert - * API. + * A JavaFX {@link TreeTableView} based on an {@link DynamicTreeContentProviderBase} and + * {@link DynamicTreeTableUIProviderBase}. This class is intended to be used as a wrapper for + * {@link TreeTableView} and its rather complex expert API. * <P> * This class currently supports only a static tree-table layout, i.e., there is no way to alter the * columns unless the developer changes the underlying {@link TreeTableView} directly. Note that if @@ -37,6 +39,12 @@ import javafx.scene.control.TreeTableView.TreeTableViewSelectionModel; public final class DynamicTreeTableViewer<T> extends DynamicTreeViewerBase<T> { /** The {@link TreeTableView} control to be managed. */ private final TreeTableView<T> view; + /** The filter text field if filtering is enabled in content provider. */ + private final TextField filter; + /** The pane for filter and tree widgets. */ + private final BorderPane pane; + /** The content provider of this tree-table. */ + private final DynamicTreeContentProviderBase<T> contentProvider; /** The UI provider of this tree-table. */ private final DynamicTreeTableUIProviderBase<T> uiProvider; @@ -45,9 +53,22 @@ public final class DynamicTreeTableViewer<T> extends DynamicTreeViewerBase<T> { DynamicTreeContentProviderBase<T> contentProvider, DynamicTreeTableUIProviderBase<T> uiProvider) { super(contentProvider); + this.contentProvider = contentProvider; this.uiProvider = uiProvider; // construct view this.view = view; + if(contentProvider.enableFiltering()) { + filter = new TextField(); + filter.textProperty().addListener((obs, oVal, nVal) -> { + update(); + }); + pane = new BorderPane(); + pane.setTop(filter); + pane.setCenter(view); + } else { + filter = null; + pane = null; + } DynamicTreeItem<T> rootItem = new DynamicTreeItem<T>(root, this); view.setRoot(rootItem); view.setShowRoot(showRoot); @@ -76,7 +97,7 @@ public final class DynamicTreeTableViewer<T> extends DynamicTreeViewerBase<T> { public void update() { // wild cast works: see constructor DynamicTreeItem<T> rootItem = (DynamicTreeItem<T>)view.getRoot(); - rootItem.update(); + rootItem.update(filter != null ? filter.getText() : null); } /** Expands items up to the given level. */ @@ -118,7 +139,7 @@ public final class DynamicTreeTableViewer<T> extends DynamicTreeViewerBase<T> { */ @Deprecated public TreeTableColumn<T, String> addColumn(String headerLabel, int prefWidth, - boolean readOnly) { + @SuppressWarnings("unused") boolean readOnly) { return addColumn(headerLabel, prefWidth); } @@ -126,4 +147,12 @@ public final class DynamicTreeTableViewer<T> extends DynamicTreeViewerBase<T> { public TreeTableView<T> getControl() { return view; } + + /** Returns the filter pane or the tree view if filtering is disabled. */ + public Parent getFilterControl() { + if(contentProvider.enableFiltering()) { + return pane; + } + return getControl(); + } } -- GitLab