I looked at my watch: 21.15. Outside it"s pitch dark. Autumn is coming. How long is it going to last? Enormously… till spring. For foggy cold days, for those who feel the need to study and perfect, I will bring a new topic to your attention, a topic I haven"t approached yet, JavaFX. My hope is to make this technology appeal to the magazine"s readers, as I consider it truly remarkable. I have written this article together with Diana Balan, Java Developer at Accesa, whom I thank a lot for the ideas and support.
We will begin this article on JavaFX with a short history.
JavaFX is the descendant of F3 (Form Follows Function), whose father is Chris Oliver. In 2010, Oracle announced that the development of JavaFX Script Language will be interrupted, and instead, it will be ported on Java, forming thus the JavaFX 2 Platform. This laid the foundation for JavaFX to become the most important environment for rich client applications.
JavaFX API is run by an engine made of subassemblies. It integrates the new high performance graphic engine called Prism, the efficient windowing system called Glass and a media engine. Glass Windowing Toolkit is responsible with providing a native service which includes window management, timer management and surface management. Also, it connects the JavaFX platform with the native operating system. Moreover, Glass is responsible with the management of the event queue. If AWT manages its own event queue, Glass uses the native queue of the operating system. Glass Toolkit runs in the same thread as the JavaFX application. In AWT, a parallel thread was being created to that of Java.
A rich client application is an application with an interface which refers the backend without thus overcrowding the user interface. JavaFX has a complete set of buttons, diagrams, tables and layout containers which we use in order to create rich user interfaces. In addition, we can use CSS styles. All the components can be connected and they display backend data.
Generally, a rich client application has the following features:
A JavaFx application is a basic Java application which allows JavaFX features. The minimum necessary code to run a JavaFx application consists of:
There are three types of JavaFX applications:
import javafx.application.Application;
import javafx.stage.Stage;
public class JavaFXApplication extends Application {
@Override
public void start(Stage stage) {
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
A stage (javafx.stage.Stage) is a top level GUI container for all the graphic objects, and a scene (javafx.scene.Scene) is the main container. The primary stage is built by the platform, but other stage objects can also be built by the application. The stage objects must be built and modified in the JavaFX application thread.
Individual articles which are within the graphic scene are called nodes. Each node is classified as one of:
The first node of the tree is called root and it does not have a parent.
The graphic scene is, therefore, an arborescent structure. The JavaFX API makes the graphic interface to be easier to create, especially when complex visual effects and transformations are involved. The API of the JavaFX graphic scene is a retained mode, meaning that it manages an internal model of all the graphic objects of the application. It knows at any time which objects to display, which areas of the screen need redrawing and how it should be rendered in the most efficient manner. This significantly reduces the quantity of code necessary in the application.
We improve the former application by adding a text button and a layout container. The button will be a leaf node, and the StackPane a root node.
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;
public class JavaFXApplication extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) {
primaryStage.setTitle("Hello World!");
Button btn = new Button();
btn.setText("Say "Hello World"");
btn.setOnAction(new EventHandler() {
@Override
public void handle(ActionEvent event) {
System.out.println("Hello World!");
}
});
StackPane root = new StackPane();
root.getChildren().add(btn);
primaryStage.setScene(new Scene(root, 300, 250));
primaryStage.show();
}
We will create an equivalent application using FXML. FXML offers the following advantages:
When we create a JavaFX FXML application, we have to create three files:
Parent root=null;
try {
root = FXMLLoader.load(getClass().getResource("Sample.fxml"));
} catch (IOException e) {
e.printStackTrace();
}
stage.setScene(new Scene(root));
The FXMLLoader.load() method loads the object hierarchy from the resource file Sample.fxml and assigns it to the variable called root. This class is the Model in the MVC pattern. The last part of the action is setting the scene. The Sample.fxml file is the file where we build the user interface
This file represents the View in the MVC pattern. The root node is AnchorPane, and the descendant nodes are Button and Label.
The Sample.java file is the controller file of the user interface. Its name has to be identical with that of the view fxml class.
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;
public class Sample 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
}
}
The applications in this article were developed by using Eclipse Luna, as Java Standard projects in which I included the libjfxrt.jar package.
Thank you very much for your patience to read the article and we are looking forward to discuss it with you, as always.