# JavaFX TreeView stylen



## deemon84 (10. Jun 2018)

Hallo,

ich möchte im TreeView folgende 2 Sachen erreichen:
1) die Hintergrundfarbe für das ganzes Sub-Tree verändern, sobald irgendwelches Element in diesem Sub-Tree ausgewählt ist. ZB: klickt man *a,b* oder *c *an, dann wird die Hintergrundfarbe von *a,b,foo,bar,c* hellgrau sein. Wenn man jedoch *foo *oder *bar *anklickt, dann nur *foo *und *bar *sollen einen hellgrauen Hintergrund haben.

Zusätzlich möchte ich die Knoten in diesem Sub-Tree, die zu den ausgewählten Knoten oder Blatt führen, unterstreichen. ZB: wenn man *foo *oder *bar *anklickt, dann sollen *b* und *3* unterstrichen werden. Wenn man jedoch *a,b,c* anklickt, dann soll nur *3* unterstrichen werden.
(siehe Bild)


2) Ich möchte für Blätter ein eigenes Symbol verwenden. (Knoten haben bereits den Dreieck) 

Ich bin ziemlich neu mit JavaFX. Angeblich sollte man diese mit CSS, oder mit einem eigenen Cell Factory (setCellFactory()) erreichen können...
Kann mir jemand weiterhelfen, wie?

Vielen Dank,
Daniel


----------



## thet1983 (11. Jun 2018)

wie hast du denn die dreiecke reinbekommen?
Konstruktor : TreeItem


----------



## deemon84 (11. Jun 2018)

thet1983 hat gesagt.:


> wie hast du denn die dreiecke reinbekommen?
> Konstruktor : TreeItem


Mit Dreieck habe ich das standard Symbol im JavaFX gemeint.


----------



## thet1983 (12. Jun 2018)

TreeItem besitzt einen Konstruktor dem du eine Node mitgeben kannst.

```
TreeItem(T value, Node graphic)
Creates a TreeItem with the value property set to the provided object, and the graphic set to the provided Node.
```
Dieser Node übergibst du einfach eine ImageView und fertig.


----------



## thet1983 (12. Jun 2018)

Hier ein Beispiel:

Die Methode initRoot() baut die Struktur auf.
In der for Schleife erstelle ich die einzelnen Leaf's und adde diese an das root Element.



```
package treeview;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeView;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;

public class TreeViewDemo extends Application {

    @Override
    public void start(Stage primaryStage) {
        try {

            BorderPane root = new BorderPane();

            TreeView<String> treeView = new TreeView<>(initRoot());
            root.setCenter(treeView);
            Scene scene = new Scene(root,400,400);
            primaryStage.setScene(scene);



            primaryStage.show();
        } catch(Exception e) {
            e.printStackTrace();
        }
    }

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

    /*
     * erstellt die struktur
     */
    private TreeItem<String> initRoot(){
        TreeItem<String> root = new TreeItem<String>("Wurzel", new ImageView(new Image(getClass().getResource("/treeview/folder.png").toExternalForm())));
        root.expandedProperty().set(true);
        // elemente
        for(int i = 1; i <= 5; i++) {
            root.getChildren().add(new TreeItem<String>("Element " + i,new ImageView(new Image(getClass().getResource("/treeview/leaf.png").toExternalForm()))));
        }
        return root;
    }
}
```


----------



## deemon84 (18. Jun 2018)

Danke für Eure Antworten.
Die Hintergrundfarbe habe ich mit einem TreeCellFactory gemacht:
tree.setCellFactory(new Callback<TreeView, TreeCell>() {
                @Override
                public TreeCell call(TreeView p) {
                    return new MyTreeCell();
                }
});

private final class MyTreeCell extends TreeCell<TreeData> {

        public MyTreeCell() {
        }

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

            if (empty) {
                setText(null);
                setGraphic(null);
            } else {
                setText(getString());
                setGraphic(getTreeItem().getGraphic());
            }

            if (getItem() != null && getItem().getNode() != null) {
                if (nodesToHighlight.containsKey(getItem().getNode().hashCode())) {
                    setBackground(new Background(new BackgroundFill(Color.LIGHTGREY, CornerRadii.EMPTY, Insets.EMPTY)));
                    System.out.format("\nHighlighting TreeItem: %s\n", getItem());
                } else {
                    setBackground(new Background(new BackgroundFill(Color.WHITE, CornerRadii.EMPTY, Insets.EMPTY)));
                }
            }
        }

        private String getString() {
            return getItem() == null ? "" : getItem().toString();
        }
    }

Jedes TreeCell ist dafür verantwortlich ein TreeData Objekt darzustellen. Das HashMap nodesToHighlight enthält alles TreeData Objekte, dessen Hintergrund anders gefärbt sein soll. Bei updateItem() wird abgefragt, ob das aktuelle TreeCell genau das TreeData enthält, was man anders färben möchte.


----------



## Fadi-D (4. Nov 2019)

Hallo Daniel,
ich bin neu in der Java umfeld
könntest du bitte mir sagen wo dein HashMap nodesToHighlight defeniert ist und wie du die item dazu hinzufügt hast
Viele Grüße


----------

