Creating Our first JavaFX Application

Here, we are creating a simple JavaFX application which prints hello world on the console on clicking the button shown on the stage.

Part 1: Creating a new JavaFX project in Intellij and testing JavaFX

  1. Open Intellij
  2. Click ‘file’ in the top menu
  3. Choose new -> project
  4. In the left navigation of the pop-up, choose ‘JavaFX’
  5. Give your project a name - the other options should be OK by default

Start Java FX

  1. Click ‘next, no need to choose options on the next page, then choose ‘create’

A new window will open showing some basic code:

Start Java FX

You will notice that a basic stage and scene are set up for you.

You should see a green arrow in the HelloApplication file, indicating that your code can run.

  1. Run the example application. You should see a window pop up with a button labelled ‘Hello!’. Click the button and check that the event hander responds.

  2. Change the button text. Close your javaFX application simply closing the window.

  3. Change some values so that you understand how the application works:

    • In the default start() method you see in front of you, change the value of stage.setTitle() to “goodbye!!”. Run your application and understand what changed (HINT: look at the title in the frame of the application window)
    • Note that on line 13 there is a link to an fxml file called hello-view.fxml. Fnd this file within the ‘resources’ folder. Open this and see if you can find out how to alter the text that shows on the button by finding the <Button> tag and its text attribute. Change the button text to your name. To test your change you will need to go back to the HelloAppication.java file and run the application again.
    • Finally, lets change the text that is generated by the button event handler. For this we need to find the ‘controller’ class. This should be in the HelloController file in the same directory as your HelloApplication file. Find the event handler for onHelloButtonClick(), and change the output text to “Welcome to SD3”. Re-run your application and observe your changes.
    • NB: if the default application does not run, try creating the JavaFX project with an alternative JDK (on uni lab computers, try JDK 11 in the project creation screen)

Part 2: A basic GUI - No FXML

As part of our familiarisation of JavaFX we will start by coding our GUI nodes directly into the start method.

Later, we will revert back to using the FXML to control the layout and discuss its advantages.

The point of this section is to help you understand the relationship between:

  1. Comment out the lines that load the FXML file and set this as the file that defines the scene.

Start Java FX

There will be an error in the ‘setScene’ method.

  1. Add the necessary components to re-build the app:

    • FlowPane root=new FlowPane(); Creates a pane node for your stage, this is the most basic layout.
    • Scene scene = new Scene(root, 300,250); Create a scene, adds a pane and sets the window size
    • stage.setScene(scene); adds the scene to the stage

Note that you may have to add the following import statement to the top of your file…

import javafx.scene.layout.FlowPane;
  1. At this point, your code should look like this. You should be able to run it, but there will be nothing appearing in the window.

Start Java FX

  1. Now you can add some ‘nodes’ to your pane. When you add different interface elements you may need to add ‘import’ statements to ensure the correct libraries are present. IntelliJ should prompt you for these.

    • add a button:
        // Add a button
        Button btn1=new Button("Hello SD3");
        root.getChildren().add(btn1);

        // Add a label
        Label bl = new Label("This is my label");
        root.getChildren().add(bl);

        // Add a circle
        Circle circle = new Circle();
        circle.setCenterX(200);
        circle.setCenterY(200);
        circle.setRadius(50);
        circle.setFill(Color.BLUE);
        root.getChildren().add(circle);


Your finished code should look something like this. Note the import statements, IntelliJ should prompt you to add these when you add new types of components.


package com.example.sd3lab;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.FlowPane;
import javafx.stage.Stage;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;

import java.io.IOException;

public class HelloApplication extends Application {

    @Override
    public void start(Stage stage) throws IOException {

        // FXMLLoader fxmlLoader = new FXMLLoader(HelloApplication.class.getResource("hello-view.fxml"));
        // Scene scene1 = new Scene(fxmlLoader.load(), 320, 240);
        stage.setTitle("Hello!");
        FlowPane root=new FlowPane();
        Scene scene = new Scene(root, 300,250);
        stage.setScene(scene);
        // Add a button
        Button btn1=new Button("Hello SD3");
        root.getChildren().add(btn1);

        // Add a label
        Label bl = new Label("This is my label");
        root.getChildren().add(bl);

        // Add a circle
        Circle circle = new Circle();
        circle.setCenterX(200);
        circle.setCenterY(200);
        circle.setRadius(50);
        circle.setFill(Color.BLUE);
        root.getChildren().add(circle);

        stage.show();
    }

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


Experiment with some other GUI elements, use the link below for reference:

https://www.javatpoint.com/javafx-tutorial

Part 3: The ‘view’: Better GUI building with FXML

You should now be able to appreciate that using a separate, stuctured FXML file to define your GUI is going to be a lot easier once you’ve gone beyond a few elements.

  1. Go back to using the FXML file to create your scene by removing your code from the previous exercise and un-commenting the FXML related lines. Your HelloApplication should now look like this:


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

import java.io.IOException;

public class HelloApplication extends Application {

    @Override
    public void start(Stage stage) throws IOException {

        FXMLLoader fxmlLoader = new FXMLLoader(HelloApplication.class.getResource("hello-view.fxml"));
        Scene scene = new Scene(fxmlLoader.load(), 320, 240);
        stage.setTitle("Hello!");
        stage.setScene(scene);
        stage.show();
    }

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

Check that you can run this code and see your button and event handler again

Your hello-view.fxml file which should be in a subdirectory of ‘resources’, should not have changed since you created a new project. It should have the following contents:

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

<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.VBox?>

<?import javafx.scene.control.Button?>
<VBox alignment="CENTER" spacing="20.0" xmlns:fx="http://javafx.com/fxml"
      fx:controller="com.example.sd3lab.HelloController">
    <padding>
        <Insets bottom="20.0" left="20.0" right="20.0" top="20.0"/>
    </padding>

    <Label fx:id="welcomeText"/>
    <Button text="Hello! Lisa" onAction="#onHelloButtonClick"/>
</VBox>

  1. Add some additional GUI elements to the FXML file

For example, you can achieve a similar result as the former excercise by adding elements to the fxml file, nested into the VBox tags as follows:

Note that you will still run your code via the HelloApplication, start method, but you won’t have to do any work in this file.

By now, your work should look like the below:

Start Java FX

Part 4: Linking the ‘view’ to the ‘controller’

Now we have our GUI defined by the FXML file, lets look at how to create interactivity by adding event handlers to the controller and making changes to the view in response to user input.

  1. Find and open the controller class. For the default project, it will be called ‘HelloController’ and will be in the same directory as your HelloApplication file with the start() method.

  2. Note the contents of HelloController which should be as below. Note that the property and method names match the id values in the FXML files. Note also the @FXML annotation.

package com.example.sd3lab;

import javafx.fxml.FXML;
import javafx.scene.control.Label;

public class HelloController {
    @FXML
    private Label welcomeText;

    @FXML
    protected void onHelloButtonClick() {
        welcomeText.setText("Welcome to SD3");
    }
}
  1. Add an event handler to your new button in the FXML file

We can use the generic ‘onAction’ event for now, and notice the hash infront of the event handler method name

<Button fx:id="btn1" text="Another button" onAction="#onAnotherButtonClick"/>

(The new event handler method name will be in red until it is added to the controller class in the next step)

  1. Add an event handler method to the controller class. It can be empty for now.
    @FXML
    protected void onAnotherButtonClick() {
        
    }
  1. Create the body for the event handler to implement our chosen functionality. Lets say we want to change the colour of the circle.

    • First, we need to register the circle UI element with the controller class by making it a property
    @FXML
    private Circle c1;
    @FXML
    protected void onAnotherButtonClick() {
        c1.setFill(Color.RED);
    }

Your completed HelloController.java code should look like this:



import javafx.fxml.FXML;
import javafx.scene.control.Label;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;

public class HelloController {
    @FXML
    private Label welcomeText;

    @FXML
    private Circle c1;

    @FXML
    protected void onHelloButtonClick() {
        welcomeText.setText("Welcome to SD3");
    }

    @FXML
    protected void onAnotherButtonClick() {
        c1.setFill(Color.RED);
    }
}


Additional tasks