Styling a JavaFX 2 button using FXML only - How to add an image to a button?

69,370

Solution 1

Solution using only fxml

As tarrsalah points out, css is the recommended way of doing this, though you can also do it in fxml if you prefer:

<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.image.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.paint.*?>
<?import javafx.scene.text.*?>

<AnchorPane id="AnchorPane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns:fx="http://javafx.com/fxml">
  <children>
    <Button layoutX="104.0" layoutY="81.0" mnemonicParsing="false" text="Love&#10;Potion">
      <font>
        <Font size="30.0" />
      </font>
      <graphic>
        <ImageView fitHeight="150.0" fitWidth="200.0" pickOnBounds="true" preserveRatio="true">
          <image>
            <Image url="http://icons.iconarchive.com/icons/mirella-gabriele/fantasy-mediaeval/128/Poison-red-icon.png" />
          </image>
        </ImageView>
      </graphic>
    </Button>
  </children>
</AnchorPane>

To get the above in SceneBuilder, drag an ImageView on top of a Button and it will automatically be set as a graphic for the button. Then select the ImageView and type the url of the image into the ImageView's image field in the SceneBuilder properties pane.

Open the above fxml in SceneBuilder to see the image below.

lovepotion


Alternate css attributes

Alternate css to the -fx-background* attributes.

  • -fx-graphic
  • -fx-padding
  • -fx-content-display
  • -fx-graphic-text-gap

These are just different, not necessarily better for what you are trying to do. It is just a preference thing as to which to use. I find these settings easier to use than the -fx-background* settings. They are more restrictive, but the syntax and options are much easier for me to understand and their meanings map to the JavaDoc API for Labeled.

A detailed description of the attributes is in the css reference guide.

Here's a example with a style setting the graphic embedded in the fxml, though it is always better to separate the style information out into a separate css stylesheet as in tarrsalah's sample.

<Button layoutX="138.0" layoutY="226.0" mnemonicParsing="false" style="-fx-graphic: url('http://icons.iconarchive.com/icons/mirella-gabriele/fantasy-mediaeval/128/Poison-red-icon.png')" text="Love&#10;Potion">
  <font>
    <Font size="20.0" />
  </font>
</Button>

Related solutions for adding images to buttons using only Java code

Solution 2

FXML is used just for designing the layout, for styling you can use css and reference it from your FXML file :

 <stylesheets>
    <URL value="@main.css" />
  </stylesheets>

To add an image to a fx:id="btn" button in your css:

#btn {          
    -fx-background-image: url("Add.png");
    -fx-background-size: 18 18;
    -fx-background-repeat: no-repeat;
    -fx-background-position:left;   
}

This Github repository provide a complete running example:

enter image description here

Solution 3

A couple of changes I made to the css example (ref. #btn { in comment #3):

-fx-background-size: 100% 100%;
-fx-background-color: transparent;  

This removed the button outline and left only the image. I was able to resize the button selector in the Scene Builder like an ImageView and see the picture change in realtime. I added a ToolTip to explain the image since there was no text and no button outline. I plan to use techniques explained elsewhere and alter the image when clicked to give more visual feedback that the image is a button.

Also note: I needed to specify the button id in the 'CSS Id' (Scene Builder) instead of the 'fx:id' to get them to be linked.

Adding these changes to what was explained above allowed me to accomplish my goal: have a button that looks only like the image (e.g. round shape in squarish button).

Share:
69,370
AymenDaoudi
Author by

AymenDaoudi

Updated on August 07, 2020

Comments

  • AymenDaoudi
    AymenDaoudi almost 4 years

    I want to change the styling of a button, most of the threads here and the articles on the internet show how to do it using Java code, which I don't see it as a real good solution, is there any way for example to set a button with some text and an image inside it all by using FXML only (no Css) ?

  • Andrew S
    Andrew S almost 8 years
    Where would Add.png be located?
  • BarbaraKwarc
    BarbaraKwarc over 7 years
    @jewelsea what's with all these love buttons you use in your examples? :)
  • jewelsea
    jewelsea over 7 years
    @BarbaraKwarc gotta share the love :-) "Thousands of candles can be lighted from a single candle, and the life of the single candle will not be shortened. Happiness never decreases by being shared."
  • Herr von Wurst
    Herr von Wurst over 4 years
    @jewelsea what an odd place to discovery these beautiful lines. :)
  • ed22
    ed22 about 3 years
    @AndrewS It would be in the same directory as the CSS