JavaFX8 treeTableView customize collapse root item


Question

How can I customize the collapse appearance of a tree root item? By customizing I mean setting an image and center that little triangle(/new image) inside its cell.

Thanks in advance.

1
3
4/11/2014 5:33:45 PM

Accepted Answer

Have a look at the default stylesheet, modena.css, which you can extract from the jfxrt.jar file in jre/lib/ext, or find online. The graphic is defined as a path there:

.tree-cell > .tree-disclosure-node,
.tree-table-row-cell > .tree-disclosure-node {
    -fx-padding: 4 6 4 8;
    -fx-background-color: transparent;
}
.tree-cell > .tree-disclosure-node > .arrow,
.tree-table-row-cell > .tree-disclosure-node > .arrow {
    -fx-background-color: -fx-text-background-color;
    -fx-padding: 0.333333em 0.229em 0.333333em 0.229em; /* 4 */
    -fx-shape: "M 0 -3.5 L 4 0 L 0 3.5 z";
}
.tree-cell:expanded > .tree-disclosure-node > .arrow,
.tree-table-row-cell:expanded > .tree-disclosure-node > .arrow {
    -fx-rotate: 90;
}

You can override these rules in your own css. The arrow referred to in the css is a Region, so you could define a -fx-background-image if you wanted.

5
4/11/2014 7:28:48 PM

The following sample customizes the graphic for the root node depending on whether the root is expanded or not (by using a binding on a graphic ImageView between the view's image and the tree item's expanded property).

The sample also centers the small triangle (the disclosure arrow) vertically with respect to the graphic image by playing with the padding settings of the arrow - you will need to adjust padding appropriately for your view as centering is not automatic.

If you want to change the shape of the disclosure arrow to something different, then see Uluk's answer to: JavaFX: Use custom Node as collapse / expand branch switch for TreeView.

shut open

CustomTree.java

import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.image.*;
import javafx.stage.Stage;

public class CustomTree extends Application {

    @SuppressWarnings("unchecked")
    @Override
    public void start(Stage stage) throws Exception {
        Image expandedImage  = new Image(
                "http://icons.iconarchive.com/icons/pelfusion/christmas-shadow-2/64/Tree-icon.png"
        );
        Image collapsedImage = new Image(
                "http://icons.iconarchive.com/icons/pelfusion/christmas-shadow/64/Tree-icon.png"
        );

        ImageView rootGraphic = new ImageView(expandedImage);

        TreeItem<String> root = new TreeItem<>("Root Node");
        root.setGraphic(rootGraphic);
        root.getChildren().setAll(
                new TreeItem<>("Item 1"),
                new TreeItem<>("Item 2"),
                new TreeItem<>("Item 3")
        );

        rootGraphic.imageProperty().bind(Bindings
                .when(root.expandedProperty())
                    .then(expandedImage)
                    .otherwise(collapsedImage)
        );
        root.setExpanded(true);

        TreeView<String> treeView = new TreeView<>(root);
        treeView.setPrefSize(300, 200);

        Scene scene = new Scene(treeView);
        scene.getStylesheets().add(
                getClass().getResource(
                        "custom-tree.css"
                ).toExternalForm()
        );
        stage.setScene(scene);
        stage.show();
    }

    public static void main(String[] args) { launch(args); }
}

custom-tree.css

.root {
    -fx-font-size: 30px;
}

.tree-cell > .tree-disclosure-node {
  -fx-padding: 24 6 24 8;
}

Licensed under: CC-BY-SA with attribution
Not affiliated with: Stack Overflow
Icon