dcsimg
October 21, 2018
Hot Topics:

Understanding the Basic JavaFX Classes and How to Use Them

  • February 5, 2018
  • By Manoj Debnath
  • Send Email »
  • More Articles »

Java started its GUI journey with AWT, which later was replaced by a better GUI framework called Swing. Swing remained in the GUI arena for almost two decades. But, it lacks many of the present-day visual requirements that demand a sparkling look and feel apart from fluid functionality across multiple devices. The latest promising player in the Java GUI arena is JavaFX, without deprecating the older libraries AWT and Swing. Therefore, Java comes with three GUI toolkits side by side—AWT, Swing, and JavaFX—all doing almost similar jobs. The trendy JavaFX uses a somewhat different approach to GUI programming, especially in view of Swing; here, we'll delve into the basics, especially with respect to the use of fundamental classes and how they are used in programming.

A Glimpse at the Java GUI

Java always lacked a focused foundation in designing a GUI library, probably because it was not meant to develop desktop applications, at least initially. With time, popularity grew to an extent that people saw it as a general purpose programming language. Initially, the AWT toolkit was supplied with Java but later was superseded by the Swing GUI framework. They both are part of the same group of Java class libraries, called Java Foundation classes (JFC). Swing became the latest GUI toolkit, with a richer set of components than its predecessor. But, there were always problems with these toolkits, be it in performance or required features. There are a few third-party libraries, such as SWT and QtJambi, that tried to steal the show, but could not garner much of developers' interest and have been in use among small groups or communities only. The Eclipse IDE is a classic example of a SWT product and no doubt an excellent one. So, Swing ruled the Java GUI arena for quite a long time. The problem with Swing is that it is poorly designed. It requires heavy tweaking to fit developers' requirement even under some of the simplest circumstances, aside from the fact that it has no support for modern touch devices. A GUI component must perform consistently across multiple devices, apart from just being a good desktop application development environment. Both AWT and Swing clearly lacked this feature. Now, JavaFX has been brought forward (this library was waiting just around the corner, awaiting to get noticed). JavaFX is the new GUI toolkit avatar to reinforce the situation. The good part is that it is rebuilt from scratch (Java FX version 2) and has a focused development with at least a sole GUI perspective. Since Java SE 7 update 6 and Java FX 2.2, it firmly found its place beside the standard JDK distribution and is bundled with the Java SE platform. Presently, the naming scheme conforms to the JDK version, such as Java SE 9 is bundled with JavaFX 9. Does this mean JavaFX waved goodbye to Swing? No, because there are large application bases standing tall on this framework. But, the truth is that JavaFX is stomping in the arena whereas Swing, as a veteran, will continue to exist as a legacy although with almost no active development.

The Structure of JavaFX Programming vis-à-vis Swing

Unlike GUI programming with Swing, which many of us are accustomed with, JavaFX begins with a different organizational structure and program flow. In Swing, typically, a class that holds all the user components is called a frame, typically represented by the javax.swing.JFrame class. It is an extension of the AWT java.awt.Frame class with additional support for JFC/Swing component architecture. However, it is not completely compatible with the Frame class and should not be used interchangeably. JFrame contains JRootPane as its single child. It is the content pane provided by JRootPane which holds all non-menu components in a JFrame and works behind the scenes. This is the primary difference between AWT Frame and Swing JFrame. Now, from the programmers' point of view, JFrame is like an empty dashboard where we add one or more JPanels. The JPanels are like the designated area where we arrange the components according to the layout definition associated with the JPanel. There are a number of layout classes, such as FlowLayout, BorderLayout, GridLayout, and so forth, defined in the java.awt package. Any experienced Java programmer would tell you that the layout classes are primitive and quite a pain to work with in raw code. The GUI program is run from the usual Java main class by constructing a JFrame instance.

A Quick Example in Swing

package sample;
import javax.swing.*;
import java.awt.*;
public class SwingFrame extends JFrame {
   private Container container;
   public SwingFrame() throws Exception {
      super("Swing Demo");
      setSize(400, 600);
      container = getContentPane();
      container.setLayout(new BorderLayout(10, 10));
      setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      container.add(loginPanel(), BorderLayout.CENTER);
      setVisible(true);
      pack();
   }
   private JPanel loginPanel() throws Exception {
      JLabel l1 = new JLabel("User Name");
      JLabel l2 = new JLabel("Password");
      JTextField t1 = new JTextField();
      JPasswordField t2 = new JPasswordField();
      JButton b1 = new JButton("Login");
      JPanel panel = new JPanel(new GridLayout(3, 1, 5, 5));
      panel.add(l1);
      panel.add(t1);
      panel.add(l2);
      panel.add(t2);
      panel.add(new JLabel(""));
      panel.add(b1);
      return panel;
   }

   public static void main(String[] args) throws Exception {
      new SwingFrame();
   }
}

A login box created with the preceding Swing code
Figure 1: A login box created with the preceding Swing code

A Quick Example in JavaFX

package sample;
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.stage.Stage;
public class Main extends Application {
   @Override
   public void start(Stage primaryStage)
         throws Exception {
      primaryStage.setTitle("Login Window");
      StackPane root = new StackPane();
      root.getChildren().add(createLoginPane());
      Scene scene = new Scene(root, 400, 200);
      primaryStage.setScene(scene);
      primaryStage.show();
   }
   private Pane createLoginPane() {
      GridPane grid = new GridPane();
      grid.setPadding(new Insets(5, 5, 5, 5));
      grid.setHgap(5);
      grid.setVgap(5);
      grid.add(new Label("User Name"), 0, 0);
      grid.add(new TextField(), 1, 0);
      grid.add(new Label("Password"), 0, 1);
      grid.add(new PasswordField(), 1, 1);
      grid.add(new Button("Login"), 1, 2);
      return grid;
   }
   public static void main(String[] args) {
      launch(args);
   }
}

A similar login box, created in JavaFX
Figure 2: A similar login box, created in JavaFX

In JavaFX, the top-level container of components is called a stage, synonymous with a real-life platform where all the drama takes place. There is literally a class with the same name, called Stage. On a desktop, it represents the display area or window. The controls and components of the user interface are contained in a scene in the stage. Guess what? There is a class with the same name, Scene. The idea is that an Application is a play consisting of several Scenes but the Stage can only perform one Scene at any given instance of time. The Scene contains a scene graph that elaborates the position of the controls and components, including other things such as controls, layouts, groups, shapes, and so on. These are generically called nodes represented by the abstract class Node. The behavior is something likes the actors in a scene on the stage.

It is interesting that, unlike Swing, where layouts are associated with panels, JavaFX layouts are subclasses of Node like other controls and components. This simple idea leverages a design that can be extended in a less cumbersome manner.

The introduction of properties has made the JavaFX event handling mechanism simpler and consistent across multiple platforms.

The Basic Structure of JavaFX Programming

The package that contains JavaFX elements begins with the javafx prefix. The primary functionalities of JavaFX GUI are defined in four packages: javafx.application, javafx.stage, javafx.scene, and javafx.scene.layout. And, among all the classes in these packages, the most important ones are: Application, Stage, and Scene.

Every JavaFX application is an extension of the Application class. This provides the entry point of execution of the application. A standalone application is run typically by invoking the static method called launch defined by this class. The Application class defines three life-cycle methods: init(), start(), and stop().

The init() method begins initialization soon after the Application class is loaded and constructed. Because this method executes before application executes, we can perform a custom initialization process prior to actually running the application. It, however, should be noted that this method is not invoked by the JavaFX Application Thread. Therefore, we must not try to instantiate a Scene or Stage in this method. We can, however, create them in other JavaFX methods.

The start() method is invoked after init(). This is the place to construct and set the Scene. A Scene is constructed with reference to a Stage object. The runtime system supplies the first stage, called the primary stage. A Stage is the top-level JavaFX container and there can be a number of stages created in an application. A Stage object is constructed and modified on the JavaFX Application Thread. For a quick understanding, the Stage is a typical window decorated by a Scene at a given instance of time.

package sample;
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.text.Font;
import javafx.scene.text.FontWeight;
import javafx.scene.text.Text;
import javafx.stage.Stage;
public class Main extends Application {
   @Override
   public void start(Stage primaryStage)
         throws Exception {
      Text content=new Text(10,20,"Primary Stage:
         Scene 1: Content  ");
      content.setFont(Font.font("",
         FontWeight.BOLD,20));
      Scene scene=new Scene(new Group(content));
      primaryStage.setScene(scene);
      primaryStage.sizeToScene();
      primaryStage.show();
   }

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

The components of the Primary Stage object
Figure 3: The components of the Primary Stage object

The stop() method is called when the application terminates. This method usually is kept empty unless some clean-up operations are to be performed just before close of the application.

About the Content of a Scene

Each element comprising a Scene is typically a node represented by the abstract class called Node. And, the collection of nodes is organised in a tree-like structure called the scene graph. Because it is implemented as tree-like structure, the relationships between nodes are designated as parent-child relationships. A Scene, therefore, always contains a root node from where all other node descends either directly or indirectly. Some of the commonly used subclasses of nodes are Parent, Shape, Canvas, Camera, Control, Group, Region, and the like. For example, the different type of controls such as ButtonBar, SToolBar, SChoiceBox, SAccordion, SSlider, SSpinner, and so forth, are subclasses of the Control node. Similarly, the layouts, StackPane, SHbox, SVbox, SBorderPane, SGridPane, and the like are subclasses of Region. And so on.

Basics of Events Handling

The GUI controls are always associated with some events, such as a button has an associated handler event that defines the function of the button when it is clicked. Similarly, combo boxes, check boxes, lists, all generate some kind of an event when they are used. Although event handling in JavaFX is similar to Swing or AWT, JavaFX's event handling mechanism is much more organised. The basis of a JavaFX event is the Event class. There are several subclasses of Event; one of them is ActionEvent. This event class handles the action of a button. Here is a simple program to demonstrate button event handling in JavaFX.

package sample;
import javafx.application.Application;
import javafx.event.*;
import javafx.geometry.*;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.scene.text.Font;
import javafx.scene.text.FontWeight;
import javafx.scene.text.Text;
import javafx.stage.Stage;
public class Main extends Application {
   private static int count=0;
   @Override
   public void start(Stage primaryStage)
         throws Exception {

      Text txt=new Text(10,20,"");
      txt.setFont(Font.font("",
         FontWeight.BOLD,20));
      FlowPane root=new
         FlowPane(Orientation.VERTICAL);
      root.setHgap(10);
      root.setVgap(10);
      Button button=new Button("Click Me!");
      button.setOnAction(new EventHandler<ActionEvent>() {
         @Override
         public void handle(ActionEvent event) {
            button.setText("You clicked me "
               +(++count)+" time(s)");
            txt.setText("Your Lucky Number is "
               +(int)(Math.random()*100));
         }
      });
      root.getChildren().add(button);
      root.getChildren().add(txt);
      Scene scene=new Scene(root,400,100);
      primaryStage.setScene(scene);
      primaryStage.show();
   }

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

Conclusion

There are many other classes, but these few perhaps are fundamental to set one's foot in the right direction in JavaFX, at least in the beginning. The greatest stumbling block of working with JavaFX for a novice or Swing user is the organizational structure of the JavaFX classes. At a glance, the idea of scene, stage, and so forth does not help much to the accustomed Swing user. This article tried to allay some of the doubts which naturally arise when one looks at JavaFX from a Swing point of view. Lastly, do not forget to consult the JavaFX API documentation for anything and everything in the code that is not understood. The write-up mainly focuses on JavaFX 8 APIs. JavaFX 9 API is more or less same except for the introduction of modules, which we'll see in some other article.






Comment and Contribute

 


(Maximum characters: 1200). You have characters left.

 

 


Enterprise Development Update

Don't miss an article. Subscribe to our newsletter below.

By submitting your information, you agree that developer.com may send you developer offers via email, phone and text message, as well as email offers about other products and services that developer believes may be of interest to you. developer will process your information in accordance with the Quinstreet Privacy Policy.

Sitemap

Thanks for your registration, follow us on our social networks to keep up-to-date