gpt4 book ai didi

java - TreeView Java FX : hide a node

转载 作者:行者123 更新时间:2023-11-29 06:33:17 27 4
gpt4 key购买 nike

是否有可能在 TreeView 中隐藏一个节点(与它对根的工作方式相同)而不必从树本身中删除该节点?目的是能够为树的某些项目提供过滤器和“显示/隐藏”选项。

感谢所有帮助

谢谢

最佳答案

我找到了这个 article由 Christoph Keimel 撰写,我认为应该可以解决您的问题。

基本上,如果没有 hack,您是做不到的。您可以拥有一个 FilterableTreeItem,它扩展了您在其中创建 FilteredList 的 TreeItem。

public class FilterableTreeItem<T> extends TreeItem<T> {
private final ObservableList<TreeItem<T>> sourceList;

private final ObjectProperty<TreeItemPredicate<T>> predicate = new SimpleObjectProperty<>();

public FilterableTreeItem(T value) {
super(value);
sourceList = FXCollections.observableArrayList();
FilteredList<TreeItem<T>> filteredList = new FilteredList<>(sourceList);

filteredList.predicateProperty().bind(Bindings.createObjectBinding(() -> {
return child -> {
// Set the predicate of child items to force filtering
if (child instanceof FilterableTreeItem) {
FilterableTreeItem<T> filterableChild = (FilterableTreeItem<T>) child;
filterableChild.setPredicate(predicate.get());
}
// If there is no predicate, keep this tree item
if (predicate.get() == null) {
return true;
}
// If there are children, keep this tree item
if (!child.getChildren().isEmpty()) {
return true;
}
// Otherwise ask the TreeItemPredicate
return predicate.get().test(this, child.getValue());
};
}, predicate));

setHiddenFieldChildren(filteredList);
}

/**
* Set the hidden private field {@link TreeItem#children} through reflection and hook the hidden {@link ListChangeListener} in {@link TreeItem#childrenListener} to the list
*
*/
protected void setHiddenFieldChildren(ObservableList<TreeItem<T>> list) {
Field children = ReflectionUtils.findField(getClass(), "children");
children.setAccessible(true);
ReflectionUtils.setField(children, this, list);

Field childrenListener1 = ReflectionUtils.findField(getClass(), "childrenListener");
childrenListener1.setAccessible(true);
Object childrenListener = ReflectionUtils.getField(childrenListener1, this);

list.addListener((ListChangeListener<? super TreeItem<T>>) childrenListener);
}

/**
* Returns the list of children that is backing the filtered list.
*
* @return underlying list of children
*/
public ObservableList<TreeItem<T>> getInternalChildren() {
return sourceList;
}

public final ObjectProperty<TreeItemPredicate<T>> predicateProperty() {
return predicate;
}

public final TreeItemPredicate<T> getPredicate() {
return predicate.get();
}

public final void setPredicate(TreeItemPredicate<T> predicate) {
this.predicate.set(predicate);
}

您还需要 TreeItemPredicate

@FunctionalInterface
public interface TreeItemPredicate<T> {
/**
* Utility method to create a TreeItemPredicate from a given {@link Predicate}
*/
static <T> TreeItemPredicate<T> create(Predicate<T> predicate) {
return (parent, value) -> predicate.test(value);
}

/**
* Evaluates this predicate on the given argument.
*
* @param parent
* the parent tree item of the element or null if there is no
* parent
* @param value
* the value to be tested
* @return {@code true} if the input argument matches the
* predicate,otherwise {@code false}
*/
boolean test(TreeItem<T> parent, T value);
}

然后你把它放在你的 Controller 里

            MyNode myRootNode = myService.getTreeRootNode();

FilterableTreeItem<MyNode> rootItem = new FilterableTreeItem<>(myRootNode);
rootItem.setExpanded(true);

for (MyNode node : myRootNode.getChildren()) {
FilterableTreeItem<MyNode> item = new FilterableTreeItem<>(node);
rootItem.getInternalChildren().add(item);
}


tree.setRoot(rootItem);


rootItem.predicateProperty().bind(Bindings.createObjectBinding(()
-> TreeItemPredicate.<MyNode> create(myNode
-> myNode.isStyled() == hide.getValue())
, hide));

hide 是一个 SimpleBooleanProperty。我的节点有一个 boolean 属性样式。

private final BooleanProperty hide = new SimpleBooleanProperty();

该代码仅允许隐藏样式化的节点或未样式化的节点。我知道这很愚蠢,但我只是做了一个测试

关于java - TreeView Java FX : hide a node,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27183526/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com