JavaFX Button

Jakob Jenkov
Last update: 2020-12-09

A JavaFX Button control enables a JavaFX application to have some action executed when the application user clicks the button. The JavaFX Button control is represented by the class javafx.scene.control.Button . A JavaFX Button can have a text and an icon on it which indicate to the user what clicking the button will do.

Creating a Button

You create a button control by creating an instance of the Button class. Here is a JavaFX Button instantiation example:

Button button = new Button("My Label");

The text to be displayed on the button is passed as parameters to the Button constructor.

Adding a Button to the Scene Graph

For a JavaFX Button to be visible the button object must be added to the scene graph. This means adding it to a Scene object, or as child of a layout which is attached to a Scene object.

Here is an example that attaches a JavaFX Button to the scene graph:

package com.jenkov.javafx.controls;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.stage.Stage;


public class ButtonExperiments extends Application  {

    @Override
    public void start(Stage primaryStage) throws Exception {
        primaryStage.setTitle("HBox Experiment 1");

        Button button = new Button("My Button");

        Scene scene = new Scene(button, 200, 100);
        primaryStage.setScene(scene);
        primaryStage.show();

    }

    public static void main(String[] args) {
        Application.launch(args);
    }
}

Notice that the Button is added directly to the Scene object. Normally you would nest the Button inside a layout component of some kind. I have left that out here to keep the example simple. See the tutorials about layout components to see how they work.

The result of running the above JavaFX Button example is an application that looks like this:

A JavaFX Button component displayed in the scene graph.

Notice that the button takes up all the space available in the window. That is why it is hard to see the edges of the button. When a JavaFX button is added to a layout component you can more easily see the edges of the button.

Button Text

There are two ways to set the text of a JavaFX button. The first way is to pass the text to the Button constructor. You have already seen this in earlier examples.

The second way to set the button text is by calling the setText() method on the Button instance. This can be done after the Button instance is created. Thus it can be used to change the text of a Button that is already visible. Here is an example how how calling setText() on a JavaFX Button looks:

button.setText("Click me if you dare!");

Button Text Size

You can set the text size of a JavaFX Button. You do so using the CSS property -fx-text-size. This CSS property is explained in the section about Button CSS Styling

Button Text Wrap

The JavaFX Button control supports text wrapping of the button text. By text wrapping is meant that if the text is too long to be displayed on a single line inside the button, the text is broken onto multiple lines.

You enable text wrapping on a JavaFX Button instance using the method setWrapText(). The setWrapText() method takes a single boolean parameter. If you pass a value of true to setWrapText() then you enable text wrapping. If you pass a value of false to setWrapText() then you disable text wrapping. Here is an example that enables text wrapping on a JavaFX button:

button.setWrapText(true);

Here is a screenshot of two JavaFX buttons one of which has text wrapping enabled:

Two JavaFX Button instances, one with text wrap enabled.

Button Font

You can specify what font the text on a JavaFX Button should be rendered with via its setFont() method. You can read more about creating fonts in my JavaFX Fonts tutorial. Here is an example of setting a font on a JavaFX Button:

Button button = new Button("Click me!");

Font font = Font.font("Courier New", FontWeight.BOLD, 36);

button.setFont(font);

Default Button Mode

A JavaFX Button can be set into a default mode. When a Button is in default mode it is rendered differently, so the user can see that this is the default button. On Windows, the Button's background color changes, although I guess that also depends on the color theme used in the application etc. and may change in future versions of JavaFX.

The default button is intended to be used for the "default choice" in a dialog or form. Thus, it becomes easier for the user to select the choice that the user is most likely making most often.

The default button of a dialog or form has some additional keyboard shortcuts to help the user click it:

  • Windows + Linux
    • If no other button has focus, pressing the ENTER keyboard key will activate the default button.
    • If the default button has focus, pressing the ENTER keyboard key will activate the default button.
  • Mac
    • Only the default button can be activated by pressing the ENTER keyboard key. All other buttons are activated by pressing the the SPACE keyboard key.

Setting a JavaFX Button as the default button is done via its setDefaultButton() method. Here is an example of setting a JavaFX button as default button:

button.setDefaultButton(true);

Cancel Button Mode

A JavaFX Button can be set into cancel mode. When a Button is in cancel mode it can be activated more easily by pressing the ESC keyboard key - if no other node in the Scene graph consumes this key press.

Setting a JavaFX Button in cancel mode (as cancel button) is done via its setCancelButton() method. Here is an example of setting a JavaFX Button in cancel mode:

buttonDefault.setCancelButton(true);

Button Image

It is possible to display an image inside a button next to the button text. The JavaFX Button class contains a constructor that can take a Node as extra parameter. Here is a JavaFX label example that adds an image to the button using an JavaFX ImageView component:

package com.jenkov.javafx.controls;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.stage.Stage;

import java.io.FileInputStream;


public class ButtonExperiments extends Application  {


    @Override
    public void start(Stage primaryStage) throws Exception {
        primaryStage.setTitle("HBox Experiment 1");

        FileInputStream input = new FileInputStream("resources/images/iconmonstr-home-6-48.png");
        Image image = new Image(input);
        ImageView imageView = new ImageView(image);

        Button button = new Button("Home", imageView);

        Scene scene = new Scene(button, 200, 100);
        primaryStage.setScene(scene);
        primaryStage.show();

    }

    public static void main(String[] args) {
        Application.launch(args);
    }
}

The result of running the above JavaFX Button example is an application that looks like this:

A JavaFX Label component with an image embedded.

Button Size

The JavaFX Button class contains a set of methods you can use to set the button size. The methods controlling the button size are:

button.setMinWidth()
button.setMaxWidth()
button.setPrefWidth()

button.setMinHeight()
button.setMaxHeight()
button.setPrefHeight()

button.setMinSize()
button.setMaxSize()
button.setPrefSize()

The methods setMinWidth() and setMaxWidth() sets the minimum and maximum width the button should be allowed to have. The method setPrefWidth() sets the preferred width of the button. When there is space enough to display a button in its preferred width, JavaFX will do so. If not, JavaFX will scale the button down until it reaches its minimum width.

The methods setMinHeight() and setMaxHeight() sets the minimum and maximum height the button should be allowed to have. The method setPrefHeight() sets the preferred height of the button. When there is space enough to display a button in its preferred height, JavaFX will do so. If not, JavaFX will scale the button down until it reaches its minimum height.

The methods setMinSize(), setMaxSize() and setPrefSize() sets both width and height for the button in a single call. Thus, these methods takes both a width and a height parameter. For instance, calling

button.setMaxSize(100, 200);

is equivalent to calling

button.setMaxWidth(100);
button.setMaxHeight(200);

Here is a screenshot of two JavaFX buttons. The first button has the default size calculated from its button text and the layout component it is nested inside. The second button has a preferred width of 200 and height of 48 set on it:

Two JavaFX Button instances - one with preferred width and height set on it.

Button Events

In order to respond to the click of a button you need to attach an event listener to the Button object. Here is how that looks:

button.setOnAction(new EventHandler() {
    @Override
    public void handle(ActionEvent actionEvent) {
        //... do something in here.
    }
});

Here is how attaching a click event listener looks with a Java Lambda expression:

button.setOnAction(actionEvent ->  {
    //... do something in here.    
});

Finally, let us see a full example that changes the text of a JavaFX Label when the button is clicked:

package com.jenkov.javafx.controls;

import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;

public class ButtonExperiments extends Application  {


    @Override
    public void start(Stage primaryStage) throws Exception {
        primaryStage.setTitle("HBox Experiment 1");

        Label label = new Label("Not clicked");
        Button button = new Button("Click");

        button.setOnAction(value ->  {
           label.setText("Clicked!");
        });

        HBox hbox = new HBox(button, label);

        Scene scene = new Scene(hbox, 200, 100);
        primaryStage.setScene(scene);
        primaryStage.show();

    }

    public static void main(String[] args) {
        Application.launch(args);
    }
}

Button Mnemonic

You can set a mnemonic on a JavaFX Button instance. A mnemonic is a keyboard key which activates the button when pressed in conjunction with the ALT key. Thus, a mnemonic is a keyboard shortcut to activating the button. I will explain how to activate a button via its mnemonic later.

The mnemonic for a button is specified inside the button text. You mark which key is to be used as mnemonic by placing an underscore character (_) in front of the character in the button text you want to set as mnemonic for that button. The underscore character will not be displayed in the button text. Here is an example setting a mnemonic for a button:

button.setMnemonicParsing(true);

button.setText("_Click");

Notice that it is necessary to first call setMnemonicParsing() on the button with a value of true. This instructs the button to parse mnemonics in the button text. If you call this method with a value of false instead, the underscore character in the button text will just show up as text, and will not be interpreted as a mnemonic.

The second line sets the text _Click on the button. This tells the button to use the key c as mnemonic. Mnemonics are case insensitive, so it does not have to be an a uppercase C that activates the button.

To activate the button you can now press ALT-C (both at the same time). That will activate the button just as if you had clicked it with the mouse.

You can also first press the ALT key once. That will show the mnemonic of the button in the button text. You can then press the c key. If you press ALT and then ALT again, the mnemonic is first shown, then hidden again. When the mnemonic is visible you can activate the button with the mnemonic key alone, without ALT pressed at the same time. When the mnemonic is not visible you have to press both ALT and the mnemonic key at the same time to activate the button.

Here are two screenshots showing what it looks like when the mnemonic is invisible and visible:

A JavaFX Button with its mnemonic hidden. A JavaFX Button with its mnemonic visible.

Button CSS Styles

You can style a JavaFX button using CSS styles. The JavaFX Button control supports the following CSS styles:

-fx-border-width
-fx-border-color
-fx-background-color
-fx-font-size
-fx-text-fill

Here is an example setting the background color of a JavaFX button to red:

Button button = new Button("My Button");

button.setStyle("-fx-background-color: #ff0000; ");

This example sets the style directly on the button via the setStyle() method, but you can also style a JavaFX button via style sheets. See my JavaFX CSS Styling tutorial for more information about using CSS stylesheets with JavaFX.

Here is a JavaFX button example which creates 4 different buttons. Each button has a CSS style set on them. After the code example I have included a screenshot of how the buttons look with the given styling.

package com.jenkov.javafx.controls;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;

import java.io.FileInputStream;
import java.io.FileNotFoundException;


public class ButtonExperiments extends Application  {


    @Override
    public void start(Stage primaryStage) throws Exception {
        primaryStage.setTitle("Button Experiment 1");

        Button button1 = new Button("Button 1");
        Button button2 = new Button("Button 2");
        Button button3 = new Button("Button 3");
        Button button4 = new Button("Button 4");

        button1.setStyle("-fx-border-color: #ff0000; -fx-border-width: 5px;");
        button2.setStyle("-fx-background-color: #00ff00");
        button3.setStyle("-fx-font-size: 2em; ");
        button4.setStyle("-fx-text-fill: #0000ff");


        HBox hbox = new HBox(button1, button2, button3, button4);


        Scene scene = new Scene(hbox, 400, 100);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public static void main(String[] args) {
        Application.launch(args);
    }
}

Here is a screenshot of the 4 JavaFX buttons with their CSS styling:

4 JavaFX Button instances with different CSS styling set on them.

The first button has both the -fx-border-width and -fx-border-color CSS properties set. This results in a 5 pixel wide red border for the button.

The second button has the -fx-background-color CSS property set. This results in a green background color for the button.

The third button has the -fx-font-size CSS property set. This results in a button with a text that is 2 times as big as normal.

The fourth button has the -fx-text-fill CSS property set. This results in a button with a blue text color.

You can combine the CSS styles for a JavaFX button simply by setting multiple CSS properties on it, like the first button in the example above has.

Disable Button

You can disable a JavaFX Button via its setDisable() method. The setDisable() method takes a boolean parameter which specify if the button should be disabled or not. A value of true means the button will be disabled, and a value of false means it will not be disabled - which means enabled. Here is an example of disabling a JavaFX Button via its setDisable() method:

Button button = new Button();
button.setText("Click me!");

// here the app is running, and something happens so
// the button should now be disabled.

button.setDisable(true);


// again the app runs, and something happens so
// the button should now be enabled again.

button.setDisable(false);

Button FXML

It is possible to declare a JavaFX Button inside a JavaFX FXML file. I will not explain FXML in every detail here. Click on the link in the first sentence to read more about how FXML works. I will just show you the parts of FXML related to the JavaFX Button control. Here is a very simple FXML file example that shows how to declare a Button:

<?xml version="1.0" encoding="UTF-8"?>
    <?import javafx.scene.layout.VBox?>
    <?import javafx.scene.control.Button?>
    <VBox xmlns:fx="http://javafx.com/fxml" spacing="20">
    <children>
        <Button fx:id="button1" text="Click me!" onAction="#buttonClicked"/>
    </children>
</VBox>

It is the <Button> element that declares the Button control. The fx:id attribute can be used to wire up the declared Button to a Button member variable inside an FXML Controller object.

The text attribute is used to set the corresponding text property value in the Button instance created for this Button declaration. That is the text displayed on the button.

The onAction attribute is used to link the Button's onAction event to a method in the FXML controller object. In this example it is the method named buttonClicked() in the FXML controller.

Here is how the corresponding FXML controller object's class looks. Notice the name of the button1 Button member variable matches the fx:id attribute value in the FXML file. This member variable must be public, by the way. Notice also the method buttonClicked() which is referenced from the Button onAction attribute in the FXML file.

import javafx.event.Event;
import javafx.fxml.FXML;
import javafx.scene.control.Button;

public class ButtonFXMLController {

    public Button button1 = null;
    private int   button1ClickCount = 0;

    @FXML
    public void buttonClicked(Event e){
        this.button1ClickCount++;

        String text = "Button1 clicked " + this.button1ClickCount + " times";

        System.out.println(text);

        button1.setText(text);
    }

}

And here is the full JavaFX app that loads the FXML file and creates the FXML controller etc. :

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

import java.io.File;
import java.net.URL;

public class ButtonFXMLExample extends Application {

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage primaryStage) throws Exception {

        FXMLLoader loader = new FXMLLoader();

        ButtonFXMLController controller = new ButtonFXMLController();
        loader.setController(controller);

        File fxmlFile = new File("assets/fxml/button-example.fxml");
        URL fxmlUrl = fxmlFile.toURI().toURL();
        loader.setLocation(fxmlUrl);

        VBox vbox = loader.<VBox>load();
        Scene scene = new Scene(vbox);

        primaryStage.setScene(scene);

        primaryStage.setTitle("Button FXML Example");
        primaryStage.setWidth(300);
        primaryStage.setHeight(300);
        primaryStage.show();
    }
}

Button Transformations

You can add JavaFX transformations to a JavaFX Button such as scaling, rotation, translation etc. You add transformation objects to a JavaFX Button like this:

button.getTransforms().add(scaleTransformation);

Here is a full example of adding a Scale transformation to a JavaFX Button:

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.VBox;
import javafx.scene.transform.Scale;
import javafx.stage.Stage;

public class ButtonTransformationExample extends Application {

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage primaryStage) {

        Button button = new Button();

        button.setText("Click me!");

        button.setOnAction((event) -> {
            System.out.println("Button clicked!");
        });

        Scale scaleTransformation = new Scale();
        scaleTransformation.setX(3.0);
        scaleTransformation.setY(2.0);
        scaleTransformation.setPivotX(0);
        scaleTransformation.setPivotY(0);

        button.getTransforms().add(scaleTransformation);

        VBox  vbox  = new VBox(button);
        Scene scene = new Scene(vbox);
        primaryStage.setScene(scene);
        primaryStage.setWidth(512);
        primaryStage.setHeight(256);
        primaryStage.show();
    }

}

Jakob Jenkov

Featured Videos

Java Generics

Java ForkJoinPool

P2P Networks Introduction



















Close TOC
All Tutorial Trails
All Trails
Table of contents (TOC) for this tutorial trail
Trail TOC
Table of contents (TOC) for this tutorial
Page TOC
Previous tutorial in this tutorial trail
Previous
Next tutorial in this tutorial trail
Next