Стрелка является частью disclosureNode
из TreeCell
.Если этот параметр не указан, скин TreeCell
отвечает за предоставление узла раскрытия по умолчанию (например, треугольника).Это указано в документации по установщику свойств:
Узел, который будет использоваться в качестве треугольника «раскрытия» или переключателя, используемого для разворачивания и свертывания элементов.Это используется только в случае элемента в дереве, который содержит дочерние элементы.Если не указано, реализация SkinCell TreeCell отвечает за предоставление узла раскрытия по умолчанию.
Тем не менее, глядя на TreeCellSkin
, кажется, что не предоставляет узел раскрытия по умолчанию.Вместо этого это, кажется, обрабатывается TreeViewSkin
(как в JavaFX 8, так и в JavaFX 11).Рассматривая реализацию, узел раскрытия по умолчанию - StackPane
с дочерним элементом StackPane
, который функционирует как фактическая стрелка.Их класс стиля - tree-disclosure-node
и arrow
соответственно.Обратите внимание, что это нигде не отражено в документации, включая Справочное руководство по JavaFX CSS .
Самый простой и наименее подверженный ошибкам способ скрыть корневой узел раскрытия информации, на мой взгляд,использовать CSS.Единственная проблема здесь заключается в том, что TreeCell
не предоставляет возможности нацеливаться только на корневую ячейку.Но это все еще может быть достигнуто путем создания подкласса TreeCell
и предоставления нашего собственного PseudoClass
.Затем мы устанавливаем cellFactory
на нашем TreeView
.
. Чтобы установить графический объект корня, установите свойство TreeItem.graphic
корня TreeItem
.
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";
}
Некоторые примечания:
- Поскольку я связал свойство
TreeCell.graphic
со свойством TreeItem.graphic
в моей реализации ячейки, вы не сможете установить графику из CSS.Вы можете изменить это, чтобы просто установить графику, а не связывать, чтобы включить эту функцию.Тогда вам не нужно будет устанавливать графическое изображение корня TreeItem
через код, но вы можете сделать .custom-tree-cell:root { -fx-graphic: ...; }
. - Это не удаляет узел раскрытия, он просто делает егоне имеют ширины и высоты.
- Это решение основано на деталях реализации;будьте осторожны при смене версий JavaFX.Я пробовал это только на JavaFX 11.0.2, но я считаю, что это должно работать и для JavaFX 8.