Today, many graphical user interfaces (GUIs) live in a browser or a mobile device.

However,

Early Java motivation

 •  Serve up "fat clients" over the nascent Web

AWT (Abstract Window Toolkit)

 •  Use native components from various operating systems, but subtle differences caused major problems

Swing

 •  Don't use native components; paint its own. Initially, it was slow.

Flash

 •  Increasingly used for fancy effects

JavaFX 1.0

 •  Competitor to Flash; ran on the JVM but required a new scripting language

JavaFX 2.0

 •  Has a Java API and no need for a separate language

Java 8

 •  Distributed with JavaFX

Java 9+

 •  Distributed without JavaFX, which must be added
A JavaFX program's life-cycle is determined by an Application, which contains a Stage on which various Scenes play out.
The Application class (in package javafx.application) is the entry point for JavaFX applications.

It is abstract and must be extended by the programmer:

The static Application.launch method initiates the following life cycle:
  1. An instance of the extended Application class is constructed
  2. init is called
  3. start is called on a newly constructed Stage object (discussed later)
  4. When the application is finished, stop is called
Here is the skeletal form of a JavaFX application:

The Stage class (in package javafx.stage) is the top-level JavaFX container.

The primary Stage object is constructed by the JVM for passing to the application's start method.

The Stage is given a title and a scene, and then it can be shown:

The Scene class (in package javafx.scene) is the container for GUI content.

All content is represented as a hierarchical scene graph (or tree) of nodes.

Each node is either a:

The Scene constructor is given the scene graph's root node.

Below is a complete example. It creates a simple one-node graph whose root is a Label.

Label is an example of a user interface control, discussed next.

When this class is run, it produces:

Another example is the DummyConsole class, which is a model for all of the problem solving domains.

A JavaFX Label is an example of a Control:

Like other GUI component frameworks, JavaFX uses the MVC (model-view-controller) architecture:
This section shows a few examples of how JavaFX controls can look.

Later we give examples of how to implement them.

Graphical user interface events include button clicks, slider movements, etc.

Responses to events are given by instances of the following interfaces, for example:

Note: There is also a ChangeListener interface for "observable values" of controls, but:
EventHandler is a functional interface with method handle.

handle accepts an event object and responds to button clicks.

EventHandlers are given to buttons through the Button class's setOnAction method.

For many JavaFX controls, events are triggered when a property of the control changes. (The next section discusses properties in more detail.)

For example, for a slider:

The Button class has a setOnAction method that takes an object implementing the EventHandler functional interface.

That object must have a handle method that accepts an event object and responds to button clicks.

Suppose we have a Button object called button and a Label object called message whose text color is initially black:

When button is clicked, we want message to become red:

We describe three ways of adding a handler to the button.

A straightforward approach is to explicitly write a class that implements EventHandler, create an object of that class, and pass it to the setOnAction method:

This approach often results in writing classes that are instantiated only once.

If a class is used only once, it can be defined using the anonymous classing syntax:

This approach still requires that the class be defined to explicitly override the handle method.

Recall that a lambda expression can be used whenever an object of a class implementing a functional interface (interface of one abstract method) is expected.

Since EventHandler is a functional interface, we can specify the action of a handler in a lambda expression simply by specifying the parameter of the handle method (event in this case) and the code that would have made up the method's body in a class definition:

The code below makes use of a VBox (vertical box, discussed later) to layout a button and label.

Before clicking the button:

After:

Suppose we have a Slider object called slider and a Label object called message whose text is initially large:

After moving the slider:

We describe three ways of adding an InvalidationListener to a slider.

A straightforward approach is to explicitly write a class that implements InvalidationListener, create an object of that class, and pass it to the addListener method:

This approach often results in writing classes that are instantiated only once.

If a class is used only once, it can be defined using the anonymous classing syntax:

This approach still requires that the class be defined to explicitly override the invalidated method.

Recall that a lambda expression can be used whenever an object of a class implementing a functional interface (interface of one abstract method) is expected.

Since InvalidationListener is a functional interface, we can specify the action of a listener in a lambda expression simply by specifying the parameter of the invalidated method (observable in this case) and the code that would have made up the method's body in a class definition:

Before moving the slider:

After:

A property is an attribute of a class that you can read or write.

In a plain, old-fashioned Java object (POJO), a property is inferred from a getter/setter pair. In the following we see the definition of a read/write property called "text" and a typical usage:

When running this class, we get:

    Hello There
    New Greeting
	
In order to add listeners to properties, JavaFX adds a third concept to the getter and setter: a property object.

For example, the StringProperty class:

In the example below, a SimpleStringProperty is created.

Property objects have get and set methods that work like their POJO counterparts.

However, they also have an addListener method to add code that is called when a property changes, as shown below in the main method.

Note the similarity to the way a listener was added to the slider's value property.

When running this class, we get:

    Greeting set to Hello There
    Greeting set to New Greeting
	
One of the most important features of JavaFX is the ability to automatically update one property when another one changes.

All properties have a bind method for this purpose. The simplest form is:

Here property1 gets property2's value whenever property2 changes.

If you also want property2 to depend on property1 in the same way:

Often property1's value needs to be computed from property2 when property2 changes:

How this is done is explained below.

In this example, a second string property another is bound to text.

As a result, when text's value changes, another's does as well.

When running this class, we get:

    before
    after
	
In this example, when the user edits the top text area, the bottom one is updated as well.

Code Result
The code below places a red circle inside a Pane container. Note:

Code Result
As shown below, if the pane is resized, the circle maintains its position:

Desired: reposition the circle to the middle of the pane as the scene containing the pane is resized:

A Circle has properties centerX and centerY for the coordinates of its center in pixels.

A Scene has properties width and height in pixels.

As a scene is resized, its width and height can be used to re-center the circle:

Unfortunately, the following will not work:

because the argument for bind must be a property.

The Bindings class has many static methods for the purpose of creating properties that are computed from others.

For our problem we would use the Bindings.divide method.

Code Result After Resizing
JavaFX supports these approaches to layout management: We will discuss the last three approaches.
Programmatic layout in JavaFX uses panes, or containers with fixed layout policy.

The JavaFX layout package is javafx.scene.layout.

The Pane class is the base class for layout management:

We have seen one, VBox, that lays out its children in a single vertical column.
This section presents layout code examples with snapshots of the scenes they produce.
The BorderPane class arranges children around the border or center of the pane:

Code Result
The BorderPane class has a static setAlignment method for horizontally aligning children:
Code Result
JavaFX incorporates the Composite design pattern that allows containers to both aggregate components and be contained in other containers.

Thus, many layouts can be achieved through combinations of VBox (vertical box) and HBox (horizontal box) layouts.

For example, here is the scene graph representing a label placed above three buttons arranged in a row:

Below is code that creates the afore-mentioned scene graph along with its result.

Note that by default no gaps are inserted between components.

Code Result
To produce a more pleasing layout, there should be gaps between the scene's elements, and padding between elements and the edge of the scene.

Below is the same code as before, with code added to produce the gaps and padding. Note:

Gaps and padding are part of a scene's style. Later we show how Cascading Style Sheets (CSS) can be used to style JavaFX scenes without having to write Java code.

Code Result
A JavaFX GridPane is like an HTML table: Below is a scene laid out with GridPane, along with a table showing the elements used and their row/column coordinates.

When you add to a GridPane, you specify a column and row index (in that order).

Scene Elements
The code below produces the afore-mentioned scene. Note:
Seeing borders between nodes in a scene can be helpful when debugging or trying to improve the scene's appearance.

Here are two ways you can display lines (temporarily), followed by an example of their use:

Code Result
This section describes how to use JavaFX to layout a GUI for the Voice Mail System Simulator (VMSS).

We will assume the system's handset is of the standard land-line variety, and not a smart phone with a touch screen.

We define a TelephoneFX class that implements the Telephone interface and extends the JavaFX VBox class:

We can arrange the components of a handset vertically, with the speaker at the top, followed by the key pad in the middle, and the microphone at the bottom.

The first version of the TelephoneFX class implements the Telephone interface and extends the VBox class in the javafx.scene.layout package, but as yet does not add any components.

Here is how the GUI renders, using default dimensions:

The MailSystemTesterFXGUI class launches the application.

Note that a TelephoneFX object is created, in place of a TelephoneNoGUI object. The rest of the launch code is the same.

The MailSystemTesterFXMLGUI class launches the application.

Note that a TelephoneFXML object is created, in place of a TelephoneFX object. With one exception — creating the Scene from TelephoneFXML — the rest of the launch code is the same.

The speaker pane consists of the label "Speaker:" above a non-editable text area used to display a string simulating audio. Here is how the GUI renders:

The keypad buttons are naturally arranged in a GridPane. Here is how the GUI renders:

The microphone pane consists of the label "Microphone:" above an editable text area used to input simulated speech, which is above a horizontal row of buttons for sending the speech and hanging up.

So the microphone pane will be a VBox, but its bottom child will be an HBox.

Here is how the GUI renders.

Here is the scene graph for the completed GUI:

The final version of TelephoneFX is here: TelephoneFX.java.

To run this version in NetBeans, simply add this class to the mailgui package and run the modified version of MailSystemTester.

This section contains the files necessary to create the console-based version of the VMSS.

To run the simulation in NetBeans:

It is possible to create GUI layouts in JavaFX using XML, the Extensible Markup Language, which we briefly describe here.

JavaFX uses an extension of XML called FXML.

For more documentation on XML, see the World Wide Web Consortium's XML Essentials.

An XML document is a hierarchically organized group of elements. An element is specified using the following form:

where the body of the element (the " ... ") can contain text and/or other elements. Example:

Since XML document elements are nested, their relationships can be depicted using a tree, as shown below.

Note the similarity in structure between the tree and a JavaFX scene graph.

XML Document Element Structure
Elements can be given attributes, using the following syntax:

Attributes can be thought of as adding to the element tree as shown below.

XML Document Element Structure
Generally, FXML elements correspond to: Properties with simple values can be indicated using element attributes.
Below is the presentation of our GridPane example from before followed by the FXML code that renders it:

Once you have created an FXML document two things must happen: This is accomplished with an FXMLLoader.

For our example, suppose the document is named "dialog.fxml". Then the following will produce the rendered scene:

The object hierarchy can be used to add listeners to GUI elements, as shown in the Voice Mail System example.

This section describes how to use FXML to layout a GUI for the Voice Mail System Simulator (VMSS).

We define a TelephoneFXML class that implements the Telephone interface and loads XML elements from the file Telephone.fxml:

As with the programmatic layout, we will layout the telephone components in a VBox. Here is how the GUI renders, using default dimensions:

The speaker area is a nested VBox containing a label and a text area. Here is how it renders:

The microphone area is represented by a nested VBox containing a label, a text area, and an HBox containing two related buttons. Although the GUI will now render completely, it will not respond to interactions until we add behavior.

Here is how it renders:

The keypad buttons need to be nested within a GridPane element. Here is how it renders:

FXML elements can give form to a GUI, but not behavior. To add behavior, we must find the JavaFX objects associated with the FXML elements and add listeners or handlers: In the VMSS, the following FXML elements were given id attributes so that their associated JavaFX objects can be looked up: The new versions of Telephone.fxml and TelephoneFXML.java are shown in the menu.

To run the FXML version of the VMSS in NetBeans, simply add these files to the mailgui package and run the modified MailSystemTester.java file.

The current version of Telephone.fxml does not attempt to style the font or color of the GUI components.

Below is a rendering of the GUI with the keypad buttons styled using CSS.

This is accomplished by: We also remove the prefWidth and prefHeight attributes from the keypad buttons in Telephone.fxml and give the buttons their dimensions in TelephoneFXML.java.

To run this in NetBeans, simply add the vmss.css file to the mailgui package and update the other three files.

See the use of getStyleSheets near the end of the start method:

See the use of the styleClass attribute in the keypad Button elements:

See the use of the setPrefSize method in the loop that gives the keypad buttons their listeners:

User interface style is concerned with presentation aspects such as:

Cascading Style Sheets (CSS):

A CSS style sheet (a file, usually with extension ".css") is composed of one or more CSS rules.

A rule tells how to style either an individual JavaFX scene component or a group of them.

A rule has the form:

A selector indicates which scene component, or group of them, is to be styled, and can be:

Within each rule:
In the example below (called scene.css),

The code below produces the previous GridPane example, but most styling has been removed from the Java code. Note the use of:
This section describes how to lay out a GUI for the Voice Mail System Simulator (VMSS) using both programmatic JavaFX and FXML.

Central to the VMSS design is the Telephone interface, shown below.

This interface allows multiple implementations, including:

The console-based implementation defines a TelephoneNoGUI class that implements the Telephone interface and extends the Console class (see menu) introduced in the first lab exercise. Here are the type relationships:

Select a menu item to the left to access Oracle's online documentation for JavaFX.
https://docs.oracle.com/javase/8/javase-clienttechnologies.htm

https://docs.oracle.com/javase/8/javafx/user-interface-tutorial

https://docs.oracle.com/javase/8/javafx/api

https://docs.oracle.com/javafx/2/api/javafx/scene/doc-files/cssref.html

The Blocks Heuristic Analysis Tool (BHAT) uses JavaFX GUI components.

BHAT allows the user to create initial and goal states for the blocks world and experiment with different heuristic functions.

Here is an executable JAR file for BHAT: Heuristic_Analysis_Tool.jar.

Below is a snapshot of BHAT in action. Click Using BHAT in the menu to the left to see the source code.