JavaFX 2 Tutorial - Part 1: Scene Builder

→ UPDATED VERSION for Java 8 available: JavaFX 8 Tutorial

Screenshot AddressApp Part 1

Topics in Part 1

  • Getting to know JavaFX 2
  • Creating and starting a JavaFX Project
  • Using Scene Builder to design the user interface
  • Basic application structure using the Model-View-Controller (MVC) pattern

Prerequisites

  • Latest Java JDK 7 that includes JavaFX 2.2 or greater.
  • Eclipse 4.2 or greater with e(fx)clipse plugin. The easiest way is to download the preconfigured distro from the e(fx)clipse website. As an alternative you can use an update site for your Eclipse installation.
  • Scene Builder 1.1 or greater

Play around with the JavaFX widgets in the JavaFX Ensemble (Under Downloads, go to JavaFX Demos and Samples Downloads, unzip the samples and click on Ensemble.jar):

  • JavaFX Ensemble is a gallery of over 100 sample applications that use a wide range of JavaFX features.
  • Contains source code for each sample.
  • Contains links to API documentation (JavaDoc).

Some other helpful links:

Now, let's get started!


Create a new JavaFX Project

In Eclipse (with e(fx)clipse installed) go to File | New | Other... and choose JavaFX Project. Specify the Name of the project (i.e. AddressApp).

Create the Packages

Right from the start we will follow good software design principles. One very important principle is that of Model-View-Controller (MVC). According to this we divide our code into three units and create a package for each (Right-click on the src-folder, New... | Package):

  • For the controller classes: ch.makery.address
  • For the view classes: ch.makery.address.view
  • For the model classes: ch.makery.address.model

Create the FXML Layout File

There are two ways to create the user interface. Either using an XML file or programming everything in Java. Looking around the internet you will encounter both. We will use XML (ending in .fxml) for most parts. I find it a cleaner way to keep the controller and model separated from each other. Further, we can use the graphical Scene Builder to edit the XML. That means we will almost never have to directly work with XML.

Right-click on the view package and create a new FXML Document called PersonOverview.

New FXML Document

New PersonOverview


Design with Scene Builder

Note: If you get stuck somewhere, watch the Getting Started with JavaFX Scene Builder YouTube Film. This helps a lot!

Right-click on PersonOverview.fxml and choose Open with Scene Builder. Now you should see the Scene Builder with just an AncherPane (visible under Hierarchy on the left).

  1. Select the Anchor Pane in your Hierarchy and adjust the size under Layout (right side):
    Adjust size

  2. Add a Split Pane (Horizontal Flow) by dragging it from the Library into the main area. Right-click and select Fit to Parent.
    Fit to Parent

  3. Add a TableView into the left side. Select the TableView (not a Column) and set the following layout constraints. Inside an AnchorPane you can always set anchors to the four borders (more information on Layouts).
    Adjust sizes

  4. Go to the menu Preview | Preview in Window to see, whether it behaves right. Try resizing the window. The TableView should always keep the 10px distance to the surrounding border.

  5. Change the column text (under Properties) to "First Name" and "Last Name" and adjust the sizes.
    Adjust columns

  6. Add a Label on the right side with the text "Person Details". Adjust it's Layout using anchors.

  7. Add a GridPane on the right side, select it and adjust it's Layout.
    GridPane Layout

  8. Add some rows (under Layout | GridPane Rows). Add labels to the cells.
    Add labels

  9. Add the three buttons at the bottom. Tipp: Select all of them, right-click and call Wrap In | HBox. This groups them together. You might need to specify a Spacing inside the HBox.

  10. Now you should see something like the following. Please test it using the Preview Menu.
    Preview


Creating the Main Application

We need another FXML for our root layout which will contain a menu bar and wraps the just created PersonOverview.fxml?.

  1. Create another FXML Document inside the view package called RootLayout.fxml. This time, choose BorderPane as the root element.
    RootLayout

  2. Open it in the Scene Builder.

  3. Resize the BorderPane with Pref Width set to 600 and Pref Height set to 400.
    Resize BorderPane

  4. Add a MenuBar into the TOP Slot. We will not implement the menu functionality at the moment.
    MenuBar

  5. Now, we need to create the Main Java that starts up our application with the RootLayout.fxml and adds the PersonOverview.fxml in the center.

  6. Right-click on the controller package, New | Other... and choose JavaFX Main Class. We'll call it MainApp.
    New JavaFX Main Class

Understanding the JavaFX Main class

The generated MainApp.java class extends from Application and contains two methods. This is the basic structure that we need to start a JavaFX Application. The most important part for us is the start(Stage primaryStage) method. It is automatically called when we run the application.

As you see, the start(...) method receives a Stage as parameter. It's good to understand the basic concept of a graphical application with JavaFX:

New FXML Document Image Source: http://www.oracle.com/

It's like a theater play: The Stage is the main container which is usually a Window with a border and the typical minimize, maximize and close buttons. Inside the Stage you add a Scene which can, of course, be switched out by another Scene. Inside the Scene the actual JavaFX nodes like AnchorPane, TextBox, etc. are added.

Open MainApp.java and replace the code with the following:

package ch.makery.address;

import java.io.IOException;

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

public class MainApp extends Application {

    private Stage primaryStage;
    private BorderPane rootLayout;

    @Override
    public void start(Stage primaryStage) {
        this.primaryStage = primaryStage;
        this.primaryStage.setTitle("AddressApp");

        try {
            // Load the root layout from the fxml file
            FXMLLoader loader = new FXMLLoader(MainApp.class.getResource("view/RootLayout.fxml"));
            rootLayout = (BorderPane) loader.load();
            Scene scene = new Scene(rootLayout);
            primaryStage.setScene(scene);
            primaryStage.show();
        } catch (IOException e) {
            // Exception gets thrown if the fxml file could not be loaded
            e.printStackTrace();
        }

        showPersonOverview();
    }

    /**
     * Returns the main stage.
     * @return
     */
    public Stage getPrimaryStage() {
        return primaryStage;
    }

    /**
     * Shows the person overview scene.
     */
    public void showPersonOverview() {
        try {
            // Load the fxml file and set into the center of the main layout
            FXMLLoader loader = new FXMLLoader(MainApp.class.getResource("view/PersonOverview.fxml"));
            AnchorPane overviewPage = (AnchorPane) loader.load();
            rootLayout.setCenter(overviewPage);

        } catch (IOException e) {
            // Exception gets thrown if the fxml file could not be loaded
            e.printStackTrace();
        }
    }

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

Try to understand the code. The various comments should give you some hints about what's going on.

If you run the application now, you should see something like the screenshot at the beginning of this post.


What's Next?

In Tutorial Part 2 we will add some data and functionality to our AddressApp.


Comments