Hello World with JavaFX
Now that we have got acquainted with JavaFX, what it is and how it is different from HTML5, it is time to start building small but important applications in this latest Java library for desktop apps.
As per the programming tradition, we will be beginning our journey with a small “Hello World” application.
2 ways to write JavaFX apps
There are 2 completely different ways to writing a JavaFX Application which makes writing apps more comfortable because you get to choose the way you want.
When I first started building JavaFx apps, I was a little confused because the tutorials I came across used completely different approaches to the same applications they were building. Once I understood it, we have 2 options when we write a program in JavaFx. I was interested in learning both approaches so I could get a firmer hold on the whole ‘JavaFx experience’.
Moving forward, I expect that I will continue to provide my examples in both formats. I am using NetBeans for all examples on JavaFx tutorials as well as SceneBuilder as a drag-and-drop interface designer for FXML.
Layout of a JavaFX app
Irrespective of which approach we use to write our JavaFX apps, they BOTH follow the same overall layout.
- Stage: This is the outermost container of the application and contains the entire program.
- Scene: The object directly contained by the stage. Just like a theatre, a scene can only exist inside a stage and a stage can have only one scene at any given time. When the story changes, the play goes to a NEW scene. In the program when you want to switch to another view you can also have the Stage change to a different Scene.
- Root Pane/Container: The container can contain other parts of the application like buttons, labels, textfields, etc. Depending on how we want to layout our apps, the root container can be represented by a number of JavaFX containers such as the StackPane, GridPane, BorderPane, FlowPane, etc. These different types of containers go beyond the scope of this simple tutorial, but if you know Swing, these should be very much familiar to you. In both examples I will be using a basic container called a “StackPane”. Now let’s look at the 2 ways you can get a new program started in JavaFX.
Using Pure Java
In the very first approach, we will be using pure Java code to construct our app. All the containers and their elements will be made using Java code, just like you can do in Swing based applications.
In this approach, we will write all of the code to create the user interface and the logic of the interface in the same class. Now, in more advanced apps we would likely use different classes to describe various elements we are using, but it is possible to get the job done completely in 1 class.
When we launch NetBeans we will choose the following: “JavaFX Application” and give it a name.
When we do this, we will get back some starting code for our Hello World application. Right now, my project has a simple structure.
With a bit of refactoring, I modified “Hello World” using a new type of Java expression called a LAMBDA for the button-click code. This way I can write a separate method called “btnClick” and connect it to my button with 1 simple line of code :
btn.setOnAction(e -> btnClick());
When we run the program we will see this, and the button will print a message every time you click it. I made the application small at 200 by 50 when I created the Scene object.
This is how the app looks like when launched:
Till now, the source code for the app is rather simple:
package discoversdk;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
/**
* @author Shubham
*/
public class JavaFXDemo extends Application {
@Override
public void start(Stage primaryStage) {
Button btn = new Button("Click Me");
//using lambda to attach listener method to button click
btn.setOnAction(e -> btnClick());
//make a frame
StackPane frame = new StackPane();
//add button to the frame
frame.getChildren().add(btn);
Scene scene = new Scene(frame, 300, 250);
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
}
public void btnClick() {
System.out.println("DiscoverSDK says Hello !!");
}
public static void main(String[] args) {
launch(args);
}
}
Using FXML
When I first saw FXML, I was both excited and a little scared at the same time. I felt like I was learning Java all over again but the Scene Builder tool looked so cool and so powerful that I had to press on and figure it out. We won’t get into the SceneBuilder part in this example but I will show you the FXML document that gets generated, along with the 2 (yes that’s right 2) other classes. In NetBeans, choose the following:
This time, the project structure was different as shown:
Clearly, Netbeans created more files here with some fxml extension. Let us figure out what they are.
FXML Document
This is very similar to HTML and we can write code to “describe” the layout of the application. No code is written here, but there is a place to point this file to the java class that actually contains the code. This uses a declarative approach to building the user interface. This is how the file looks:
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<AnchorPane id="AnchorPane" prefHeight="200" prefWidth="320" xmlns:fx="http://javafx.com/fxml/1" fx:controller="discoversdk.FXMLDocumentController">
<children>
<Button layoutX="126" layoutY="90" text="Click Me!" onAction="#handleButtonAction" fx:id="button" />
<Label layoutX="126" layoutY="120" minHeight="16" minWidth="69" fx:id="label" />
</children>
</AnchorPane>
Controller Class
This class contains the code needed to run when the user interacts with the app. As a simple example, when the user hits the button, the code for that button will be in this class. This is where we will spend the most amount of time writing the code for our application.
package discoversdk;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Label;
/**
* @author shubham
*/
public class FXMLDocumentController implements Initializable {
@FXML
private Label label;
@FXML
private void handleButtonAction(ActionEvent event) {
System.out.println("You clicked me!");
label.setText("Hello World!");
}
@Override
public void initialize(URL url, ResourceBundle rb) {
// TODO
}
}
Main Application / Startup Class
Although it has the important job of LAUNCHING the application, nothing else much goes on in here at this point. This gets generated for you by NetBeans and you can leave it as is. This class will load up a scene from the FXML document and put it on the stage.
package discoversdk;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
/**
* @author shubham
*/
public class JavaFXDemoFxml extends Application {
@Override
public void start(Stage stage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml"));
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
FXML Document – A Closer Look
This is the code that is auto-generated by NetBeans. If you know HTML, it looks a little familiar. We can actually write our own code in here to modify the design, which I found very different coming from a Swing/coding background.
Get the SceneBuilder
As I mentioned earlier, I will be using SceneBuilder to design the FXML user interface. You can download SceneBuilder here. Once you have it, Netbeans will automatically open it up as the editing tool when you are working with the FXML document. Here is what the FXML document looks like when you are editing it in Scene Builder. More specific details about SceneBuilder will be covered in another article.
Conclusion
What are your thoughts about the 2 approaches? Do you already prefer one over the other? Or if you are just starting out, do you plan on spending time getting more comfortable with FXML and SceneBuilder? Do let me know in the comments below.
Recent Stories
Top DiscoverSDK Experts
Compare Products
Select up to three two products to compare by clicking on the compare icon () of each product.
{{compareToolModel.Error}}
{{CommentsModel.TotalCount}} Comments
Your Comment