How To Use JavaFX For GUI Development?: Setup, Examples and a Calculator App

JavaFX For GUI Development

As a CS student, if you are confident about your Java programming skills and want to explore more advanced topics, then learning "JavaFX for GUI Development" is a great place to start.

JavaFX is the newest of Java's toolkits for building graphical user interfaces (GUIs), the windows, buttons, and text boxes you click on in a desktop app. In this article, we will first learn about JavaFX, how to set it up, its application structure, and some UI controls.

Later, we will look at practical examples of JavaFX, from CSS styling to animations, and then build a complete GUI calculator step by step. We compiled and ran every program on this page ourselves. So, let us start our discussion.

Summary Or Key Highlights:

  • With the JavaFX framework, we can build modern, good-looking desktop GUIs in Java.
  • JavaFX is no longer part of the JDK. Since Java 11, you download it separately (as OpenJFX) or add it through Maven or Gradle.
  • A JavaFX application is made of 4 important parts: the Application class, the Stage, the Scene, and Nodes.
  • JavaFX has ready-made UI controls like Button, Label, TextField, CheckBox, and more.
  • You can style an app with CSS, design its layout with FXML, add animations, and build full projects like a calculator.
  • From financial applications to IoT dashboards, the list of real-world uses of JavaFX is long.

What Is JavaFX In GUI Development?

As developers, when we build desktop applications with Java, we need a graphical user interface to make the application easy and pleasant to use. JavaFX is a framework that helps us build that GUI.

JavaFX comes with modern features like CSS styling and FXML support, plus built-in charts, animations, and media playback. The best thing about JavaFX is that the same code runs on different operating systems, like Windows, macOS, and Linux.

Historical Evolution Of JavaFX In GUI Development:

  • 1990s: The first Java GUI toolkit was AWT, which came with the first version of Java in 1996. It uses the operating system's own controls, so you can only customize it a little.
  • Late 1990s: Swing arrived and became part of Java in 1998. It gave us more UI components and much more flexibility. Swing is still included in the JDK today.
  • 2008 to 2014: JavaFX 1.0 came out in 2008 with its own scripting language. JavaFX 2.0 (2011) switched to a normal Java API, and JavaFX 8 shipped inside JDK 8 in 2014.
  • 2018 to today: Starting with Java 11, JavaFX was taken out of the JDK and became a separate open-source project called OpenJFX. It still gets a new release every six months, alongside the JDK.

How To Set Up JavaFX (It Is Not Part Of The JDK Anymore)

This is the first place most students get stuck. If you install a recent JDK and try to compile a JavaFX program the normal way, it fails right away:

HelloJav.java:1: error: package javafx.application does not exist
import javafx.application.Application;
                         ^

That happens because JavaFX has not been bundled with the standard JDK since Java 11. (A few JDK builds, like Liberica Full and Zulu FX, still include it, but most students use a JDK without it.) You have two easy ways to add it.

Option 1: Download the JavaFX SDK and use the command line. Download the JavaFX SDK for your operating system from the official OpenJFX site and unzip it. Then tell javac and java where the JavaFX files are and which parts (modules) you need:

javac --module-path path/to/javafx-sdk/lib --add-modules javafx.controls,javafx.fxml HelloJav.java
java --module-path path/to/javafx-sdk/lib --add-modules javafx.controls,javafx.fxml HelloJav

Replace path/to/javafx-sdk/lib with the real path to the lib folder you unzipped, for example C:\javafx-sdk\lib on Windows. The javafx.controls module gives you buttons, labels, and layouts. Add javafx.fxml only when your program uses FXML files.

If you skip the --module-path and --add-modules part when running, Java cannot find JavaFX at all:

Error: Could not find or load main class HelloJav
Caused by: java.lang.NoClassDefFoundError: javafx/application/Application

And if your IDE adds the JavaFX jar files to the classpath instead of the module path, you get a different error:

Error: JavaFX runtime components are missing, and are required to run this application

The fix is the same for both: load JavaFX with --module-path and --add-modules, or let a build tool do it for you.

Option 2: Use an IDE with Maven or Gradle. IntelliJ IDEA has a built-in JavaFX project wizard that sets everything up for you. The official Getting Started with JavaFX guide has step-by-step instructions for IntelliJ IDEA, NetBeans, Eclipse, and VS Code, with or without Maven and Gradle.

Which version should you use? At the time of writing (September 2026), the newest release is JavaFX 27, which needs JDK 25 or later. If your course uses an older JDK, pick an older JavaFX release that supports it. The JavaFX download page, linked from openjfx.io, lists which JDK each version needs.

What Is The JavaFX Application Structure?

Now that we have a basic definition of the JavaFX framework, it is time to move to some deeper concepts. In this section, we will talk about the structure of a JavaFX application. You need to understand this structure before you write your first program.

JavaFX application structure: Application class, Stage, Scene, and Nodes

These are the key parts that work together to build a graphical user interface with JavaFX. Let us check the following list to know more about them.

  • Application Class: Every JavaFX program starts with a class that extends the Application class. When the program runs, main() calls launch(), JavaFX starts up, and then it calls your start() method. That is where you build your window.
  • Stage (Window): The Stage is the main application window. When you run a JavaFX program, the window that opens is the Stage. JavaFX passes the first one to start() for you, usually named primaryStage.
  • Scene (UI Container): The Scene holds everything you see inside the Stage. It has one root node, usually a layout like VBox or GridPane, and that root holds all the other UI components.
  • Nodes (UI Elements): Nodes are the basic building blocks of a JavaFX application. Every UI element, from buttons to shapes, is a node. The nodes inside a Scene form a tree called the scene graph.

What Are Some User Interface (UI) Controls In JavaFX?

After discussing the structure of a JavaFX application, it is time to look at some UI controls. In the JavaFX structure, these controls are nodes.

Before we start writing code, you should know the most used JavaFX UI controls. Let us check the following list.

  • Button: A basic button that runs some code when the user clicks it, for example to submit a form.
  • Label: Shows text that the user cannot edit.
  • TextField: Takes one line of input from the user.
  • TextArea: Takes multi-line input from the user.
  • CheckBox: A box the user can tick on or off. Use several of them when the user can pick more than one option.
  • TableView: Shows data in rows and columns, like a table.
  • ListView: Shows data as a list, and the user can select items from it.

What Are Some Practical Ways To Use JavaFX For GUI Development?

We hope what we have discussed so far clears up the basics of the JavaFX framework. So, in this section, we can move to practical examples.

After going through these practical ways to use JavaFX, your understanding of this topic will become much more solid. All three examples use the class name HelloJav, so put each one in its own folder, together with its CSS or FXML file. Then compile and run it with the commands from the setup section.

1. JavaFX With CSS Styles:

With JavaFX, we can use Cascading Style Sheets (CSS). Working with CSS in JavaFX is similar to web development, except that JavaFX property names start with -fx-. In the Java code, you give each element a style class name. After that, you can change how the app looks by editing only the CSS file, without touching the Java code.

HelloJav.java File:

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

public class HelloJav extends Application // HelloJav Is Extending To Application
{

    @Override // Override Annotation Is Used
    public void start(Stage primaryStage)
    {
        // Creating The Label For The JavaFX Application
        Label l = new Label("JavaFX With CSS In CodingZap");
        l.getStyleClass().add("custom-label");

        // Implementing A Custom Button
        Button b = new Button("Check Our Blogs");
        b.getStyleClass().add("custom-button");

        // The VBox Layout Is Called With The Label And Button
        VBox v = new VBox(20, l, b);
        v.getStyleClass().add("root-container");

        // We Will Create A Scene With The VBox Layout
        Scene s = new Scene(v, 400, 200);
        // Calling The CSS File
        s.getStylesheets().add(getClass().getResource("zap.css").toExternalForm());

        primaryStage.setTitle("JavaFX with CSS");
        primaryStage.setScene(s); // Calling The Scene
        primaryStage.show();
    }

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

The zap.css File:

.root-container
{
    -fx-background-color: blue;
    -fx-padding: 20px;
    -fx-alignment: center;
}

.custom-label
{
    -fx-font-size: 20px;
    -fx-text-fill: white;
}

.custom-button
{
    -fx-background-color: #3498DB;
    -fx-text-fill: white;
    -fx-font-size: 16px;
}

Steps Of The Application:

  • First, in the Java file, we import the classes for Application, Scene, Stage, Button, Label, and VBox.
  • Next, the HelloJav class extends the Application class to start the JavaFX program.
  • Execution starts from the start() method, where a Label is created to show a message.
  • Then, a Button is created with the text "Check Our Blogs".
  • Later, a VBox (the root container) is created with the Label and Button inside it, 20 pixels apart.
  • At last, we load the zap.css file into the Scene and show the Scene on the Stage.
  • The CSS file itself is written just like in web development. Each style class name, like .custom-button, matches a name we added in the Java code.

Output:

JavaFX window styled with CSS: blue background, white label, and a light blue button

2. JavaFX With FXML For Design:

FXML is an XML-based language for describing the layout of a JavaFX screen. Instead of creating every button and label in Java code, you list them in an .fxml file, and JavaFX builds them for you. This keeps the layout separate from the Java logic, so you can change the layout by editing only the FXML file.

HelloJav.java File:

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

public class HelloJav extends Application // HelloJav Is Extending To Application
{

    @Override // Override Annotation Is Used
    public void start(Stage primaryStage) throws Exception
    {
        // Calling The FXML File
        FXMLLoader l = new FXMLLoader(getClass().getResource("zap.fxml"));
        Parent r = l.load();

        // We Will Find The UI Elements From The FXML File
        Label z = (Label) r.lookup("#z");
        Button o = (Button) r.lookup("#o");

        // We Will Handle The Button-Click Event With A Message
        o.setOnAction(event -> z.setText("The CodingZap Button Clicked!"));

        Scene s = new Scene(r, 300, 150);
        primaryStage.setTitle("JavaFX with FXML");
        primaryStage.setScene(s); // Calling The Scene
        primaryStage.show();
    }

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

The zap.fxml File:

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>

<VBox xmlns:fx="http://javafx.com/fxml" spacing="10" alignment="CENTER">

    <Label fx:id="z" text="JavaFX with FXML!"/>
    <Button fx:id="o" text="Click On CodingZap"/>

</VBox>

Steps Of The Application:

  • In the Java file, we import the classes for Application, FXMLLoader, Parent, Scene, Label, Button, and Stage.
  • Now, the HelloJav class extends Application, and JavaFX calls its start() method.
  • First, we load the zap.fxml file, and JavaFX creates all the elements listed in it.
  • Later, we find the Label and Button by their fx:id using lookup(). The # in "#z" means "find by id", just like in CSS.
  • Also, we give the Button an action that changes the Label's text when we click it.
  • In the end, we put the loaded layout in a Scene and show it on the Stage.
  • The ids in the FXML file (z and o) must match the ids we look up in the Java code.

Using lookup() is fine for a small demo. In bigger apps, the usual way is a separate controller class with @FXML fields, linked from the FXML file with fx:controller. Keeping the layout (FXML) and the logic (controller) apart is the same idea behind MVC architecture in Java. Gluon's free Scene Builder tool lets you design FXML screens by dragging and dropping.

Output Before Clicking The Button:

JavaFX FXML example before clicking the button

Output After Clicking The Button:

JavaFX FXML example after clicking the button, showing the new label text

3. Smooth Animations With JavaFX:

With JavaFX, we can add animations too. JavaFX has built-in transitions like fading, moving, rotating, and scaling. In the following program, we use two of them to make a button slide and fade when it is clicked.

import javafx.animation.FadeTransition;
import javafx.animation.TranslateTransition;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import javafx.util.Duration;

public class HelloJav extends Application // HelloJav Is Extending To Application
{

    @Override // Override Annotation Is Used
    public void start(Stage primaryStage)
    {
        Button b = new Button("Click On CodingZap");

        // We Are Implementing Smooth Move Animation
        TranslateTransition m = new TranslateTransition(Duration.seconds(1), b);

        m.setByX(100);  // We Will Move 100 Pixels To The Right On The X-Axis
        m.setAutoReverse(true); // Then Come Back
        m.setCycleCount(2); // One Trip Out And One Trip Back

        // We Are Implementing The Fade Animation Effect
        FadeTransition f = new FadeTransition(Duration.seconds(1), b);
        f.setFromValue(1.0);
        f.setToValue(0.3);
        f.setAutoReverse(true);
        f.setCycleCount(2);

        // The Animation Will Be Done When We Click On The Button
        b.setOnAction(e -> {
            m.play();
            f.play();
        });

        StackPane r = new StackPane(b);
        r.setStyle("-fx-padding: 20px;");

        Scene s = new Scene(r, 400, 300); // We Are Creating The Scene

        primaryStage.setTitle("JavaFX Animations");
        primaryStage.setScene(s); // We Are Calling The Scene
        primaryStage.show();
    }

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

Steps Of The Application:

  • First, we import the classes for Application, Stage, Button, Scene, StackPane, and the two animations: FadeTransition and TranslateTransition.
  • As before, the HelloJav class extends Application and builds everything in start().
  • We make a Button with the text "Click On CodingZap".
  • Next, we create the move animation. It slides the button 100 pixels to the right in one second. Because auto reverse is on and the cycle count is 2, it then slides back to where it started.
  • After that, we create the fade animation. It fades the button to 30% opacity and then back to full, in the same two seconds.
  • When the button is clicked, both animations play at the same time.
  • In the end, the Scene is set on the Stage, and the window is shown.

Output: When you click the button, it slides to the right while fading out, then slides back and fades in again. The whole effect takes about two seconds, and the button ends up exactly where it started.

Worked Example: Build A GUI Calculator With JavaFX

Now let us put everything together in a real project. A GUI calculator is one of the most common JavaFX assignments, and it is a great first project because it uses layouts, buttons, styles, and event handling all at once. If you want more projects at this level, check out our list of Java project ideas.

In this section, we will walk through a JavaFX GUI calculator, from the assignment sheet to the working app.

What Are The Requirements Of A Typical JavaFX Calculator Assignment?

Before we start building the calculator, we have to go through the assignment sheet. Once we understand it, we know exactly what the app must do. Here are the requirements of a typical JavaFX GUI calculator assignment:

  • Create a desktop GUI calculator (an app that opens in its own window) with JavaFX.
  • There should be a display screen to show the inputs and outputs.
  • There should be buttons for the digits, the operations, Clear (C), and Equals (=).
  • The calculator should do the basic arithmetic operations: add, subtract, multiply, and divide.
  • The calculator should handle bad input and errors, like dividing by zero, without crashing.

What JavaFX Components Are Used In The GUI Calculator?

The first step is to decide which JavaFX components we need. This list works as the blueprint for the code:

  • TextField: The display area that shows the numbers and results.
  • Button: The digit, operation, Clear (C), and Equals (=) buttons.
  • GridPane: Places all the calculator buttons in a 4x4 grid.
  • MouseEvent: Changes a button's color while it is being pressed, so the user gets visual feedback.
  • VBox: Stacks the TextField and the GridPane vertically in the main layout.
  • Scene: Holds the entire main layout and displays it.
  • Stage: The main window that shows the Scene.

What Are The Different Sections In The JavaFX Calculator Code?

To make it easier to follow, we have divided the complete calculator code into 6 sections. All six sections go into one file named ZapCalculator.java, in this order. Put them together, then compile and run the file with the commands from the setup section, replacing HelloJav with ZapCalculator. The calculator window will open.

Section 1: Necessary Imported Packages

To build anything with JavaFX, we have to import several classes. That is why we start with a separate section for the imports. Without them, the compiler would not know what a Button or a GridPane is.

// We Will Import Necessary Packages For JavaFX
import javafx.application.Application;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

Explanation Of The Code Snippet:

  • First, we import Application, which every JavaFX app needs.
  • Next, we import Pos from the geometry package. It is used to align components, like centering the buttons.
  • Then, we import Scene, plus the Button and TextField controls.
  • We import MouseEvent from the input package to react when a button is pressed and released.
  • Later, we import the GridPane and VBox layouts.
  • In the end, we import Stage, which is the main window.

Section 2: The Application Class And Its Variables

In this section, we create the main class. It extends Application, which makes it a JavaFX app, and it holds the variables the calculator needs to remember between button clicks.

public class ZapCalculator extends Application // Creation Of Application Class
{

    private TextField tf; // TextField Will Be Used To Display I/O

    private double n1 = 0; // Variable To Store First Number
    private String opr = ""; // Variable To Store Operator

    private boolean newNumber = false; // A Flag To Start A New Number

Explanation Of The Code Snippet:

  • First, we name the class ZapCalculator. The file must be named ZapCalculator.java to match.
  • The class uses the extends keyword to get all the features of a JavaFX Application.
  • Next, a TextField called tf is declared. It will act as the calculator's display.
  • We also create two private variables: n1 for the first number and opr for the operator.
  • Finally, a boolean flag called newNumber tells the calculator when the next digit should start a fresh number instead of adding to the one on screen.

Section 3: The start() Method

The start() method is the largest section of the calculator. All the JavaFX design work happens here: creating the display, the buttons, the layout, and the window.

    @Override
    public void start(Stage primaryStage) // Start Function Of The JavaFX
    {
        tf = new TextField(); // A TextField Will Be Created

        tf.setEditable(false); // The User Can't Edit It Manually

        // We Are Aligning The TextField With Design
        tf.setAlignment(Pos.CENTER_RIGHT);
        tf.setStyle("-fx-font-size: 20px; -fx-background-color: #E8F8F5; -fx-border-color: #117A65; -fx-border-width: 2px;");

        GridPane gd = new GridPane(); // We Will Create A GridPane For The Buttons
        gd.setAlignment(Pos.CENTER);

        gd.setHgap(10); // The Horizontal Gap Between Buttons
        gd.setVgap(10); // The Vertical Gap Between Buttons
        gd.setStyle("-fx-padding: 20px; -fx-background-color: #D6DBDF;");

        // The Button Texts Will Be Taken In An Array
        String[] bt = {
            "7", "8", "9", "/",
            "4", "5", "6", "*",
            "1", "2", "3", "-",
            "0", "C", "=", "+"
        };

        // This Is The Normal Style For Buttons
        final String normal = "-fx-font-size: 18px; -fx-background-color: #AED6F1; -fx-text-fill: #154360; -fx-background-radius: 10;";
        // This Is The Style When Buttons Are Pressed
        final String pressed = "-fx-font-size: 18px; -fx-background-color: #5DADE2; -fx-text-fill: white; -fx-background-radius: 10;";

        int rw = 1; // Variable For Row
        int cl = 0; // Variable For Column

        // We Will Use A Loop To Create And Add Buttons
        for (String txt : bt)
        {
            Button zap = new Button(txt); // The Button Will Be Created

            // The Size And Style Will Be Provided
            zap.setPrefSize(60, 60);
            zap.setStyle(normal);

            zap.setOnAction(e -> click(txt)); // We Will Call The click() Method

            // The Button Color Will Change With Mouse Press
            zap.addEventHandler(MouseEvent.MOUSE_PRESSED, e -> zap.setStyle(pressed));
            zap.addEventHandler(MouseEvent.MOUSE_RELEASED, e -> zap.setStyle(normal));

            gd.add(zap, cl, rw); // The Button Will Be Added To The Grid

            // Logic To Move To The Next Column And Row
            cl++;
            if (cl > 3)
            {
                cl = 0;
                rw++;
            }
        }

        // We Will Create A VBox To Take The TextField And Buttons
        VBox layout = new VBox(15, tf, gd);
        layout.setAlignment(Pos.CENTER);
        layout.setStyle("-fx-padding: 20px; -fx-background-color: #EBF5FB;");

        // The Scene Will Be Created And Called To The Stage
        Scene sc = new Scene(layout, 300, 400);
        primaryStage.setTitle("Calculator");
        primaryStage.setScene(sc);

        primaryStage.show(); // The Window Will Display With show()
    }

Explanation Of The Code Snippet:

  • First, the TextField tf is created and made read-only, so the user can only type with the buttons.
  • Next, we align the text to the right, like a real calculator, and give the display a style.
  • After that, the GridPane gd is created, centered, and given 10-pixel gaps between the buttons.
  • Then, the array bt holds the text of all 16 buttons, and two variables, rw and cl, keep track of the row and column.
  • We also store two styles as strings: normal for a button at rest and pressed for a button being clicked.
  • A for-each loop creates one button for each text in the array. Each button calls click() when it is clicked, turns darker blue while the mouse is pressed, and goes back to normal when the mouse is released.
  • After 4 buttons, the loop moves to the next row, which gives us the 4x4 grid.
  • Then, the VBox layout stacks the display on top of the button grid.
  • In the end, the Scene sc is created with a size of 300 by 400 pixels, set on the Stage, and shown.

Section 4: The click() Method For Button Clicks

The fourth section is the click() method. Every time we click a button on the calculator, this method decides what to do based on the button's text.

    private void click(String txt) // Method Will Handle All The Button Clicks
    {
        if ("0123456789".contains(txt)) // If Any Number Digit Is Clicked
        {
            if (newNumber)
            {
                tf.clear(); // The Previous Number Or Message Will Be Cleared
                newNumber = false;
            }
            tf.appendText(txt); // The Digit Will Come To The Display
        }
        else if (txt.equals("C")) // If The Clear (C) Button Is Clicked
        {
            tf.clear();
            n1 = 0;
            opr = "";
            newNumber = false;
        }
        else if (txt.equals("=")) // If The Equal (=) Button Is Clicked
        {
            calculate(); // The calculate() Method Will Be Called
        }
        else // If Any Operator Is Clicked
        {
            if (!opr.isEmpty() && !newNumber)
            {
                calculate(); // Finish The Waiting Operation First, Like In 3 + 6 + 2
            }
            try
            {
                n1 = Double.parseDouble(tf.getText()); // Store The First Number
                opr = txt;
                newNumber = true;
            }
            catch (NumberFormatException ex)
            {
                // The Screen Is Empty Or Shows A Message, So We Ignore The Operator
            }
        }
    }

Explanation Of The Code Snippet:

  • The method uses a long if-else chain to check which button was clicked.
  • If a digit was clicked, it is added to the display. If newNumber is true, the display is cleared first, so the digit starts a new number.
  • If Clear (C) was clicked, the display and all the stored values are reset.
  • If Equals (=) was clicked, the calculate() method is called.
  • If an operator was clicked, the calculator first finishes any operation that is still waiting. That is what makes 3 + 6 + 2 work: when you press the second +, it shows 9.0 before you type the 2.
  • Then it stores the number on screen as n1 and remembers the operator.

Why the try and catch? Double.parseDouble() throws a NumberFormatException if the text is not a number, for example when the screen is empty or shows an error message. Catching it means pressing an operator at the wrong time simply does nothing, instead of printing an error. You can read more about this and other common Java errors in our guide.

Section 5: The calculate() Method For Arithmetic

Section 5 is the calculate() method. It is the only method with no JavaFX design work in it. It only does the math.

    // Method To Perform Arithmetic Calculation
    private void calculate()
    {
        if (opr.isEmpty() || tf.getText().isEmpty()) // If No Operator Is Pressed
        {
            return;
        }

        double n2 = Double.parseDouble(tf.getText()); // Variable For The Second Number
        double res = 0;

        // Switch Case For Different Operators
        switch (opr)
        {
            case "+": res = n1 + n2; break;
            case "-": res = n1 - n2; break;
            case "*": res = n1 * n2; break;
            case "/":
                if (n2 != 0) // Handling The Division By Zero
                    res = n1 / n2;
                else
                {
                    tf.setText("Cannot divide by zero");
                    opr = "";
                    newNumber = true; // The Next Digit Will Clear The Message
                    return;
                }
                break;
        }

        // The Result Will Be Displayed
        tf.setText(String.valueOf(res));
        opr = "";

        newNumber = true; // The Calculator Will Be Ready For The Next Input
    }

Explanation Of The Code Snippet:

  • First, we check whether an operator was pressed and whether there is a number on screen. If not, the method simply returns.
  • If there is, the number on screen becomes the second number, n2.
  • Then, a switch statement does the operation that matches the stored operator.
  • For division, we check for zero ourselves. With double values, Java does not throw an exception for dividing by zero. It quietly gives Infinity (or NaN, which means "not a number", for 0 / 0), so we show a clear message instead.
  • In the end, the result is shown on the display, and newNumber is set so the next digit starts a new number.

Section 6: The main() Method

The last section is the main() method. It is the smallest section, and it is not complicated at all.

    // Main Method To Launch The JavaFX Application
    public static void main(String[] args)
    {
        launch(args);
    }
}

Explanation Of The Code Snippet:

  • The main() method calls launch().
  • launch() comes from the Application class. It starts JavaFX, creates the window, and calls our start() method.
  • The last closing brace ends the ZapCalculator class.

Understanding The JavaFX Calculator With An Output Walkthrough

Now let us see the calculator in action, step by step.

1. Entering The First Number: When we run the code, the calculator window opens. Then we click a number button, like 3. While you hold it down, it turns a darker blue, and when you let go, 3 appears on the screen.

JavaFX calculator after entering the first number, 3

2. Choosing The Operator: Next, we press an operator. Here we press the Add (+) button. The + sign is not shown on the screen, but the calculator remembers it.

JavaFX calculator after choosing the add operator

3. Entering The Second Number: After choosing the operator, we enter the second number by pressing 6. The first number (3) disappears from the screen, and 6 takes its place.

JavaFX calculator after entering the second number, 6

4. Pressing The Equals (=) Button: To get the result, we press the Equals (=) button. It turns a darker blue while pressed because of the pressed style.

JavaFX calculator while pressing the equals button

5. Getting The Final Output: As soon as we press Equals, the result of the addition appears: 9.0. It shows a decimal point because the calculator does its math with double values.

JavaFX calculator showing the result of 3 plus 6

6. Clearing The Calculator: To start a new calculation, we press the Clear (C) button, and the screen is cleared.

JavaFX calculator after pressing the clear button

Edge Cases We Tested

Teachers love to test the tricky cases, so we ran these through the calculator too. Each row starts from a freshly opened calculator (or right after pressing C). Here is what the display shows at the end of each sequence:

Buttons pressedDisplay showsWhy
3 + 6 =9.0Normal addition.
3 + 6 + 2 =11.0The second + finishes 3 + 6 first.
7 - 2 * 3 =15.0It works left to right, like a basic pocket calculator: (7 - 2) x 3.
9 / 0 =Cannot divide by zeroOur own check in calculate().
9 / 0 = 55The next digit clears the message.
+ 5 =5An operator on an empty screen is ignored.

If your assignment asks for normal math order (multiplication before subtraction), you will need to store the whole expression and evaluate it at the end. That is a good next step once this version works.

Ideas to extend the calculator:

  • Add a decimal point (.) button, and make sure a number cannot get two decimal points.
  • Show whole-number results without the ".0", for example with a check like res == (long) res.
  • Let the user type with the keyboard by handling key presses on the Scene.
  • Move the button styles into a CSS file, like in the CSS example above.

Want to compare how the same project looks in another language? We also built a Python GUI calculator with Tkinter.

Comparison Table Between JavaFX And Other GUI Frameworks

We have seen that other frameworks were used for Java GUI development before JavaFX appeared. In this section, we compare them in a table.

The table shows the differences between JavaFX, Swing, AWT, and web-based UIs (apps built with HTML, CSS, and JavaScript).

CriteriaJavaFXSwingAWTWeb-based UIs
Included in the JDK?No, a separate download since Java 11YesYesNo, runs in a browser
Look and stylingModern, styled with CSSClassic, with swappable "look and feel" themesUses the operating system's own controlsStyled with CSS
Layout in a separate fileYes, with FXMLNo, layout is in Java code (or made with a visual GUI builder)NoYes, with HTML
Built-in charts, animations, mediaYesNo, needs extra librariesNoThrough JavaScript libraries
DrawingUses the graphics card (GPU) when availableDrawn by Java (Java 2D)Drawn by the operating systemDrawn by the browser
Learning curveModerateModerateSimple, but limitedDepends on the framework
New features todayYes, a new release every six monthsMostly bug fixesMostly bug fixesYes

Oracle once presented JavaFX as the replacement for Swing, but Swing never went away. It is still part of the JDK, and many older apps and some courses still use it. For a new Java desktop app, JavaFX is usually the better pick. If you are still deciding which language to use for a GUI project in the first place, our guide to the best GUI programming languages compares Java with Python, C++, and others.

What Are Some Real-World Applications Of JavaFX?

From what we have discussed so far, you can see that JavaFX is a very useful framework for building GUIs. This section looks at the areas where JavaFX is used in the real world.

1. Financial Applications:

One of the biggest areas is finance. Financial desktop applications need live charts and data that updates in real time, and JavaFX's built-in charts and fast drawing make it a good fit.

When To Use In Real-World Applications:

  • In desktop trading platforms, JavaFX can show interactive charts of live stock market data.
  • In financial dashboards, JavaFX can show real-time updates on transactions.

2. Enterprise Software Solutions:

When companies build internal desktop software, JavaFX helps them create clean, easy-to-use interfaces that employees are happy to work with every day.

When To Use In Real-World Applications:

  • JavaFX can be used to build HR management systems and CRM applications.
  • With JavaFX, we can build a desktop point of sale (POS) system with touch-friendly buttons and tables.

3. Industrial and IoT Applications:

JavaFX is not only used in finance and business software. It is also used in factories and with IoT (Internet of Things) devices, mainly to show sensor data in a way that is easy to read.

When To Use In Real-World Applications:

  • JavaFX can be used to build control screens for industrial automation systems, like SCADA (Supervisory Control and Data Acquisition) systems.
  • JavaFX can be used in IoT dashboards to show real-time sensor data and analytics. It even runs on small devices like the Raspberry Pi.

What Is The Role Of Third-Party Libraries In JavaFX?

With JavaFX alone, we can build a complete, modern GUI application. But if we want to add even more features, we can use JavaFX with third-party libraries.

Many third-party libraries can make GUI development faster and the result better looking. Here are a few important ones:

  • ControlsFX: Adds extra controls that JavaFX does not have, like notifications, a check list box, and a range slider.
  • AtlantaFX: A collection of modern CSS themes that give your app a fresh, flat look with one line of code. (You may see JFoenix mentioned in older tutorials for Material Design. It has not been updated in years and has known problems with newer JavaFX versions, so it is best avoided in new projects.)
  • MigLayout: A powerful layout manager that makes complex screen layouts simpler. It has a JavaFX version called MigPane.
  • FXGL: A game engine built on JavaFX. It is a good choice if your project is a 2D game.
  • Apache PDFBox: A general Java library for creating and editing PDF files. In a JavaFX app, you can use it for features like "Export report as PDF".

What Are Some Performance Considerations In GUI Development With JavaFX?

If you think working with JavaFX is always simple, think again. Along with learning the framework, there are some performance points to keep in mind. Let us check the following list.

  • If the scene graph has too many nodes, drawing the screen gets slower. Keep your layouts as simple as you can.
  • Very heavy or complicated CSS can also slow down drawing.
  • JavaFX uses the graphics card (GPU) when it can and falls back to slower software drawing when it cannot. Run your app with java -Dprism.verbose=true ... to check. Look for the line that starts with Initialized prism pipeline:. If it ends in SWPipeline, JavaFX is drawing without the GPU. A name like D3DPipeline or ES2Pipeline means it is using the graphics card.
  • If you create new UI components every time instead of reusing them, memory use goes up.
  • JavaFX lets you "listen" for changes and "bind" one value to another, so the screen updates by itself. Adding too many of these, especially ones you never remove, can slow down updates and waste memory.
  • Never do slow work on the JavaFX Application Thread. This one is the most important.

Keep Slow Work Off The JavaFX Application Thread

JavaFX runs all your event handlers and draws the screen on one thread, called the JavaFX Application Thread. If a button click starts something slow, like reading a big file or calling a web service, the whole window freezes until it finishes. The user cannot click, type, or scroll, and the window may show "Not Responding".

The fix is to run slow work on a background thread. JavaFX gives us the Task class for exactly this. Here is a small, complete example:

import javafx.application.Application;
import javafx.concurrent.Task;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class SlowTaskDemo extends Application
{

    @Override
    public void start(Stage primaryStage)
    {
        Label status = new Label("Click the button to start.");
        Button start = new Button("Start Slow Task");

        start.setOnAction(e -> {
            // The Slow Work Goes Inside A Task
            Task<String> task = new Task<>() {
                @Override
                protected String call() throws Exception
                {
                    Thread.sleep(3000); // Pretend This Is A Big File Or A Web Request
                    return "Done! The window never froze.";
                }
            };

            // This Runs On The JavaFX Thread When The Task Finishes
            task.setOnSucceeded(done -> {
                status.setText(task.getValue());
                start.setDisable(false);
            });

            status.setText("Working...");
            start.setDisable(true);
            new Thread(task).start(); // Run The Task On A Background Thread
        });

        VBox root = new VBox(15, status, start);
        root.setStyle("-fx-padding: 20px; -fx-alignment: center;");

        primaryStage.setTitle("JavaFX Background Task");
        primaryStage.setScene(new Scene(root, 350, 150));
        primaryStage.show();
    }

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

Output: When you click the button, the label changes to "Working..." and the button is disabled. For three seconds, the window stays fully responsive. Then the label changes to "Done! The window never froze." and the button works again.

The slow part goes inside call(), which runs on the background thread. setOnSucceeded() runs back on the JavaFX Application Thread when the task is done, so it is safe to update the label there. If you put Thread.sleep(3000) directly inside the button's action instead, the window would freeze for three seconds.

What Are Some Common Mistakes With GUI Development In JavaFX?

As we get close to the end, let us look at the most common mistakes students make with JavaFX. Once you know these, you can avoid them, or fix them fast when you see the error. We triggered each of these errors ourselves, so the messages below are real.

  • Forgetting to extend Application. Your main class must extend the Application class. Without it, there is no start() method for JavaFX to call, and launch() will not compile.
  • Not setting up JavaFX. You get package javafx.application does not exist when compiling, or NoClassDefFoundError: javafx/application/Application or JavaFX runtime components are missing when running. Go back to the setup section and add the --module-path and --add-modules options, or use Maven or Gradle.
  • Putting the CSS or FXML file in the wrong folder. getClass().getResource("zap.css") looks for the file next to the compiled class. If the file is not there, getResource() returns null, and on Java 15 or newer you get this error:
    NullPointerException: Cannot invoke "java.net.URL.toExternalForm()" because the return value of "java.lang.Class.getResource(String)" is null
    For a missing FXML file, the error is IllegalStateException: Location is not set. instead. In a simple project, keep the files in the same folder as your Java file. In a Maven or Gradle project, put them in src/main/resources, inside the same package folders as your class.
  • Creating windows in main() before launch(). Code in main() runs on the main thread, not the JavaFX Application Thread, so new Stage() there fails with IllegalStateException: Not on FX application thread. Build your UI inside start(), which is the real entry point of a JavaFX app.
  • Changing the UI from a background thread. If a background thread tries to change what is on screen, for example by adding a node to a layout, JavaFX may throw IllegalStateException: Not on FX application thread. Some changes do not throw an error but cause random glitches instead. Update the UI from setOnSucceeded() in a Task, or wrap the change in Platform.runLater(() -> ...).
  • Forgetting to set the Scene or show the Stage. Sometimes we create all the UI elements but forget to call setScene() or show() on the Stage. Then nothing appears on the screen. So, always double-check the last few lines of start().

Conclusion

In the end, we can say that knowing "JavaFX for GUI Development" is a very useful skill for any Java student. Once you understand the Stage, the Scene, and nodes, building a project like a GUI calculator is not that complicated.

We recommend getting comfortable with the basics of Java before moving on to advanced topics like JavaFX. And if you are stuck on a deadline, you can always reach out to us for help with a JavaFX assignment.

Takeaways:

  • Since Java 11, JavaFX is a separate download. Add it with --module-path and --add-modules, or with Maven or Gradle.
  • The Application class, Stage, Scene, and nodes are the main parts of every JavaFX app.
  • We can use a CSS file with JavaFX to style desktop apps just like web pages.
  • We can use FXML files to keep the layout separate from the Java code.
  • We can add animations like fading and moving with JavaFX's built-in transitions.
  • A GUI calculator combines all of this: a TextField display, a GridPane of buttons, a click() method for events, and a calculate() method for the math.
  • Keep slow work off the JavaFX Application Thread by using a Task.
  • Third-party libraries like ControlsFX and AtlantaFX can add even more features to JavaFX.

Frequently Asked Questions

1. Is JavaFX still used in 2026?

Yes. JavaFX is an active open-source project with a new release every six months, alongside the JDK. It is used for desktop tools, dashboards, and business apps, and it is still taught in many Java courses. It is not built into the JDK anymore, but it is easy to add.

2. Is JavaFX included in the JDK?

Not since Java 11. Before that, Oracle's JDK (versions 8, 9, and 10) included it. Now you download the JavaFX SDK separately from the OpenJFX site, or add it as a dependency with Maven or Gradle.

3. How do I fix "JavaFX runtime components are missing"?

This error usually means the JavaFX jar files are on the classpath instead of the module path, so Java does not load them as modules. Run your program with --module-path path/to/javafx-sdk/lib --add-modules javafx.controls (add javafx.fxml if you use FXML), or run it through your IDE or build tool with the JavaFX plugin set up.

4. Should I use JavaFX or Swing for a school project?

First, check your assignment. If it names Swing or JavaFX, use that one. If you get to choose, JavaFX is usually the better choice for a new project, because it supports CSS styling, FXML layouts, built-in charts, and animations. Swing is a good pick if your course materials use it, since it comes with the JDK.

5. What is FXML in JavaFX?

FXML is an XML file that describes a JavaFX screen, like which buttons and labels it has and how they are arranged. Your Java code loads it with FXMLLoader. It keeps the layout separate from the logic, and you can design FXML screens visually with the free Scene Builder tool.

6. Why does my JavaFX window freeze when I click a button?

Your button is probably doing slow work, like a long loop, Thread.sleep(), or a file or network call, on the JavaFX Application Thread. That thread also draws the screen, so the window stops responding. Move the slow work into a Task that runs on a background thread, and update the UI when the task finishes.