JavaFX

Move from console output to real windows. By the end of this lesson you'll be able to open a JavaFX window, lay out controls, respond to clicks, keep your UI in sync with property bindings, and style it all with CSS.

Learn JavaFX in our free Java course — a beginner-friendly interactive lesson with worked examples, a practice exercise and a quick reference.

Part of the free Java course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.

You should be comfortable with classes and objects (OOP) — JavaFX is built from classes you instantiate and extend — and with lambda expressions , which you'll use for event handlers. To run these examples you'll add the JavaFX libraries with Maven or Gradle .

A JavaFX app is like staging a play. The Stage is the physical window — the building the audience walks into. The Scene is the set for the current act: everything currently on display. The Nodes are the actors and props — your buttons, labels, and text fields.

Just as a theatre swaps the set between acts while the building stays put, you can swap a new Scene onto the same Stage to move from a login screen to a dashboard. The layout panes are the stage directions that tell each actor where to stand.

Every JavaFX app is a class that extends Application . You override one method, start(Stage stage) — JavaFX calls it for you once the runtime is ready, handing you the primary Stage (the window).

Inside start you build a tree of Nodes (the visible controls), put them in a Scene (which sets the window size), give the Scene to the Stage, and call stage.show() . In main you call launch(args) , which boots the JavaFX runtime and then calls your start .

💡 The chain to remember: launch() → start(Stage) → build Nodes → wrap in a Scene → stage.setScene(scene) → stage.show() .

You rarely position controls by pixel coordinates. Instead you drop them into a layout pane that arranges them for you and reflows when the window resizes. Four panes cover almost everything:

Panes nest freely: a BorderPane can hold a VBox in its centre, which holds a GridPane and an HBox . That's how real layouts are built — small panes inside bigger ones.

Controls are the interactive Nodes: a Button the user clicks, a Label that shows text, a TextField they type into. You make code run on a click with an event handler — pass a lambda to setOnAction .

A property is a value the UI can watch — like SimpleIntegerProperty . Binding ties one property to another: when the source changes, the target updates by itself. Bind a Label's textProperty() to a counter and you never touch the label again — it follows the number for you. That's reactive UI : describe the relationship once, and JavaFX maintains it.

💡 Analogy: A binding is a linked spreadsheet cell. Write =A1 in cell B1 and B1 mirrors A1 forever — you don't re-copy it every time A1 changes. label.textProperty().bind(count.asString()) is the same idea.

Fill in the two blanks marked ___ . You'll create a Button and set a label's text from a handler. The hints ( 👉 ) tell you exactly what goes in each gap.

Building the whole UI in Java works, but it mixes layout with behaviour. FXML is an XML file that describes the UI on its own — which panes and controls exist, and how they nest. A separate Controller class holds the behaviour.

Two attributes connect the FXML to the controller: fx:id="emailField" in the FXML matches an @FXML field of the same name, and onAction="#handleLogin" matches an @FXML method. FXMLLoader.load(...) reads the file, builds the Nodes, and injects them into the controller. The free Scene Builder tool lets you edit FXML by dragging.

Connect the FXML to the controller below by filling the two blanks: give the Label an fx:id and point the Button's onAction at the controller method.

JavaFX is styled with CSS that looks like the web's — selectors, pseudo-classes like :hover and :focused — but every property name starts with -fx- (so background-color becomes -fx-background-color ).

You target nodes by type ( .button ), by style class you assign with getStyleClass().add("btn-primary") or styleClass in FXML, or by id ( #title ). Attach the stylesheet with scene.getStylesheets().add(...) .

Now with the scaffolding removed. The starter has only a comment outline — you write the controls, the layout, and the click handler yourself. Use the worked examples above as a reference, and check your result against the expected output.

You can now build real desktop apps. You know the launch → start → Stage → Scene → show chain, how to arrange controls with VBox, HBox, BorderPane, and GridPane, how to respond to clicks with event handlers, how to keep the UI in sync with property bindings, and how to split UI from logic with FXML, controllers, and CSS.

Next up: Networking — sockets, HTTP clients, and talking to the web from your Java programs.

Practice quiz

In JavaFX, what is the difference between a Stage and a Scene?

  • Stage is the content; Scene is the window
  • They are the same thing
  • Stage is the window; Scene is the content shown inside it
  • Stage holds nodes; Scene holds the title bar

Answer: Stage is the window; Scene is the content shown inside it. The Stage is the actual window (frame, title bar); the Scene is the tree of Nodes shown inside it. One Stage shows one Scene at a time.

Which method must you call to boot the JavaFX runtime from main()?

  • launch(args)
  • start(args)
  • run(args)
  • show(args)

Answer: launch(args). launch(args) boots the JavaFX runtime and then calls your overridden start(Stage) method.

Which method do you override to build your first window, and what is passed to it?

You override start(Stage stage); JavaFX calls it once the runtime is ready, handing you the primary Stage.

Which layout pane arranges children in rows and columns for a labelled form?

  • VBox
  • GridPane
  • HBox
  • StackPane

Answer: GridPane. GridPane places nodes by column and row with add(node, column, row), ideal for labelled input forms.

How do you make code run when a Button is clicked?

  • button.setOnAction(e -> ...)
  • button.onClick(...)
  • button.addListener(...)
  • button.bind(...)

Answer: button.setOnAction(e -> ...). You pass a lambda event handler to setOnAction, which runs each time the button is pressed.

What does property binding like label.textProperty().bind(count.asString()) achieve?

  • It copies the value once
  • It disables the label
  • The label updates automatically whenever the bound property changes
  • It throws if count changes

Answer: The label updates automatically whenever the bound property changes. Binding ties the label's text to the property so the UI updates by itself when the source changes — reactive UI, no manual refresh.

What is FXML?

  • A CSS dialect for JavaFX
  • An XML file that describes the UI declaratively, separate from Java logic
  • A build tool for JavaFX
  • A threading API

Answer: An XML file that describes the UI declaratively, separate from Java logic. FXML is XML describing which controls and layouts exist and how they nest; a Controller class supplies the behaviour.

In FXML, which two attributes connect the view to its controller?

  • id and onClick
  • name and handler
  • ref and call
  • fx:id (matches an @FXML field) and onAction (matches an @FXML method)

Answer: fx:id (matches an @FXML field) and onAction (matches an @FXML method). fx:id matches an @FXML field of the same name, and onAction="#method" matches an @FXML method in the controller.

Why might a JavaFX UI freeze after a button click?

  • The Scene was garbage collected
  • Slow work ran on the JavaFX Application Thread, which also paints the screen
  • The Stage was not shown
  • FXML was missing

Answer: Slow work ran on the JavaFX Application Thread, which also paints the screen. Event handlers run on the Application Thread that draws the UI; doing slow work there blocks repaints. Move it to a background Task and update via Platform.runLater().

In JavaFX CSS, how is the background-color property written?

  • background-color
  • fx:background-color
  • -fx-background-color
  • css-background-color

Answer: -fx-background-color. JavaFX CSS prefixes every property with -fx-, so background-color becomes -fx-background-color.