JavaFX 8 - Add a graphic to a TitledPane on the right side

左心房为你撑大大i 提交于 2019-12-01 06:51:57

Based on the code shown by the OP on his edited question, this code addresses the fact that the titled pane is created on a listener before the stage is shown, on a custom class.

@Override
public void start(Stage primaryStage) {

    Scene scene = new Scene(new StackPane(), 300, 250);

    primaryStage.setScene(scene);

    primaryStage.setOnShown(e -> {
        CustomTitledPane customTitledPane = new CustomTitledPane("Title", new StackPane(new Label("Graphic to the Right")));
        scene.setRoot(customTitledPane);
        customTitledPane.applyCss();
        customTitledPane.layout();

        // title region
        Node titleRegion=customTitledPane.lookup(".title");
        // padding
        Insets padding=((StackPane)titleRegion).getPadding();
        // image width
        double graphicWidth=customTitledPane.getGraphic().getLayoutBounds().getWidth();
        // arrow
        double arrowWidth=titleRegion.lookup(".arrow-button").getLayoutBounds().getWidth();
        // text
        double labelWidth=titleRegion.lookup(".text").getLayoutBounds().getWidth();

        double nodesWidth = graphicWidth+padding.getLeft()+padding.getRight()+arrowWidth+labelWidth;

        customTitledPane.graphicTextGapProperty().bind(customTitledPane.widthProperty().subtract(nodesWidth));
    });

    primaryStage.show();

}

class CustomTitledPane extends TitledPane {

    public CustomTitledPane(String titleText, Node node) {
        super(titleText, node);
        setAnimated(true);
        setCollapsible(true);
        ImageView img = new ImageView(new Image(getClass().getResource("unlock24.png").toExternalForm()));
        img.setFitHeight(10d);
        img.setPreserveRatio(true);
        img.setSmooth(true);
        setGraphic(img);
        setContentDisplay(ContentDisplay.RIGHT);
    }
}

There's no need to wrap graphic and text in a box, since you can select how to display your content with setContentDisplay():

title.setContentDisplay(ContentDisplay.RIGHT);

Once you have the image at the right you need to set the gap between the image and the text. For that, we can use some lookups to get the real dimensions of the nodes in the title, once the stage is shown.

Finally, we bind the gap space to the width property of the title subtracting those dimensions.

EDIT

The sample now supports creation before the stage is shown.

@Override
public void start(Stage primaryStage) {
    Scene scene = new Scene(new StackPane(), 300, 250);

    primaryStage.setScene(scene);

    primaryStage.setOnShown(e -> {
        TitledPane title = new TitledPane("Title",
                new StackPane(new Label("Graphic to the Right")));

        ImageView imageView = new ImageView(new Image(getClass().getResource("unlock24.png").toExternalForm()));

        title.setGraphic(imageView);
        title.setContentDisplay(ContentDisplay.RIGHT);

        scene.setRoot(title);

        // apply css and force layout of nodes
        title.applyCss();
        title.layout();

        // title region
        Node titleRegion=title.lookup(".title");
        // padding
        Insets padding=((StackPane)titleRegion).getPadding();
        // image width
        double graphicWidth=imageView.getLayoutBounds().getWidth();
        // arrow
        double arrowWidth=titleRegion.lookup(".arrow-button").getLayoutBounds().getWidth();
        // text
        double labelWidth=titleRegion.lookup(".text").getLayoutBounds().getWidth();

        double nodesWidth = graphicWidth+padding.getLeft()+padding.getRight()+arrowWidth+labelWidth;  

        title.graphicTextGapProperty().bind(title.widthProperty().subtract(nodesWidth));
    });

    primaryStage.show();

}

And this is how it looks like:

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!