Introduction

Here is a simple introductory program to JavaFX:

import javafx.application.*;
import javafx.stage.*;
import javafx.scene.*;
import javafx.scene.layout.*;
import javafx.scene.control.*;

// javafx.application.Application is the basis for all JavaFX apps.
// Don't forget to have your window classes extend it!
public class HelloJavaFX extends Application
{
    // We only have one javafx.scene.control.Button in our
    // application
    private static Button btn;

    // Main is much less important in JavaFX, it only it used to call
    // the launch(String[]) method of Application
    public static void main(String[] args)
    {
        launch(args);
    }

    // This is a Java annotation, informing the compiler that this method
    // overrides a method in the superclass. Netbeans will remind you to
    // add these. They aren't required, but if you have it and misspell the
    // name of the method or incorrectly code its signature, the compiler
    // will give you an error.
    @Override
    // start(Stage) is the "main" of JavaFX. It is responsible for building and
    // displaying the user interface. In a simple application like this,
    // putting all of that code in start(Stage) is fine. However, as your apps
    // grow in complexity, it is better to abstract that logic out into
    // separate methods, called inside start(Stage).
    //
    // The javafx.stage.Stage argument, primaryStage, is the overall window of your 
    // application.
    public void start(Stage primaryStage)
    {
        // Create a javafx.scene.control.Button, set its display text, and its 
        // action event handler
        // Event handlers use lambda expressions (introduced in Java 8)
        // or anonymous classes (pre-Java 8) to run code when certain
        // events happen; in this case, the user pressing the button will
        // fire the event.
        btn = new Button();
        btn.setText("Click me please!");
        btn.setOnAction(e -> buttonClick());

        // Add the button to a javafx.scene.layout.BorderPane layout pane. 
        // Panes organize elements within a javafx.scene.Scene.
        // A BorderPane separates elements into five areas, top, right, center,
        // left, and bottom.
        BorderPane pane = new BorderPane();
        pane.setCenter(btn);

        // Add the layout pane to the scene. Scenes display 'nodes', or GUI 
        // elements like our layout pane.
        // The constructor's arguments are as follows:
        // Scene(<node>, <width>, <height>);
        // where:
        // <node> - the root node, usually a layout pane
        // <width> - the width of the scene
        // <height> - the height of the scene
        Scene scene = new Scene(pane, 300, 250);

        // Finalize and show the stage
        primaryStage.setScene(scene);
        primaryStage.setTitle("Welcome to JavaFX");
        primaryStage.show();
    }

    // This is the method we want to run when the button is pressed
    public void buttonClick()
    {
        if (btn.getText() == "Click me please!") {
            btn.setText("You clicked me!");
        } else {
            btn.setText("Click me please!");
        }
    }
}
Import Statements
Documentation

Documentation is ever more important as we explore JavaFX. Often there may be a class built-in that will provide you the functionality you're looking for. The documentation can be viewed online here:

Java 8 Documentation

Or simply by Googling javafx api.

Program Walkthrough

The class HelloJavaFX inherits, or extends, from the JavaFX superclass Application. Application manages the lifecycle of the GUI application. A GUI lifecycle is the steps a GUI application goes through during its execution. The lifecycle of an Application is as follows:

  1. Create a new Application instance.
  2. Call init(). By default, init() does nothing, but can be overriden to do processing before the user interface is shown.
  3. Call start(). This is the method implemented in the HelloJavaFX class.
  4. Call stop(). Again, by default stop() does nothing but can be overridden to perform any last minute operations, like closing file streams.

All of our GUI elements are declared as static, since we only have one window to display. More complicated applications that show multiple copies of the same window should use non-static elements.

Since we only have overridden start(), we'll see what happens there. It is reprinted here for clarity:

@Override
public void start(Stage primaryStage)
{
    btn = new Button()
    btn.setText("Click me please!");
    btn.setOnAction(e -> buttonClick());

    BorderPane pane = new BorderPane();
    pane.setCenter(btn);

    Scene scene = new Scene(pane, 300, 250);

    primaryStage.setScene(scene);
    primaryStage.setTitle("Welcome to JavaFX");
    primaryStage.show();
}

First, our @Override annotation prevents us from misspelling the overridden method. Again, Netbeans will remind you about these. Next, a Button is created. It is positioned within a BorderPane layout pane, which is added to a Scene, which is finally added to the primaryStage Stage.

Let's see how BorderPanes work in more detail. This time, we'll create an application that counts how many times a button has been clicked.

import javafx.application.*;
import javafx.stage.*;
import javafx.scene.*;
import javafx.scene.layout.*;
import javafx.scene.control.*;
 
public class ClickCounter extends Application
{
    private static Button btn;
    private static Label lbl;
    private static int clickCount = 0;
    
    public static void main(String[] args)
    {
        launch(args);
    }
    
    @Override
    public void start(Stage primaryStage)
    {
        btn = new Button();
        btn.setText("Click me please!");
        btn.setOnAction(e -> buttonClick());
        
        lbl = new Label();
        lbl.setText("You have not clicked the button.");
        
        BorderPane pane = new BorderPane();
        pane.setTop(lbl);
        pane.setCenter(btn);
        
        Scene scene = new Scene(pane, 250, 150);
        
        primaryStage.setScene(scene);
        primaryStage.setTitle("Click Counter");
        primaryStage.show();
    }
    
    public void buttonClick()
    {
        clickCount++;
        if (clickCount == 1) {
            lbl.setText("You've clicked the button once.");
        } else {
            lbl.setText("You've clicked the button " + clickCount + " times.");
        }
    }
}

Here, we've been introduced to the javafx.scene.control.Label element, used for displaying Strings of text. As you can see, our event handling method buttonClick() updates the Label's text to display how many times the Button has been clicked.