JavaFX 8 - Add Graphics to TitledPane on the Right Side

I want to add a little icon to the TitledPane header. So I set an empty title and add an HBox containing a Label and a ImageView as graphics. Thus, the icon is displayed closer to the end of the text. I want it to always appear next to the right border of the TitledPane . How can i do this? I also tried using BorderPane and add the Label to the center and ImageView to the right, but BorderPane does not get the maximum size of the TitledPane. So I tried setting MaxWidth to Max-Value, but that didn't help

Does anyone know what to do?

** EDIT: ** The user element I created will be initialized in the method specified 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 is the CSS for the 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; } 
+4
source share
2 answers

Based on the code shown by the OP on its edited question, this code refers to the fact that the title bar is created on the listener before this scene is shown in the user 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); } } 
+2
source

There is no need to wrap the graphics and text in the field, as you can choose how to display your content using setContentDisplay() :

 title.setContentDisplay(ContentDisplay.RIGHT); 

Once you have the image on the right, you need to set the gap between the image and the text. To do this, we can use some search queries to get the actual sizes of the nodes in the title as soon as this page is shown.

Finally, we bind the space of spaces to the name width property by subtracting these sizes.

EDIT

The sample now supports pre-scene creation.

 @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 here is what it looks like:

Titled pane

+2
source

Source: https://habr.com/ru/post/1208039/


All Articles