javafx:如何隐藏TreeView中的“下拉箭头”?

问题描述 投票:3回答:1

希望大家都做得好。

我的问题非常基本:如果可能的话,如何隐藏TreeView根部的箭头?在Windows事件查看器中可以看到我想要实现的一个很好的例子。

enter image description here

虽然我的javafx应用程序如下图所示

enter image description here

默认情况下,车辆旁边的箭头存在。

我阅读了文档here,但我只找到.showRoot(),它没有实现我想要的。我真的很感激任何输入,即使它是一种欺骗方式(使用x-offset属性克服了我的想法)。

java javafx tree treeview scenebuilder
1个回答
3
投票

箭头是disclosureNodeTreeCell的一部分。未指定时,TreeCell皮肤负责提供默认的披露节点(例如三角形)。这由property-setter文档说明:

用作“公开”三角形或切换的节点,用于展开和折叠项目。这仅适用于树中包含子项的项。如果未指定,TreeCell的Skin实现负责提供默认的公开节点。

然而,看看TreeCellSkin,它似乎没有提供默认的披露节点。相反,这似乎是由TreeViewSkin处理的(在JavaFX 8和JavaFX 11中)。查看实现,默认的公开节点是一个带有子StackPaneStackPane,它起到实际箭头的作用。他们的风格分别是tree-disclosure-nodearrow。请注意,这似乎没有出现在任何地方,包括JavaFX CSS Reference Guide

在我看来,隐藏根公开节点的最简单且最容易出错的方法是使用CSS。这里唯一的问题是TreeCell无法仅定位根单元格。但这仍然可以通过继承TreeCell并提供我们自己的PseudoClass来实现。然后我们在cellFactory上设置TreeView

要设置根集的图形,请设置根TreeItem.graphicTreeItem属性。


CustomTreeCell

import javafx.beans.InvalidationListener;
import javafx.css.PseudoClass;
import javafx.scene.control.TreeCell;
import javafx.scene.control.TreeView;
import javafx.util.Callback;

public class CustomTreeCell<T> extends TreeCell<T> {

    private static final PseudoClass ROOT = PseudoClass.getPseudoClass("root");

    public static <T> Callback<TreeView<T>, TreeCell<T>> forTreeView() {
        return treeView -> new CustomTreeCell<>();
    }

    public CustomTreeCell() {
        getStyleClass().add("custom-tree-cell");

        InvalidationListener listener = observable -> {
            boolean isRoot = getTreeView() != null && getTreeItem() == getTreeView().getRoot();
            pseudoClassStateChanged(ROOT, isRoot);
        };

        treeViewProperty().addListener(listener);
        treeItemProperty().addListener(listener);
    }

    @Override
    protected void updateItem(T item, boolean empty) {
        super.updateItem(item, empty);
        if (empty || item == null) {
            setText(null);
            graphicProperty().unbind();
            setGraphic(null);
        } else {
            setText(item.toString()); // Really only works if item is a String. Change as needed.
            graphicProperty().bind(getTreeItem().graphicProperty());
        }
    }

}

CSS文件

.custom-tree-cell:root .tree-disclosure-node,
.custom-tree-cell:root .arrow {

    -fx-min-width: 0;
    -fx-pref-width: 0;
    -fx-max-width: 0;

    -fx-min-height: 0;
    -fx-pref-height: 0;
    -fx-max-height: 0;

}

/* Related to question asked in the comments by OP */
.custom-tree-cell > .tree-disclosure-node > .arrow {
    -fx-shape: "M 0 0 L 10 5 L 0 10 L 0 8 L 8 5 L 0 2 Z";
}

一些说明:

  1. 由于我在单元格实现中将TreeCell.graphic属性绑定到TreeItem.graphic属性,因此您将无法从CSS设置图形。您可以修改此设置以简单地设置图形,而不是绑定,以启用该功能。然后你不必通过代码设置根TreeItem的图形,但可以做.custom-tree-cell:root { -fx-graphic: ...; }
  2. 这不会删除公开节点,它只是使它没有宽度,没有高度。
  3. 该解决方案依赖于实现细节;更改JavaFX版本时要小心。我只在JavaFX 11.0.2上尝试过这个,但我相信它也适用于JavaFX 8。
© www.soinside.com 2019 - 2024. All rights reserved.