Unit 8: GUI Programming
Unit Goals
• To distinguish between JavaFX, Swing, and AWT
• To write a simple JavaFX program and understand the
relationship among stages, scenes, and nodes
• To update property values automatically through
property binding
• To create user interfaces using panes, UI controls, and
shapes
• To layout nodes using Pane, StackPane, FlowPane,
GridPane, BorderPane, HBox, and Vbox
• To display text using the Text class and create shapes
using Line, Circle, Rectangle, Ellipse, Arc
2
Motivations
• The design of the application programming interface
(API) for Java GUI programming and event-driven
programming are excellent examples of how the
object-oriented principle is applied.
• In the following topics, you will learn the framework of
Java GUI API and use the GUI components to
develop user-friendly interfaces for applications.
3
JavaFX vs Swing and AWT
• When Java was introduced, the GUI classes were bundled in
a library known as the Abstract Windows Toolkit (AWT). AWT
is fine for developing simple graphical user interfaces (GUI),
but not for developing comprehensive GUI projects. Besides,
AWT is prone to platform-specific bugs because it relies
heavily on the underlying platform.
• With the release of Java 2, the AWT components were
replaced by a more robust, versatile, and flexible library
known as Swing components. Swing components are less
dependent on the target platform and use less of the native
GUI resources.
• With the release of Java 8, Swing is replaced by a completely
new GUI platform known as JavaFX for developing rich
Internet applications. .
4
JavaFX
• JavaFX incorporates modern GUI technologies to enable you
to develop rich Internet applications (RIA).
• A JavaFX application can run seemlessly on a desktop and
from a Web browser. Additionally, JavaFX provides a multi-
touch support for touch-enabled devices (tablets and smart
phones).
• JavaFX has a built-in 2D, 3D, animation support, video and
audio playback, and runs as a stand-alone application or from
a browser.
• JavaFX is the new GUI tool for developing cross-platform-rich
Internet applications on desktop computers, on hand-held
devices, and on the Web.
• https://openjfx.io/openjfx-docs
5
Why Java GUI programming using JavaFX ?
• JavaFX is much simpler to learn and use for new Java
programmers.
• Java Swing will not receive any further enhancement.
• For visual layout, an XML file may also be used (called
FXML)
• Graphic appearance can be set using web-standard CSS
style sheets
6
Visual Layout Tool
• Normally, you will use visual layout tools (e.g. JavaFX Scene Builder)
using drag-and-drop to design and create Java GUI applications with
minimum coding.
• However, you will still need to have background of the Java API in order
to modify the program.
• Here, we will introduce the JavaFX API and some of the commonly
used UI components.
8
The Basic Structure of a JavaFX Program
• Every JavaFX program is defined in a class that extends
javafx.application.Application,
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.stage.Stage;
public class MyJavaFX extends Application {
@Override // Implement the start method in the Application class
public void start(Stage primaryStage) {
// Create a button and place it in the scene
Button btOK = new Button("OK"); // Create a button
Scene scene = new Scene(btOK, 200, 250); // Create a scene
primaryStage.setTitle("MyJavaFX"); // Set the stage title
primaryStage.setScene(scene); // Place the scene in the stage
primaryStage.show(); // Display the stage
}
Note:
public static void main(String[] args) { To create a JavaFX application,
launch(args); // launch the JavaFX applicationyou need to inherit/instantiate
the Application class and
} implement its abstract method
} start(). 9
The Basic Structure of a JavaFX Program
• The abstract javafx.application.Application class
defines the essential framework for writing JavaFX programs.
• The launch method is a static method defined in the
Application class for launching a stand-alone JavaFX
application.
• After a JavaFX application is launched, the JVM constructs an
instance of the class using its no-arg constructor and invokes
its start method.
• The start method normally places UI controls in a scene and
displays the scene in a stage.
• By default, the user can resize the stage. To prevent the user
from resizing the stage, invoke
stage.setResizable(false).
10
Key Components: Stage, Scene, and Nodes
• A Stage object is a window. It contains all the objects of a JavaFX
application. A Stage object called primary stage is automatically created
by the JVM when the application is launched.
• A Scene represents the physical contents of a JavaFX application. It
contains all the contents of a scene graph.
• A Node is an element in the Scene, with a visual appearance and an
interactive behavior. Nodes may be hierarchically nested. The Node
Class of the package javafx.scene represents a node in JavaFX.
• JavaFX names the Stage and Scene classes using the analogy from
the theater. You may think stage as the platform to support scenes and
Nodes as actors to perform in the scenes.
Stage
Scene
Button
(Node)
11
Multiple Stages
• You can create additional stages if needed.
public class MultipleStageDemo extends Application {
@Override // Override the start method in the Application class
public void start(Stage primaryStage) {
// Create a scene and place a button in the scene
Scene scene = new Scene(new Button("OK"), 200, 250);
primaryStage.setTitle("MyJavaFX"); // Set the stage title
primaryStage.setScene(scene); // Place the scene in the stage
primaryStage.show(); // Display the stage
Stage stage = new Stage(); // Create a new stage or second stage
stage.setTitle("Second Stage"); // Set the stage title
// Set a scene with a button in the stage
stage.setScene(new Scene(new Button("New Stage"), 100, 100));
stage.show(); // Display the stage
}
public static void main(String[] args) {
launch(args);
}
}
12
JavaFX UI Example
• A typical JavaFX window consists of a hierarchy of Nodes including
layout panes (for organizing nodes), UI controls (Button, CheckBox,
RadioButton, TextArea, MenuBar, Slider...), and maybe some shapes
(Line, Circle, Text...)
13
JavaFX Class Hierarchy
Note that this is a simplified version of the JavaFX class hierarchy 14
Nodes: Panes, UI Controls, Shapes and ImageView
• Panes, UI controls, shapes and ImageView are subtypes of Node
– A Pane is a container class for automatically laying out the nodes in
a desired location and size.
– An UI control refers to a label, button, check box, radio button, text
field, text area, combo box, menu, tool bar, etc.
– A Shape refers to a text, line, circle, ellipse, rectangle, arc, polygon,
polyline, etc.
– An ImageView is for displaying an image.
• You can create a Scene using the constructor
Scene(Parent,width,height) or Scene(Parent).
• Note that a Scene can contain a parent node (Control or a Pane), but
not a Shape or an ImageView.
• A Pane can contain any subtype of Node.
• There are other types of Node (e.g. Canvas) but we will focus on Panes
and Controls
15
Example: ButtonInPane.java
• The following program places a button in a StackPane:
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.stage.Stage;
import javafx.scene.layout.StackPane;
public class ButtonInPane extends Application {
@Override // Override the start method in the Application class
public void start(Stage primaryStage) {
// Create a scene and place a button in the scene
StackPane pane = new StackPane(); //Create a Pane
pane.getChildren().add(new Button("OK"));//Add a button
Scene scene = new Scene(pane, 200, 50); //Add Pane to scene
primaryStage.setTitle("Button in a pane"); // Set the stage title
primaryStage.setScene(scene); // Place the scene in the stage
primaryStage.show(); // Display the stage
}
public static void main(String[] args) {
launch(args);
}
} 16
Example: ButtonInPane.java
• The previous program creates a StackPane and adds a button as a
child of the pane.
• The getChildren() method returns a list for holding nodes in the pane.
pane.getChildren().add(node); // add one node to the list
pane.getChildren().addAll(node1, node2, ...); // add multiple nodes
pane.getChildren().remove(node); // remove a node
pane.getChildren().removeAll(); // remove all nodes in the list
Note: one node can only be added to one and only one pane
• The StackPane places the nodes in the center of the pane on top of
each other.
• The StackPane respects a node’s preferred size. You should see the
button displayed in its preferred size.
• More on different types of layout panes later.
17
Example: ShowCircle.java
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;
public class ShowCircle extends Application {
@Override // Override the start method in the Application class
public void start(Stage primaryStage) {
// Create a circle and set its properties
Circle circle = new Circle(100, 100, 50); // (x, y, radius)
circle.setStroke(Color.BLUE); //The color to draw the circle
circle.setFill(Color.WHITE); //The color to fill the circle
Pane pane = new Pane();
pane.getChildren().add(circle);//Add circle to pane
Scene scene = new Scene(pane, 200, 200);//Add pane to scene
primaryStage.setTitle("ShowCircle"); //Set the Stage title
primaryStage.setScene(scene); // Place the scene in the stage
primaryStage.show(); // Display the stage
}
public static void main(String[] args) {
launch(args);
}
} 18
Java Coordinate System
• The Java coordinate system is measured in pixels, with
(0,0) at its upper-left corner.
x
Y Axis
(0, 0) X Axis
y
(x, y)
(0, 0) X Axis
Java Conventional
Coordinate Coordinate
System System
Y Axis
19
Property Binding
• JavaFX introduces a new concept called property binding that enables
a target object to be bound to a source object. If the value in the source
object changes, the target object is also changed automatically.
• The target object is called a binding object or a binding property and the
source object is called a bindable object or observable object. A Bound
property cannot be changed.
• A target binds with a source using the bind method.
target.bind(source);
• In the previous example, the circle is not centered after the window is
resized. In order to display the circle centered as the window resizes,
the x- and y-coordinates of the circle center need to be reset to the
center of the pane. This can be done by binding the centerX with
pane’s width/2 and centerY with pane’s height/2.
JavaFX property binding allows you to synchronize the value of two properties
so that whenever one of the properties changes, the value of the other property
is updated automatically. 20
ShowCircleCentered.java
public class ShowCircleCentered extends Application {
@Override // Override the start method in the Application class
public void start(Stage primaryStage) {
Pane pane = new Pane();
// Create a circle and set its properties
Circle circle = new Circle(100, 100, 50); // (x, y, radius)
circle.centerXProperty().bind(pane.widthProperty().divide(2));
circle.centerYProperty().bind(pane.heightProperty().divide(2));
circle.setStroke(Color.BLUE);
circle.setFill(Color.WHITE);
pane.getChildren().add(circle); // add circle to pane
Scene scene = new Scene(pane, 200, 200);
primaryStage.setTitle("ShowCircleCentered");
primaryStage.setScene(scene); // Place the scene in the stage
primaryStage.show(); // Display the stage
}
public static void main(String[] args) {
launch(args);
}
}
21
Property Binding: getter, setter, and property getter
• JavaFX defines binding properties for primitive types and strings:
– DoubleProperty
– FloatProperty
– LongProperty
– IntegerProperty
– BooleanProperty
– StringProperty
• By convention, each binding property in a JavaFX class has a getter
and setter method for returning and setting the property’s value, and a
property getter method for returning the property itself.
22
Numeric Binding Property Classes
• The numeric binding property classes such as DoubleProperty
and IntegerProperty contain the add, subtract, multiply, and
divide methods for adding, subtracting, multiplying, and dividing
a value in a binding property and returning a new observable
property.
circle.centerXProperty().bind(pane.widthProperty().divide(2));
• A generic property class ObjectProperty<T> is used to define
binding property for reference types.
23
Layout Panes
• JavaFX provides many types of panes for organizing nodes in a
container.
• Each pane contains a list for holding nodes in the pane. A node can be
placed only in one pane.
24
StackPane
• The StackPane places all of the nodes within a single stack with each
new node added on top of the previous node.
• This layout model provides an easy way to overlay text on a shape or
image or to overlap common shapes to create a complex shape.
Circle circle = new Circle(100, 100, 50); // (x, y, radius)
circle.setStroke(Color.BLUE);
circle.setFill(Color.WHITE);
StackPane pane = new StackPane();
pane.getChildren().add(circle);
pane.getChildren().add(new Text("Circle"));
25
FlowPane
• FlowPane arranges the nodes in the pane horizontally from left to right
or vertically from top to bottom in the order in which they were added.
• When one row or one column is filled, a new row or column is started.
• You can also specify the gap between the nodes in pixels.
26
The FlowPane Class
• Data fields alignment, orientation, hgap, and vgap are binding
properties.
Pos.TOP_LEFT)
27
FlowPane
• FlowPane construction:
FlowPane pane = new FlowPane(); // default: no gaps, horizontal orientation
FlowPane pane = new FlowPane(Orientation.VERTICAL, 5, 10);
• FlowPane methods:
pane.setAlignment(Pos.CENTER);
pane.setHgap(5); // in pixels
pane.setVgap(5);
pane.setPadding(new Insets(10, 15, 10, 15)); // (top, right, bottom, left)
flow.setPrefWrapLength(300); // default wrap length=400
28
ShowFlowPane.java
public class ShowFlowPane extends Application {
public void start(Stage primaryStage) {
// Create a pane and set its properties
FlowPane pane = new FlowPane();
pane.setPadding(new Insets(10, 15, 10, 15));
pane.setHgap(5);
pane.setVgap(5);
pane.setPrefWrapLength(300);
// Place nodes in the pane
pane.getChildren().addAll(new Label("First Name:"),
new TextField(), new Label("MI:"));
TextField tfMi = new TextField();
tfMi.setPrefColumnCount(1); // width of 'W', default=12
pane.getChildren().addAll(tfMi, new Label("Last Name:"),
new TextField());
// Create a scene and place it in the stage
Scene scene = new Scene(pane);
primaryStage.setTitle("ShowFlowPane"); // Set the stage title
primaryStage.setScene(scene); // Place the scene in the stage
primaryStage.show(); // Display the stage
} ...
29
GridPane
• A GridPane arranges nodes in a grid (matrix) formation.
• The nodes are placed in the specified (column, row) indices using the
add(Node, columnIndex, rowIndex) method.
• The column and row index starts from 0. Not every cell in the grid needs
to be filled.
30
The GridPane Class
31
ShowGridPane.java
public class ShowGridPane extends Application {
public void start(Stage primaryStage) {
GridPane pane = new GridPane();
pane.setAlignment(Pos.CENTER); // align the grid to center
pane.setPadding(new Insets(15));
pane.setHgap(5);
pane.setVgap(5);
// Place nodes in the pane
pane.add(new Label("First Name:"), 0, 0);
pane.add(new TextField(), 1, 0);
pane.add(new Label("MI:"), 0, 1);
pane.add(new TextField(), 1, 1);
pane.add(new Label("Last Name:"), 0, 2);
pane.add(new TextField(), 1, 2);
Button btAdd = new Button("Add Name");
pane.add(btAdd, 1, 3);
GridPane.setHalignment(btAdd, HPos.RIGHT);
Scene scene = new Scene(pane);
primaryStage.setTitle("ShowGridPane"); // Set the stage title
primaryStage.setScene(scene); // Place the scene in the stage
primaryStage.show(); // Display the stage
} ... 32
GridPane
• To display grid lines (for debugging purpose):
pane.setGridLinesVisible(true);
• To add a node to grid pane at specific column, row and span:
public void add(Node child,
int columnIndex,
int rowIndex,
int colspan,
int rowspan);
e.g.: Button btAdd = new Button(" Add Name ");
pane.add(btAdd, 0, 3, 2, 1);
GridPane.setHalignment(btAdd, HPos.CENTER);
33
BorderPane
• A BorderPane can place nodes in five regions: top, bottom, left, right,
and center, using the setTop(node), setBottom(node), setLeft(node),
setRight(node), and setCenter(node) methods.
• To remove a node from the top region, invoke setTop(null). If a region is
not occupied, no space will be allocated for this region.
34
BorderPane
• A border pane is useful for the classic look of a tool bar at the top, a
status bar at the bottom, a navigation panel on the left, additional
information on the right, and a working area in the center.
• Example:
35
The BorderPane Class
36
HBox and VBox
• A HBox lays out its children in a single horizontal row.
• A VBox lays out its children in a single vertical column.
• Recall that a FlowPane can lay out its children in multiple rows or
multiple columns, but HBox or VBox can lay out children only in one
row or one column.
37
ShowBorderPane.java 1/3
public class ShowBorderPane extends Application {
@Override // Override the start method in the Application class
public void start(Stage primaryStage) {
// Create a border pane
BorderPane pane = new BorderPane();
// Place nodes in the pane
pane.setCenter(getCenter());
pane.setTop(getHBox());
pane.setLeft(getVBox());
// Create a scene and place it in the stage
Scene scene = new Scene(pane, 300, 250);
primaryStage.setTitle("ShowBorderPane"); // Set the stage title
primaryStage.setScene(scene); // Place the scene in the stage
primaryStage.show(); // Display the stage
}
private StackPane getCenter() {
StackPane pane = new StackPane();
pane.getChildren().add(new Text("Work Area"));
pane.setStyle("-fx-border-color: black;");
return pane;
38
}
ShowBorderPane.java 2/3
private VBox getVBox() {
VBox vBox = new VBox(15);
vBox.setPadding(new Insets(15, 5, 5, 5));
vBox.setStyle("-fx-background-color: aqua");
vBox.getChildren().add(new Label("Courses"));
Label[] courses = {new Label("CSCI 1301"), new Label("CSCI 1302"),
new Label("CSCI 2410"), new Label("CSCI 3720")};
for (Label course: courses) {
VBox.setMargin(course, new Insets(0, 0, 0, 15));
vBox.getChildren().add(course);
}
return vBox;
}
39
ShowBorderPane.java 3/3
private HBox getHBox() {
HBox hBox = new HBox(15);
hBox.setAlignment(Pos.CENTER_RIGHT);
hBox.setPadding(new Insets(15));
hBox.setStyle("-fx-background-color: gold");
hBox.getChildren().add(new Button("Computer Science"));
hBox.getChildren().add(new Button("Chemistry"));
return hBox;
}
public static void main(String[] args) {
launch(args);
}
}
40
Setting Node Styles
• Nodes share many common properties and styles.
• JavaFX style properties are similar to cascading style sheets (CSS)
used to specify the styles for HTML elements in a Web page, called
JavaFX CSS.
• Use the node.setStyle("–fx-styleName:value") method to set
the style of a node (with a prefix –fx-).
• Examples:
circle.setStyle("-fx-stroke: black; -fx-fill: red;");
hBox.setStyle("-fx-background-color: gold");
• Each node has its own style properties. You can find these properties
from this link:
http://docs.oracle.com/javafx/2/api/javafx/scene/doc-files/cssref.html
41
Shapes
• JavaFX provides many shape classes for drawing texts, lines, circles,
rectangles, ellipses, arcs, polygons, and polylines.
42
The Shape Abstract Class
• The Shape class is the abstract base class that defines the common
properties for all shapes. Among them are the fill, stroke, and
strokeWidth properties.
• Two ways to set the common properties of shapes,
– JavaFX CSS:
shapeObj.setStyle("-fx-stroke: black; -fx-fill: red;
-fx-stroke-width: 5;");
– Shape methods:
shapeObj.setStroke(Color.BLACK);
shapeObj.setFill(Color.RED);
shapeObj.setStrokeWidth(5);
• Some standard colors:, BLACK, BLUE, BROWN, CYAN,
DARKGRAY, GOLD, GRAY, GREEN, LIGHTGRAY, MAGENTA,
NAVY, ORANGE, PINK, RED, SILVER, WHITE, and YELLOW
43
The Text Class
• The Text class defines a node that displays a string at a starting point
(x, y). For examples:
Text text1 = new Text("Programming is fun");
Text text2 = new Text(60, 60, "Programming is fun\nDisplay
text");
44
The Text Class
• A Text object is usually placed in a pane. The pane’s upper-left corner
point is (0, 0) and the bottom-right point is
(pane.getWidth(), pane.getHeight()).
Pane p = new Pane();
Text text1 = new Text("Programming is fun");
Text text2 = new Text(60, 60, "Programming is fun\nDisplay
text");
p.getChildren().add(text1); // what happen to text1??
p.getChildren().add(text2);
45
ShowText.java
public class ShowText extends Application {
@Override // Override the start method in the Application class
public void start(Stage primaryStage) {
// Create a pane to hold the texts
Pane pane = new Pane();
pane.setPadding(new Insets(5, 5, 5, 5));
Text text1 = new Text("Programming is fun");
text1.setFont(Font.font("Courier", FontWeight.BOLD,
FontPosture.ITALIC, 15));
pane.getChildren().add(text1); // what happen to text1??
Text text2 = new Text(60, 60, "Programming is fun\nDisplay text");
pane.getChildren().add(text2);
text2.setFill(Color.RED);
text2.setUnderline(true);
text2.setStrikethrough(true);
// Create a scene and place it in the stage
Scene scene = new Scene(pane);
primaryStage.setTitle("ShowText"); // Set the stage title
primaryStage.setScene(scene); // Place the scene in the stage
primaryStage.show(); // Display the stage
} ...
46
The Font Class
• Font class is used to create font.
• Font is defined by its name, weight, posture, and size.
– name ("Times", "Courier", "Arial", ...)
– weight (FontWeight.NORMAL, FontWeight.BOLD, ...)
– posture (FontPosture.REGULAR, FontPosture.ITALIC)
– size (default = 12)
• A Font instance can be constructed using its constructors or using its
static methods.
Font font1 = new Font("SansSerif", 16);
Font font2 = Font.font("Times New Roman", FontWeight.BOLD,
FontPosture.ITALIC, 12);
47
The Line Class
• A Line connects two points with four parameters startX, startY, endX,
and endY:
Line line1 = new Line(10, 10, 30, 20);
48
The Rectangle Class
• A Rectangle is defined by the parameters x, y, width, height, arcWidth,
and arcHeight:
Rectangle r2 = new Rectangle(30, 100, 70, 40);
r2.setArcWidth(15);
r2.setArcHeight(25);
r2.setRotate(30);
49
The Circle Class
• We have used circles before. A Circle is defined by its parameters
centerX, centerY, and radius:
Circle circle = new Circle(25, 25, 50);
50
The Ellipse Class
• An Ellipse is defined by its parameters centerX, centerY, radiusX,
and radiusY:
Ellipse e1 = new Ellipse(150, 100, 100, 50);
51
The Arc Class
• An ARC is conceived as part of an ellipse, defined by the parameters
centerX, centerY, radiusX, radiusY, startAngle, length (spanning angle)
52
ShowShapes.java 1/2
public class ShowShapes extends Application {
@Override // Override the start method in the Application class
public void start(Stage primaryStage) {
// Create a pane to hold the texts
Pane pane = new Pane();
pane.setPadding(new Insets(10));
Line line1 = new Line(10, 10, 150, 20);
pane.getChildren().add(line1);
Rectangle r1 = new Rectangle(10, 60, 120, 70);
r1.setStroke(Color.BLUE);
r1.setFill(Color.RED);
pane.getChildren().add(r1);
Rectangle r2 = new Rectangle(30, 100, 70, 40);
r2.setArcWidth(15);
r2.setArcHeight(25);
r2.setRotate(30); // rotate 30 deg
pane.getChildren().add(r2);
53
ShowShapes.java 2/2
Ellipse e1 = new Ellipse(250, 50, 60, 40);
e1.setStroke(Color.BLACK);
e1.setFill(null); // no fill
pane.getChildren().add(e1);
Arc arc1 = new Arc(250, 150, 60, 40, -5, 50);
arc1.setStroke(Color.GREEN);
arc1.setFill(null);
pane.getChildren().add(arc1);
Arc arc2 = new Arc(250, 150, 60, 40, 120, 50);
arc2.setType(ArcType.ROUND);
pane.getChildren().add(arc2);
// Create a scene and place it in the stage
Scene scene = new Scene(pane);
primaryStage.setTitle("ShowText"); // Set the stage title
primaryStage.setScene(scene); // Place the scene in the stage
primaryStage.show(); // show stage
}
...
54
Respond to User-generated Events
• So far we have introduced how to create and layout GUI
components (nodes) in a window (stage).
• To be useful, the GUI components must be able to
respond to user input (e.g. press a button, click the
mouse).
• In other words, your application must be able to handle
user-initiated events.
• This is the topic in the next unit – Event-driven
programming.
55