javafx: Как скрыть «стрелку выпадающего меню» в TreeView? - PullRequest
0 голосов
/ 02 марта 2019

Надеюсь, у всех дела идут хорошо.

Мой вопрос довольно простой: как сделать стрелку в корне TreeView скрытой, если это возможно?Хороший пример того, чего я хочу достичь, можно увидеть в средстве просмотра событий Windows.

enter image description here

В то время как мое приложение javafx похоже на изображение ниже

enter image description here

По умолчанию эта стрелка рядом с транспортными средствами присутствует.

Я прочитал документацию здесь , но я нашел только .showRoot (), который не достигает того, чего я хочу.Я был бы очень признателен за любой ввод, даже если это хитрый способ сделать это (использование свойства x-offset пришло мне в голову).

1 Ответ

0 голосов
/ 03 марта 2019

Стрелка является частью 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";
}

Некоторые примечания:

  1. Поскольку я связал свойство TreeCell.graphic со свойством TreeItem.graphic в моей реализации ячейки, вы не сможете установить графику из CSS.Вы можете изменить это, чтобы просто установить графику, а не связывать, чтобы включить эту функцию.Тогда вам не нужно будет устанавливать графическое изображение корня TreeItem через код, но вы можете сделать .custom-tree-cell:root { -fx-graphic: ...; }.
  2. Это не удаляет узел раскрытия, он просто делает егоне имеют ширины и высоты.
  3. Это решение основано на деталях реализации;будьте осторожны при смене версий JavaFX.Я пробовал это только на JavaFX 11.0.2, но я считаю, что это должно работать и для JavaFX 8.
...