JavaFX 8 - Add a graphic to a TitledPane on the right side
java, javafx-8, layout
Solution
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);
}
}
Problem
I want to add a little icon to the title of a `TitledPane`. Therefore I set an empty title and add a `HBox` containing a `Label` and a `ImageView` as graphic. In this way the icon is shown close to the end of the text. I want it to be shown always next to the right border of the `TitledPane`. How can I do this? I also tried to use a `BorderPane` and add the `Label` to the center and the `ImageView` to the right, but the `BorderPane` doesn't get the maximum size of the TitledPane. So I tried to set MaxWidth to Max-Value, but this didn't help Does anybody know what to do? **EDIT: ** The "custom" control I created will be initialized within a method called in stage.setOnShown. ``` public class CustomTitledPane extends TitledPane { private Image alert; private Image registered; private Image deleted; private ImageView img; public CustomTitledPane(String titleText, Node node) { super(titleText, node); setAnimated(true); setCollapsible(true); img = new ImageView(); img.setFitHeight(10d); img.setPreserveRatio(true); img.setSmooth(true); setGraphic(img); setContentDisplay(ContentDisplay.RIGHT); // apply css and force layout of nodes applyCss(); layout(); // title region Node titleRegion = lookup(".title"); // padding Insets padding = ((StackPane) titleRegion).getPadding(); // image width double graphicWidth = img.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; System.out.println("w: " + graphicWidth + " " + arrowWidth + " " + labelWidth); graphicTextGapProperty().bind(widthProperty().subtract(nodesWidth)); try { alert = new Image(new FileInputStream("img/Alert.png")); registered = new Image(new FileInputStream("img/Registered.png")); deleted = new Image(new FileInputStream("img/Deleted.png")); } catch (FileNotFoundException e) { e.printStackTrace(); } } } ``` And here's the CSS for TitledPane: ``` .titled-pane { -fx-text-fill: #006FD8; } .titled-pane > .title { -fx-background-color: transparent; -fx-border-color: linear-gradient(to right, white 0%, grey 30%, grey 70%, white 100%) transparent transparent transparent; } .titled-pane:expanded > .title { -fx-border-color: grey transparent transparent transparent; -fx-background-color: linear-gradient(to bottom, #DCE7F5, white); } .titled-pane:expanded > *.content { -fx-border-width: 0; } ```