Himani Virmani Himani Virmani - 4 months ago 81
CSS Question

JavaFX : color individual TreeItems using css

I want to be able to color individual Tree Item of treeView based on some condition.
This answer seems good but I am unable to implement it.
http://stackoverflow.com/a/10931896/6653207

I am unable to understand how to use

setCellFactory
method to format individual
TreeItem
s.

I have a class

public class Bag {
public String caption,assignment="";
Boolean eval;
public Set<Vertex> Nodes = new HashSet<Vertex>();
public Vector<Bag> ChildBags = new Vector<Bag>();

@Override
public String toString()
{
return assignment+ " " +caption;
}

}


Here's my css file:

.true{
-fx-text-fill:#33cc00 ;
}
.assignment{
-fx-text-fill: #0033cc
}


So I want to color to green the caption ( the
toString()
method returns ) of all those nodes whose eval property is true.
and assignment string which
toString()
method returns for all the nodes should be blue.

How can I do so?

Thanks.

Answer

By overriding the updateItem method of the TreeCell, you can adjust the TreeCell's properties based on the value of the TreeItem the cell contains.

In the following examplea pseudoclass is assigned to all cells that contain a value with the prefix "child" and all empty cells get a black background.

TreeView<String> treeView = ...

PseudoClass childPseudoClass = PseudoClass.getPseudoClass("child");

treeView.setCellFactory(tv -> new TreeCell<String>() {

    @Override
    protected void updateItem(String item, boolean empty) {
        super.updateItem(item, empty);
        if (empty || item == null) {
            // update for empty cell / cell containing null
            pseudoClassStateChanged(childPseudoClass, false);
            setText("");
            setStyle("-fx-background-color: black;");
        } else {
            // update for filled cell
            pseudoClassStateChanged(childPseudoClass, item.startsWith("child"));
            setText(item);
            setStyle(null);
        }
    }

});

CSS Stylesheet

.tree-cell:child {
    -fx-background-color: red;
}

The updateItem method is called by the TreeView every time the value changes, e.g. if a new TreeItem is associated with the cell or the value property of a TreeItem is modified.

You could also use the factory to add listeners to the TreeCell, before it's returned, in case you prefer this and e.g. want to change the cell based on the treeItem property.


EDIT: To apply different colors to the text, you need to use different Nodes for the text parts.

treeView.setCellFactory(tv -> new TreeCell<Bag>() {

    private final Text assignment;
    private final Text caption;
    private final Node graphic;

    {
        assignment = new Text();
        caption = new Text();
        assignment.getStyleClass().add("assignment");
        graphic = new HBox(4, assignment, caption);
        setGraphic(graphic);
    }

    @Override
    protected void updateItem(Bag item, boolean empty) {
        super.updateItem(item, empty);
        if (empty || item == null) {
            setGraphic(null);
        } else {
            setGraphic(graphic);
            assignment.setText(item.assignment);
            caption.setText(item.caption);
            caption.getStyleClass().remove("true");
            if (item.eval) {
                caption.getStyleClass().add("true");
            }
        }
    }

});

To color the text you need to use the -fx-fill property instead of the -fx-text-fill property.

Comments