Как установить отступ ячейки в TreeView в Javafx - PullRequest
0 голосов
/ 16 ноября 2018

Я работаю над TreeView, который представляет управляющую программу робота, каждый TreeCell представляет оператор, а TreeCell может быть вложен в другой. Как и в программировании, операторы могут быть вложены в операторы if или for.

Здесь я создал простую демонстрацию, заполненную случайными блоками.

Снимок экрана с демонстрацией

Чтобы настроить отображение TreeCell, я создал класс, расширяющий TreeCell:

public class TreeDataCell extends TreeCell<TreeData> {

    public void updateItem(TreeData item, boolean empty) {
        super.updateItem(item, empty);

        setText(null);
        if (item == null || empty) {
            setGraphic(null);
        } else {
            setGraphic(getCellGraphic(item));
        }
    }

    private Group getCellGraphic(TreeData data) {

        Group grp = new Group();

        VBox vbox = new VBox();
        vbox.setMinWidth(100);
        vbox.setMaxWidth(200);
        vbox.setBorder(new Border(new BorderStroke(
                Color.LIGHTGRAY.darker(), 
                BorderStrokeStyle.SOLID, 
                new CornerRadii(10.0), 
                new BorderWidths(2.0))));
        vbox.setBackground(new Background(new BackgroundFill(Color.LIGHTGRAY, new CornerRadii(10.0), null)));
        vbox.setEffect(new DropShadow(2.0, 3.0, 3.0, Color.DIMGRAY));

        Region header = new Region();
        header.setPrefHeight(5.0);

        Region footer = new Region();
        footer.setPrefHeight(5.0);

        Label labTitle = new Label();
        labTitle.setFont(new Font("San Serif", 20));
        labTitle.setText(data.getTitle());

        Label labDesc = null;
        if (data.getDescription() != null) {
            labDesc = new Label();
            labDesc.setWrapText(true);
            labDesc.setText(data.getDescription());
        }

        vbox.getChildren().addAll(header, labTitle);
        if (labDesc != null) {
            vbox.getChildren().add(labDesc);
        }
        vbox.getChildren().add(footer);
        grp.getChildren().add(vbox);

        return grp;
    }
}

TreeData - это простой класс, содержащий 2 String с:

public class TreeData {
    private String title;
    private String desc;
    /* getters + setters */
}

Как видите, отступ между двумя уровнями слишком мал, и мы едва можем видеть вложение операторов.

Я жестко программирую все стили в Java, так как я еще не изучил FXML + CSS.

Я хотел бы знать, возможно ли установить размер отступа в Java? Я не могу найти API для этой цели. Кроме того, можно ли рисовать линии между родительским узлом и его дочерними элементами , как JTree в Swing?

Спасибо.

1 Ответ

0 голосов
/ 16 ноября 2018

Относительно наличия строк, подобных JTree, нет встроенного способа сделать это с JavaFX 11. Есть запрос функции ( JDK-8090579 ), но, похоже, нет любые планы по его реализации. Вы можете реализовать это самостоятельно, но я не уверен, как.

Что касается изменения отступа TreeCell s, проще всего использовать CSS.

Как указано в Справочном руководстве по JavaFX CSS , TreeCell имеет свойство CSS с именем -fx-indent, значение которого равно <size>. Вы можете установить это свойство с помощью таблицы стилей или встроить его через свойство style . Пример использования встроенных стилей:

public class TreeDataCell extends TreeCell<TreeData> {

    public TreeDataCell() {
        setStyle("-fx-indent: <size>;");
    }

}

Однако, поскольку вы в настоящее время не используете CSS или FXML, существует еще одна опция, представляющая собой чисто код: изменение свойства indent для TreeCellSkin. Этот класс стал открытым API в JavaFX 9. Может быть эквивалентный внутренний API в JavaFX 8, но я не уверен.

По умолчанию Skin из TreeCell будет экземпляром TreeCellSkin. Это означает, что вы можете получить этот скин и установить значение отступа по мере необходимости. Вы должны быть осторожны, так как кожа лениво создана; оно не обязательно будет доступно до тех пор, пока TreeView не станет частью отображаемого окна.

Если вы хотите установить свойство только один раз, можно перехватить скин внутри createDefaultSkin():

public class TreeDataCell extends TreeCell<TreeData> {

    @Override
    protected Skin<?> createDefaultSkin() {
        TreeCellSkin<?> skin = (TreeCellSkin<?>) super.createDefaultSkin();
        skin.setIndent(/* your value */);
        return skin;
    }

}

Вы также можете расширить TreeCellSkin и настроить его. Просто не забудьте переопределить createDefaultSkin() и вернуть вам собственную реализацию скина.

...