I have defined a css structure for the childless case:
.tree-cell:browser-folder-childless .tree-disclosure-node .arrow {
-fx-font-weight: bold;
-fx-shape: null;
-fx-background-color: null;
-fx-background-image: url("childless.png");
-fx-background-repeat: no-repeat;
}
.tree-cell:browser-folder-childless:expanded .tree-disclosure-node .arrow {
-fx-font-weight: bold;
-fx-shape: null;
-fx-background-color: null;
-fx-background-image: url("childless.png");
-fx-background-repeat: no-repeat;
}
Next I have extended the TreeItem class:
public class BrowserTreeItem extends TreeItem<MyData> {
public BrowserTreeItem(MyData data) {
super(data);
}
@Override
public boolean isLeaf() {
return (getValue().getTypes().contains(NodeType.FOLDER) && getValue().getChildren().size() == 0) ? false : super.isLeaf();
}
}
So the TreeItem returns always false for isLeaf() in the case of a childless folder. The isLeaf() method will be used by the com.sun.javafx.scene.control.skin.TreeCellSkin.class to decide, whether or not the disclosure node should be removed. Rebuilding the node could be tricky, so I prevent the remove of the node.
This results in a normal disclosure node, now I have to change the image of the node.
It would be nice to overwrite also the isExanded() method of the TreeItem class. Then I would need only one CSS structure (the method would return always false for childless folders). But isExpanded() is final. So I cannot prevent the not/expanded switch by the user and I have to define two CSS structures.
Next, I have built a TreeCellFactory, which generates my own BrowserTreeCell classes. It toggles a PseudoClass state, which we use in the CSS above to activate some new images for the disclosure node.
public class BrowserTreeCell extends TreeCell<MyData> {
private final PseudoClass childless = PseudoClass.getPseudoClass("browser-folder-childless");
@Override
protected void updateItem(MyData item, boolean empty) {
super.updateItem(item, empty);
if (!empty && item != null) {
setText(item.getName());
setGraphic(item.getThumbnail());
setTooltip(item.getTooltip());
} else {
setText("");
setGraphic(null);
setTooltip(null);
}
pseudoClassStateChanged(childless, !empty && item != null && item.getTypes().contains(NodeType.FOLDER) && item.getChildren().size() == 0);
}
}
As the result, I get a disclosure node with a "childless.png" in both cases (not/expanded).