Search code examples
cssjavafxfxml

FXML/CSS: Button with image in center and text in bottom


I have a button with an icon and text and I can't figure out how to place the icon in the center and the text in the bottom left of the button. This is what it looks like right now:

<Button text="Text" GridPane.rowIndex="0" GridPane.columnIndex="2" prefWidth="135" prefHeight="110" style="-fx-background-color: rgb(176,30,0); -fx-text-fill: rgb(255,255,255); -fx-alignment: BOTTOM_LEFT;">
    <graphic>
        <ImageView>
            <Image url="file:///....png"/>
        </ImageView>
    </graphic>
</Button>

Two things I've tried, which haven't been working: 1. Giving the ImageView a separate alignment attribute. 2. Placing a VXbox inside the button and the imageView as well as label with text inside the VBox.

Thanks in advance!


Solution

  • The contentDisplay property controls the position of the graphic relative to the text. The alignment property controls the position of the overall content.

    So

    <Button text="Text" GridPane.rowIndex="0" GridPane.columnIndex="2" prefWidth="135" prefHeight="110" 
        alignment="BOTTOM_LEFT" contentDisplay="TOP" 
        style="-fx-background-color: rgb(176,30,0); -fx-text-fill: rgb(255,255,255);">
    

    or some similar combination, should work.

    If you prefer to set these in CSS, -fx-alignment: bottom-left; -fx-content-display: top ; will do the same.

    The contentDisplay property doesn't quite give you full control over the positioning of the graphic; you may need to use the idea you proposed of placing a container with the image view and a label as the graphic. In this case, you probably want an alignment of center. A BorderPane would probably be closer to what you need than a VBox:

    <Button GridPane.rowIndex="0" GridPane.columnIndex="2" prefWidth="135" prefHeight="110" style="-fx-background-color: rgb(176,30,0); -fx-text-fill: rgb(255,255,255); -fx-alignment: center;">
        <graphic>
            <BorderPane>
                <center>
                    <ImageView>
                        <Image url="file:///....png"/>
                    </ImageView>
                </center>
                <bottom>
                    <Label text="Text"/>
                </bottom>
            </BorderPane>
        </graphic>
    </Button>
    

    You may also need to experiment with setting the preferred size of the border pane, to make it fill the area allocated to the button.