Chapter 15 Event-Driven Programming and Animations
Chapter 15 Event-Driven Programming and Animations
Liang, Introduction to Java Programming, Eleventh Edition, (c) 2017 Pearson Education, Inc. All
rights reserved. 1
Motivations
Suppose you want to write a GUI
program that lets the user enter a
loan amount, annual interest rate,
and number of years and click the
Compute Payment button to obtain
the monthly payment and total
payment. How do you accomplish
the task? You have to use event-
driven programming to write the
code to respond to the button-
clicking event.
Liang, Introduction to Java Programming, Eleventh Edition, (c) 2017 Pearson Education, Inc. All
rights reserved. 2
Objectives
To get a taste of event-driven programming (§15.1).
To describe events, event sources, and event classes (§15.2).
To define handler classes, register handler objects with the source object, and write
the code to handle events (§15.3).
To define handler classes using inner classes (§15.4).
To define handler classes using anonymous inner classes (§15.5).
To simplify event handling using lambda expressions (§15.6).
To develop a GUI application for a loan calculator (§15.7).
To write programs to deal with MouseEvents (§15.8).
To write programs to deal with KeyEvents (§15.9).
To create listeners for processing a value change in an observable object (§15.10).
To use the Animation, PathTransition, FadeTransition, and Timeline classes to
develop animations (§15.11).
To develop an animation for simulating a bouncing ball (§15.12).
Liang, Introduction to Java Programming, Eleventh Edition, (c) 2017 Pearson Education, Inc. All
rights reserved. 3
Introduction
When you run a Java GUI program, the program
interacts with the user and the events drive its
execution. This called event-driven programming.
Example: A message is displayed on the console
when a button is clicked.
Liang, Introduction to Java Programming, Eleventh Edition, (c) 2017 Pearson Education, Inc. All
rights reserved. 4
public class HandleEvent extends Application {
@Override
public void start(Stage primaryStage) {
// Create a pane and set its properties
HBox pane = new HBox(10);
pane.setAlignment(Pos.CENTER);
Button btOK = new Button("OK");
Button btCancel = new Button("Cancel");
pane.getChildren().addAll(btOK, btCancel);
Liang, Introduction to Java Programming, Eleventh Edition, (c) 2017 Pearson Education, Inc. All
rights reserved. 6
Handling GUI Events
To respond to a button click, you need to write the code
to process the button-clicking action.
The button is an event source object.
You need to create an object capable of handling the
action event. This object is called an event handler.
Liang, Introduction to Java Programming, Eleventh Edition, (c) 2017 Pearson Education, Inc. All
rights reserved. 7
Trace Execution
public class HandleEvent extends Application {
public void start(Stage primaryStage) { 1. Start from the
… main method to
OKHandlerClass handler1 = new OKHandlerClass(); create a window and
btOK.setOnAction(handler1); display it
CancelHandlerClass handler2 = new CancelHandlerClass();
btCancel.setOnAction(handler2);
…
primaryStage.show(); // Display the stage
}
}
Liang, Introduction to Java Programming, Eleventh Edition, (c) 2017 Pearson Education, Inc. All
rights reserved. 11
Event Classes
Liang, Introduction to Java Programming, Eleventh Edition, (c) 2017 Pearson Education, Inc. All
rights reserved. 12
Event Information
An event object contains whatever properties are
pertinent to the event.
You can identify the source object of the event using the
getSource() instance method in the EventObject class.
The subclasses of EventObject deal with special types
of events, such as button actions, window events,
mouse movements, and keystrokes.
Table in the next slide lists external user actions, source
objects, and event types generated.
Liang, Introduction to Java Programming, Eleventh Edition, (c) 2017 Pearson Education, Inc. All
rights reserved. 13
Selected User Actions and Handlers
Liang, Introduction to Java Programming, Eleventh Edition, (c) 2017 Pearson Education, Inc. All
rights reserved. 14
Handling Events
Java uses a delegation-based model for event handling: A
source object fires an event, and an object (called event
handler) handles it.
For an object to be an event handler:
– The handler object must be an instance of the corresponding
event-handler interface to ensure the handler has the correct
method for processing the event.
JavaFX defines a unified handler interface EventHandler<T extends
Event>. The interface contains the handle method for processing the
event.
– The handler object must be registered by the source object.
Liang, Introduction to Java Programming, Eleventh Edition, (c) 2017 Pearson Education, Inc. All
rights reserved. 15
The Delegation Model
Liang, Introduction to Java Programming, Eleventh Edition, (c) 2017 Pearson Education, Inc. All
rights reserved. 16
The Delegation Model: Example
// create a source object
Button btOK = new Button("OK");
// create a handler object
OKHandlerClass handler = new OKHandlerClass();
// register handler
btOK.setOnAction(handler);
Liang, Introduction to Java Programming, Eleventh Edition, (c) 2017 Pearson Education, Inc. All
rights reserved. 17
Example: First Version for
ControlCircle (no listeners)
Now let us consider to write a program that
uses two buttons to control the size of a circle.
Liang, Introduction to Java Programming, Eleventh Edition, (c) 2017 Pearson Education, Inc. All
rights reserved. 18
public class ControlCircleWithoutEventHandling extends Application {
@Override // Override the start method in the Application class
public void start(Stage primaryStage) {
Liang, Introduction to Java Programming, Eleventh Edition, (c) 2017 Pearson Education, Inc. All
rights reserved. 19
BorderPane borderPane = new BorderPane();
borderPane.setCenter(pane);
borderPane.setBottom(hBox);
BorderPane.setAlignment(hBox, Pos.CENTER);
} ControlCircleWithoutEventHandling
Liang, Introduction to Java Programming, Eleventh Edition, (c) 2017 Pearson Education, Inc. All
rights reserved. 20
Example: Second Version for
ControlCircle (with listener for Enlarge)
Now let us consider to write a program that
uses two buttons to control the size of a circle.
ControlCircle
Liang, Introduction to Java Programming, Eleventh Edition, (c) 2017 Pearson Education, Inc. All
rights reserved. 21
public class ControlCircle extends Application {
private CirclePane circlePane = new CirclePane();
Liang, Introduction to Java Programming, Eleventh Edition, (c) 2017 Pearson Education, Inc. All
rights reserved. 22
// Create a scene and place it in the stage
Scene scene = new Scene(borderPane, 200, 150);
primaryStage.setTitle("ControlCircle"); // Set the stage title
primaryStage.setScene(scene); // Place the scene in the stage
primaryStage.show(); // Display the stage
}
Liang, Introduction to Java Programming, Eleventh Edition, (c) 2017 Pearson Education, Inc. All
rights reserved. 23
class CirclePane extends StackPane {
private Circle circle = new Circle(50);
public CirclePane() {
getChildren().add(circle);
circle.setStroke(Color.BLACK);
circle.setFill(Color.WHITE);
}
Liang, Introduction to Java Programming, Eleventh Edition, (c) 2017 Pearson Education, Inc. All
rights reserved. 24
Inner Class Listeners
A listener class is designed specifically to
create a listener object for a GUI component
(e.g., a button).
It will not be shared by other applications. So,
it is appropriate to define the listener class as
an inner class.
Liang, Introduction to Java Programming, Eleventh Edition, (c) 2017 Pearson Education, Inc. All
rights reserved. 25
Inner Classes
An inner class, or a nested class is a class defined
within the scope of another class.
Advantages: In some applications, you can use an
inner class to make programs simple.
An inner class can reference the data and methods
defined in the outer class in which it nests, so you do
not need to pass the reference of the outer class to
the constructor of the inner class.
Liang, Introduction to Java Programming, Eleventh Edition, (c) 2017 Pearson Education, Inc. All
rights reserved. 26
Inner Classes
Liang, Introduction to Java Programming, Eleventh Edition, (c) 2017 Pearson Education, Inc. All
rights reserved. 27
Inner Classes
An inner class is compiled into a class named
OuterClassName$InnerClassName.class.
For example, the inner class B in the outer class
A is compiled into A$B.class.
Liang, Introduction to Java Programming, Eleventh Edition, (c) 2017 Pearson Education, Inc. All
rights reserved. 28
Inner Classes
An inner class can be declared public, protected,
or private subject to the same visibility rules
applied to a member of the class.
An inner class can be declared static. A static
inner class can be accessed using the outer class
name. A static inner class cannot access
nonstatic members of the outer class.
Liang, Introduction to Java Programming, Eleventh Edition, (c) 2017 Pearson Education, Inc. All
rights reserved. 29
Inner Classes
Objects of an inner class are often created in the
outer class. You can also create an object of an
inner class from another class.
If the inner class is nonstatic, you must first create
an instance of the outer class.
OuterClass.Innerclass innerObject = outerObject.new InnerClass()
If the inner class is static, use
OuterClass.Innerclass innerObject = new OuterClass.InnerClass()
Liang, Introduction to Java Programming, Eleventh Edition, (c) 2017 Pearson Education, Inc. All
rights reserved. 30
Anonymous Inner Classes
An anonymous inner class is an inner class without
a name.
An anonymous inner class must always extend a
superclass or implement an interface, but it cannot
have an explicit extends or implements clause.
An anonymous inner class must implement all the
abstract methods in the superclass or in the
interface.
Liang, Introduction to Java Programming, Eleventh Edition, (c) 2017 Pearson Education, Inc. All
rights reserved. 31
Anonymous Inner Classes
An anonymous inner class always uses the no-arg
constructor from its superclass to create an instance.
If an anonymous inner class implements an
interface, the constructor is Object().
An anonymous inner class is compiled into a class
named OuterClassName$n.class. For example, if
the outer class Test has two anonymous inner
classes, these two classes are compiled into
Test$1.class and Test$2.class.
Liang, Introduction to Java Programming, Eleventh Edition, (c) 2017 Pearson Education, Inc. All
rights reserved. 32
Anonymous Inner Classes
Inner class listeners can be shortened using
anonymous inner classes.
It combines declaring an inner class and creating an
instance of the class in one step. An anonymous inner
class is declared as follows:
new SuperClassName/InterfaceName() {
// Implement or override methods in superclass or interface
// Other methods if necessary
}
Liang, Introduction to Java Programming, Eleventh Edition, (c) 2017 Pearson Education, Inc. All
rights reserved. 33
Anonymous Inner Classes
Liang, Introduction to Java Programming, Eleventh Edition, (c) 2017 Pearson Education, Inc. All
rights reserved. 34
public void start(Stage primaryStage) {
Text text = new Text(40, 40, "Programming is fun");
Pane pane = new Pane(text);
Liang, Introduction to Java Programming, Eleventh Edition, (c) 2017 Pearson Education, Inc. All
rights reserved. 35
// Create and register the handler
btUp.setOnAction(new EventHandler<ActionEvent>() {
@Override // Override the handle method
public void handle(ActionEvent e) {
text.setY(text.getY() > 10 ? text.getY() - 5 : 10);
}
});
btDown.setOnAction(new EventHandler<ActionEvent>() {
@Override // Override the handle method
public void handle(ActionEvent e) {
text.setY(text.getY() < pane.getHeight() ?
text.getY() + 5 : pane.getHeight());
}
});
Liang, Introduction to Java Programming, Eleventh Edition, (c) 2017 Pearson Education, Inc. All
rights reserved. 36
btLeft.setOnAction(new EventHandler<ActionEvent>() {
@Override // Override the handle method
public void handle(ActionEvent e) {
text.setX(text.getX() > 0 ? text.getX() - 5 : 0);
}
});
btRight.setOnAction(new EventHandler<ActionEvent>() {
@Override // Override the handle method
public void handle(ActionEvent e) {
text.setX(text.getX() < pane.getWidth() - 100?
text.getX() + 5 : pane.getWidth() - 100);
}
});
(a) Anonymous inner class event handler (b) Lambda expression event handler
Liang, Introduction to Java Programming, Eleventh Edition, (c) 2017 Pearson Education, Inc. All
rights reserved. 38
Basic Syntax for a Lambda Expression
The basic syntax for a lambda expression is either
(type1 param1, type2 param2, ...) -> expression
or
(type1 param1, type2 param2, ...) -> { statements; }
Liang, Introduction to Java Programming, Eleventh Edition, (c) 2017 Pearson Education, Inc. All
rights reserved. 39
Single Abstract Method Interface (SAM)
The statements in the lambda expression is all for that
method. If it contains multiple methods, the compiler
will not be able to compile the lambda expression.
So, for the compiler to understand lambda expressions,
the interface must contain exactly one abstract method.
Such an interface is known as a functional interface, or
a Single Abstract Method (SAM) interface.
Liang, Introduction to Java Programming, Eleventh Edition, (c) 2017 Pearson Education, Inc. All
rights reserved. 40
// Create and register the handler The data type for a
btUp.setOnAction((ActionEvent e) -> { parameter may be
text.setY(text.getY() > 10 ? text.getY() - 5 : 10); explicitly declared.
});
The data type for a
btDown.setOnAction((e) -> {
parameter may be
text.setY(text.getY() < pane.getHeight() ?
implicitly inferred.
text.getY() + 5 : pane.getHeight());
});
The parentheses can be
btLeft.setOnAction(e -> { omitted if there is only
text.setX(text.getX() > 0 ? text.getX() - 5 : 0); one parameter without
}); an explicit data type.
LoanCalculator
Liang, Introduction to Java Programming, Eleventh Edition, (c) 2017 Pearson Education, Inc. All
rights reserved. 42
public class LoanCalculator extends Application {
private TextField tfAnnualInterestRate = new TextField();
private TextField tfNumberOfYears = new TextField();
private TextField tfLoanAmount = new TextField();
private TextField tfMonthlyPayment = new TextField();
private TextField tfTotalPayment = new TextField();
private Button btCalculate = new Button("Calculate");
@Override
public void start(Stage primaryStage) {
// Create UI
GridPane gridPane = new GridPane();
gridPane.setHgap(5);
gridPane.setVgap(5);
gridPane.add(new Label("Annual Interest Rate:"), 0, 0);
gridPane.add(tfAnnualInterestRate, 1, 0);
gridPane.add(new Label("Number of Years:"), 0, 1);
gridPane.add(tfNumberOfYears, 1, 1);
gridPane.add(new Label("Loan Amount:"), 0, 2);
gridPane.add(tfLoanAmount, 1, 2);
gridPane.add(new Label("Monthly Payment:"), 0, 3);
Liang, Introduction to Java Programming, Eleventh Edition, (c) 2017 Pearson Education, Inc. All
rights reserved. 43
gridPane.add(tfMonthlyPayment, 1, 3);
gridPane.add(new Label("Total Payment:"), 0, 4);
gridPane.add(tfTotalPayment, 1, 4);
gridPane.add(btCalculate, 1, 5);
Liang, Introduction to Java Programming, Eleventh Edition, (c) 2017 Pearson Education, Inc. All
rights reserved. 44
// Process events
btCalculate.setOnAction(e -> calculateLoanPayment());
Liang, Introduction to Java Programming, Eleventh Edition, (c) 2017 Pearson Education, Inc. All
rights reserved. 45
private void calculateLoanPayment() {
// Get values from text fields
double interest =
Double.parseDouble(tfAnnualInterestRate.getText());
int year =
Integer.parseInt(tfNumberOfYears.getText());
double loanAmount =
Double.parseDouble(tfLoanAmount.getText());
} Liang, Introduction to Java Programming, Eleventh Edition, (c) 2017 Pearson Education, Inc. All
46
rights reserved.
Mouse Events
A mouse event is fired whenever a mouse button
is pressed, released, clicked, moved, or dragged on
a node or a scene.
Each node or scene can fire mouse events.
A mouse event is captured by the MouseEvent
object.
– number of clicks, the location (the x and y coordinates)
of the mouse, or which button was pressed.
Liang, Introduction to Java Programming, Eleventh Edition, (c) 2017 Pearson Education, Inc. All
rights reserved. 47
Mouse Events
The MouseEvent class provides four constants:
PRIMARY, SECONDARY, MIDDLE, and NONE.
– The constants are defined in the MouseButton class.
Use the getButton() method to detect which button
is pressed.
– Example: getButton() == MouseButton.SECONDARY
indicates that the right button was pressed.
Liang, Introduction to Java Programming, Eleventh Edition, (c) 2017 Pearson Education, Inc. All
rights reserved. 48
The MouseEvent Class
Liang, Introduction to Java Programming, Eleventh Edition, (c) 2017 Pearson Education, Inc. All
rights reserved. 49
public void start(Stage primaryStage) {
// Create a pane and set its properties
Pane pane = new Pane();
Text text = new Text(20, 20, "Programming is fun");
pane.getChildren().addAll(text);
text.setOnMouseDragged(e -> {
text.setX(e.getX());
text.setY(e.getY());
});
Liang, Introduction to Java Programming, Eleventh Edition, (c) 2017 Pearson Education, Inc. All
rights reserved. 50
Key Events
A key event is fired whenever a key is
pressed, released, or typed on a node or a
scene.
Key events enable the use of the keys to
control and perform actions or get input
from the keyboard.
Liang, Introduction to Java Programming, Eleventh Edition, (c) 2017 Pearson Education, Inc. All
rights reserved. 51
The KeyEvent Class
Liang, Introduction to Java Programming, Eleventh Edition, (c) 2017 Pearson Education, Inc. All
rights reserved. 52
Handling Keyboard Events
The key pressed handler is invoked when a key is
pressed.
The key released handler is invoked when a key is
released.
The key typed handler is invoked when a Unicode
character is entered. If a key does not have a Unicode (e.g.,
function keys, arrow keys) the key typed handler will not
be invoked.
Liang, Introduction to Java Programming, Eleventh Edition, (c) 2017 Pearson Education, Inc. All
rights reserved. 53
Handling Keyboard Events
Each key event has an associated code that is returned by
the getCode() method in keyEvent.
The key codes are constants defined in KeyCode (an enum
type).
For the key-pressed and key-released events, getCode()
returns the value as defined in the next slide.
Only a focused node can receive KeyEvent. Call the
method requestFocus() to enable the node to receive the
key input. This method must be invoked after the stage is
displayed.
Liang, Introduction to Java Programming, Eleventh Edition, (c) 2017 Pearson Education, Inc. All
rights reserved. 54
The KeyCode Constants
Liang, Introduction to Java Programming, Eleventh Edition, (c) 2017 Pearson Education, Inc. All
rights reserved. 55
public void start(Stage primaryStage) {
// Create a pane and set its properties
Pane pane = new Pane();
Text text = new Text(20, 20, "A");
pane.getChildren().add(text);
text.setOnKeyPressed(e -> {
switch (e.getCode()) {
case DOWN: text.setY(text.getY() + 10); break;
case UP: text.setY(text.getY() - 10); break; KeyEventDemo
case LEFT: text.setX(text.getX() - 10); break;
case RIGHT: text.setX(text.getX() + 10); break;
default:
if (e.getText().length() > 0)
text.setText(e.getText());
}
});
Liang, Introduction to Java Programming, Eleventh Edition, (c) 2017 Pearson Education, Inc. All
rights reserved. 56
// Create a scene and place the pane in the stage
Scene scene = new Scene(pane);
primaryStage.setTitle("KeyEventDemo");
primaryStage.setScene(scene);
primaryStage.show();
Liang, Introduction to Java Programming, Eleventh Edition, (c) 2017 Pearson Education, Inc. All
rights reserved. 57
Example: Control Circle with
Mouse and Key
We can add more control for our
ControlCircle example to increase/decrease
the circle radius by clicking the left/right
mouse button or by pressing the up and
down arrow keys.
Liang, Introduction to Java Programming, Eleventh Edition, (c) 2017 Pearson Education, Inc. All
rights reserved. 58
……
circlePane.setOnMouseClicked(e -> {
if (e.getButton() == MouseButton.PRIMARY) {
circlePane.enlarge();
}
else if (e.getButton() == MouseButton.SECONDARY) {
circlePane.shrink();
}
});
scene.setOnKeyPressed(e -> {
if (e.getCode() == KeyCode.UP) {
circlePane.enlarge();
}
else if (e.getCode() == KeyCode.DOWN) {
circlePane.shrink();
}
ControlCircleWithMouseAndKey
});
Liang, Introduction to Java Programming, Eleventh Edition, (c) 2017 Pearson Education, Inc. All
rights reserved. 59
Listeners for Observable Objects
You can add a listener to process a value change in an
observable object.
An instance of Observable is known as an observable object,
which contains the addListener(InvalidationListener
listener) method for adding a listener.
Once the value is changed in the property, a listener is notified.
The listener class should implement the InvalidationListener
interface, which uses the invalidated(Observable o) method
to handle the property value change.
Every binding property is an instance of Observable.
Liang, Introduction to Java Programming, Eleventh Edition, (c) 2017 Pearson Education, Inc. All
rights reserved. 60
public class MyJavaFX {
public static void main(String[] args) {
DoubleProperty balance = new SimpleDoubleProperty();
balance.addListener(new InvalidationListener() {
public void invalidated(Observable ov) {
System.out.println("The new value is " +
balance.doubleValue());
}
});
Can be simplified using a lambda expression:
balance.set(4.5);
balance.addListener(ov ->
}
System.out.println("The new value is " +
}
balance.doubleValue())
);
ObservablePropertyDem
o
Liang, Introduction to Java Programming, Eleventh Edition, (c) 2017 Pearson Education, Inc. All
rights reserved. 61
ResizableCircleRectangle
Example: displays a circle with its
bounding rectangle. The circle and
rectangle are automatically resized when
the user resizes the window.
Liang, Introduction to Java Programming, Eleventh Edition, (c) 2017 Pearson Education, Inc. All
rights reserved. 62
public class MyJavaFX extends Application {
// Create a circle and a rectangle
private Circle circle = new Circle(60);
private Rectangle rectangle = new Rectangle(120, 120);
Liang, Introduction to Java Programming, Eleventh Edition, (c) 2017 Pearson Education, Inc. All
rights reserved. 63
// Create a scene and place the pane in the stage
Scene scene = new Scene(pane, 140, 140);
primaryStage.setTitle("ResizableCircleRectangle");
primaryStage.setScene(scene);
primaryStage.show();
Liang, Introduction to Java Programming, Eleventh Edition, (c) 2017 Pearson Education, Inc. All
rights reserved. 64
Animation
JavaFX provides the abstract Animation class with the
core functionality for all animations.
Liang, Introduction to Java Programming, Eleventh Edition, (c) 2017 Pearson Education, Inc. All
rights reserved. 65
PathTransition
The PathTransition class animates the
moves of a node along a path from one end
to the other over a given time.
PathTransition is a subtype of Animation.
Liang, Introduction to Java Programming, Eleventh Edition, (c) 2017 Pearson Education, Inc. All
rights reserved. 66
PathTransition
Liang, Introduction to Java Programming, Eleventh Edition, (c) 2017 Pearson Education, Inc. All
rights reserved. 67
public void start(Stage primaryStage) {
// Create a pane
Pane pane = new Pane();
}
FlagRisingAnimation
Liang, Introduction to Java Programming, Eleventh Edition, (c) 2017 Pearson Education, Inc. All
rights reserved. 68
FadeTransition
The FadeTransition class animates the change of the
opacity in a node over a given time.
Liang, Introduction to Java Programming, Eleventh Edition, (c) 2017 Pearson Education, Inc. All
rights reserved. 69
class FadeTransitionDemo extends Application {
@Override // Override the start method in the Application class
public void start(Stage primaryStage) {
// Place an ellipse to the pane
Pane pane = new Pane();
Ellipse ellipse = new Ellipse(10, 10, 100, 50);
ellipse.setFill(Color.RED);
ellipse.setStroke(Color.BLACK);
ellipse.centerXProperty().bind(pane.widthProperty().divide(2));
ellipse.centerYProperty().bind(pane.heightProperty().divide(2));
ellipse.radiusXProperty().bind(
pane.widthProperty().multiply(0.4));
ellipse.radiusYProperty().bind(
pane.heightProperty().multiply(0.4));
pane.getChildren().add(ellipse);
Liang, Introduction to Java Programming, Eleventh Edition, (c) 2017 Pearson Education, Inc. All
rights reserved. 70
// Apply a fade transition to ellipse
FadeTransition ft =
new FadeTransition(Duration.millis(3000), ellipse);
ft.setFromValue(1.0);
ft.setToValue(0.1);
ft.setCycleCount(Timeline.INDEFINITE);
ft.setAutoReverse(true);
ft.play(); // Start animation
// Control animation
ellipse.setOnMousePressed(e -> ft.pause());
ellipse.setOnMouseReleased(e -> ft.play());
Liang, Introduction to Java Programming, Eleventh Edition, (c) 2017 Pearson Education, Inc. All
rights reserved. 71
Timeline
PathTransition and FadeTransition define
specialized animations.
The Timeline class can be used to program any
animation using one or more KeyFrames.
Each KeyFrame is executed sequentially at a
specified time interval. Timeline inherits from
Animation.
Liang, Introduction to Java Programming, Eleventh Edition, (c) 2017 Pearson Education, Inc. All
rights reserved. 72
public void start(Stage primaryStage) {
StackPane pane = new StackPane();
Text text = new Text(20, 50, "Programming if fun");
text.setFill(Color.RED);
pane.getChildren().add(text); // Place text into the stack pane
Liang, Introduction to Java Programming, Eleventh Edition, (c) 2017 Pearson Education, Inc. All
rights reserved. 73
// Pause and resume animation
text.setOnMouseClicked(e -> {
if (animation.getStatus() == Animation.Status.PAUSED) {
animation.play();
}
else {
animation.pause();
}
});
Liang, Introduction to Java Programming, Eleventh Edition, (c) 2017 Pearson Education, Inc. All
rights reserved. 74
Case Study: Bouncing Ball
BallPane BounceBallControl
Liang, Introduction to Java Programming, Eleventh Edition, (c) 2017 Pearson Education, Inc. All
rights reserved. 75
public class BallPane extends Pane {
public final double radius = 20;
private double x = radius, y = radius;
private double dx = 1, dy = 1;
private Circle circle = new Circle(x, y, radius);
private Timeline animation;
public BallPane() {
circle.setFill(Color.GREEN); // Set ball color
getChildren().add(circle); // Place a ball into this pane
Liang, Introduction to Java Programming, Eleventh Edition, (c) 2017 Pearson Education, Inc. All
rights reserved. 77
protected void moveBall() {
// Check boundaries
if (x < radius || x > getWidth() - radius) {
dx *= -1; // Change ball move direction
}
if (y < radius || y > getHeight() - radius) {
dy *= -1; // Change ball move direction
}
Liang, Introduction to Java Programming, Eleventh Edition, (c) 2017 Pearson Education, Inc. All
rights reserved. 78
public class BounceBallControl extends Application {
@Override // Override the start method in the Application class
public void start(Stage primaryStage) {
BallPane ballPane = new BallPane(); // Create a ball pane
Liang, Introduction to Java Programming, Eleventh Edition, (c) 2017 Pearson Education, Inc. All
rights reserved. 79
// Create a scene and place it in the stage
Scene scene = new Scene(ballPane, 250, 150);
primaryStage.setTitle("BounceBallControl");
primaryStage.setScene(scene);
primaryStage.show();
Liang, Introduction to Java Programming, Eleventh Edition, (c) 2017 Pearson Education, Inc. All
rights reserved. 80