2 votes

Comment définir l'indentation d'une cellule dans un TreeView en Javafx

Je travaille sur un TreeView qui représente un programme de commande de robot, chaque TreeCell représente une déclaration, et un TreeCell peut être imbriqué dans un autre. Comme en programmation, les déclarations peuvent être imbriquées dans des if o for déclarations.

Ici, j'ai créé une démo simple, remplie de blocs aléatoires.

Capture d'écran de démonstration

Pour personnaliser le rendu de TreeCell J'ai créé une classe étendant 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;
    }
}

En TreeData est une classe simple contenant 2 String s :

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

Comme vous pouvez le constater, l'indentation entre deux niveaux est trop faible, et nous pouvons à peine voir l'imbrication des instructions.

Je codifie tous les styles en Java, car je n'ai pas encore appris FXML+CSS.

J'aimerais savoir s'il est possible de définit la taille de l'indentation en Java ? Je ne trouve pas d'API à cet effet. En outre, Est-il possible de tracer des lignes entre le nœud parent et ses enfants ? comme JTree en Swing ?

Nous vous remercions.

1voto

Slaw Points 14364

En ce qui concerne les lignes comme dans JTree il n'y a pas de moyen intégré de le faire à partir de JavaFX 11. Il existe une demande de fonctionnalité ( JDK-8090579 ), mais il ne semble pas prévu de la mettre en œuvre. Vous pouvez peut-être le faire vous-même, mais je ne sais pas exactement comment.

En ce qui concerne la modification de l'indentation du TreeCell le moyen le plus simple est d'utiliser les feuilles de style CSS.

Comme l'indique le document Guide de référence CSS JavaFX , TreeCell possède une propriété CSS nommée -fx-indent dont la valeur est un <size> . Vous pouvez définir cette propriété à l'aide d'une feuille de style ou l'intégrer en ligne via l'option [style propriété](https://openjfx.io/javadoc/11/javafx.graphics/javafx/scene/Node.html#styleProperty()) . Exemple d'utilisation de styles en ligne :

public class TreeDataCell extends TreeCell<TreeData> {

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

}

Cependant, étant donné que vous n'utilisez actuellement ni CSS ni FXML, il existe une autre option qui est purement codée : Modifier le fichier indent propriété de TreeCellSkin . Cette classe est devenue une API publique dans JavaFX 9. Il existe peut-être une API interne équivalente dans JavaFX 8, mais je n'en suis pas sûr.

Par défaut, le Skin d'un TreeCell sera une instance de TreeCellSkin . Cela signifie que vous pouvez obtenir cet habillage et définir la valeur d'indentation comme vous le souhaitez. Il faut cependant être prudent, car l'habillage est créé paresseusement ; il ne sera pas nécessairement disponible avant que la fonction TreeView fait en fait partie d'une fenêtre de présentation.

Si vous ne souhaitez définir la propriété qu'une seule fois, une solution consiste à intercepter le skin à l'intérieur de createDefaultSkin() :

public class TreeDataCell extends TreeCell<TreeData> {

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

}

Vous pouvez également étendre TreeCellSkin et le personnaliser. N'oubliez pas de remplacer createDefaultSkin() et renvoie la mise en œuvre de votre skin personnalisé.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X