0% found this document useful (0 votes)
201 views93 pages

Java FX

This document discusses JavaFX and introduces its basic structure and components. It begins by explaining that JavaFX is the new GUI framework that replaced Swing, and that JavaFX programs extend the Application class. It then shows a simple example JavaFX program with a button on a stage/window. Finally, it discusses panes, UI controls, and shapes that make up JavaFX scenes and components like buttons can be placed inside panes for layout.

Uploaded by

Mark Twain
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
201 views93 pages

Java FX

This document discusses JavaFX and introduces its basic structure and components. It begins by explaining that JavaFX is the new GUI framework that replaced Swing, and that JavaFX programs extend the Application class. It then shows a simple example JavaFX program with a button on a stage/window. Finally, it discusses panes, UI controls, and shapes that make up JavaFX scenes and components like buttons can be placed inside panes for layout.

Uploaded by

Mark Twain
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
You are on page 1/ 93

Section 14.

Introduction
§14.1 Introduction
 Graphical User Interface (GUI) applications, as
opposed to console UI applications, rely heavily
on objects
 JavaFX is a framework and (large) set of objects
we can use to develop GUI-based applications
 The JavaFX API is a good example of how
object-oriented principles can be applied in
software development
§14.1 Introduction
 This chapter introduces us to creating the UI, but
it will be very simple, and it
won’t actually do anything
(like the façade of a building
in a movie set; it doesn’t
have anything “behind it”)
 Chapter 15 (Event-Driven Programming) shows
us how to get that interface to do things (how to
link executable code to the UI elements)
 Chapter 16 shows us more elements we can use
to add different kinds of functionality to the UI
Section 14.2

JavaFX vs Swing vs
AWT
§14.2: JavaFX vs Swing vs AWT
 Java was first released with GUI support in
something called the Abstract Windows Toolkit
(AWT)
 AWT wasn’t bad, but it had some limitations, and
some particular problems with how it was
implemented on some platforms
 Ultimately, AWT (which still exists, but isn’t used
much anymore) was replaced by a new library
called Swing, which was more versatile, more
robust, and more flexible.
§14.2: JavaFX vs Swing vs AWT
 Swing was designed primarily for use in desktop
applications (although you could do some web-
based things with it, too).
 Swing has now been replaced by a completely
new GUI library called JavaFX
 You can still use Swing (for the foreseeable
future), but Oracle isn’t going to develop it any
further – it’s essentially a dead-end technology
 Java has replaced Swing with JavaFX
 How long until JavaFX is replaced by something
else? Nobody knows; probably many years
§14.2: JavaFX vs Swing vs AWT
 JavaFX lets us write RIAs (Rich Internet
Applications), which essentially run under a
browser (IE / FireFox / Chrome / Safari) just like
they run on a desktop
 Previously, the cross-platform (desktop vs
browser) experience was delivered by Java
Applets, but applets are pretty much dead, too.
 If you need to learn Swing, see Liang’s 9e, and I
will provide lecture slides; otherwise, just learn
JavaFX, and don’t look back.
Section 14.3

The Basic
Structure of a
JavaFX Program
§14.3: JavaFX Programs: Basic
Structure
 In Chapter 13, we said that abstract classes
were used to create a starting point for
inheritance, but that the abstract class is never
intended to be instantiated itself – it’s too
incomplete.
 JavaFX programs all start not as some “regular”
class like we’ve been doing, but as an extension
of the abstract Application class in JavaFX,
javafx.application.Application

(next slide)
§14.3: JavaFX Programs: Basic
Structure
public class MyProgram
{
// Body of class
}

Becomes:

import javafx.application.Application;

public class MyProgram extends Application
{
// Body of class
}
§14.3: Running JavaFX Apps in
Eclipse
 There is a problem with the default installation of
Eclipse and getting JavaFX to run. Here’s the
fix:
 When you create a JavaFX project, right-click on
the project (under the Package Explorer in
Eclipse), and select “Properties”
 In the window that
appears, click on
“Java Build Path”
on the left side, then
“Add External JARs”
on the right
§14.3: Running JavaFX Apps in
Eclipse
 Navigate to:
C:\Program Files (x86)\Java\jre1.8.0_40\lib\ext\
 Double-click on jfxrt.jar, which should now
appear at the top of your build path
 Click on the “Order and Export” tab
§14.3: Running JavaFX Apps in
Eclipse
 Click on jfxrt.jar to highlight it
 Then click the button labeled “Top” to move it to
the top of the list
 Click “OK”
§14.3: Our First JavaFX Program
 Our first JavaFX program will open a window, whose
title bar will display “MyJavaFX”, and which will have
a (huge) button in the middle labeled “OK”
 First, the result, and then the code:
§14.3: Our First JavaFX Program
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.stage.Stage;

public class MyJavaFX extends Application


{
@Override // Override the start method in the Application class
public void start(Stage primaryStage)
{
// Create a scene and place a button in theEclipse
scene DOES have enough JavaFX
Button btOK = new Button("OK"); //support
create for us to not need main().
a button
Scene scene = new Scene(btOK, 200, 250); //You can acompletely
create scene WITHcomment-out
the button (or
primaryStage.setTitle("MyJavaFX"); //delete)
Set the stage title
main(), and this code runs
primaryStage.setScene(scene); // Place the scene in the stage
primaryStage.show(); // Displayexactly the same under Eclipse
the stage
}

/**
* The main method is only needed for the IDE with limited
* JavaFX support. Not needed for running from the command line.
*/
public static void main(String[] args)
{
Application.launch(args);
}
}
§14.3: Our First JavaFX Program
 JavaFX programs are based on the analogy of a
stage (think “theater stage” for the moment).
 On the stage are scenes, and each scene is also
made up of other components.
 On a theater stage, the stage may be divided into
portions, where individual scenes take place.
 Each scene’s set will have actors, props, backdrops,
lighting, etc.
 In JavaFX, we create the components, add them to
scenes, and then add scenes to the stage
§14.3: Our First JavaFX Program
 In JavaFX, the stage is the window our code runs in
 Since every GUI application, by definition, involves a
window with the UI, we get the primaryStage by
default when the application launches.
 Our applications are not limited to a single stage
 Just as a music festival may have simultaneous
performances on multiple stages, we can have more
than one stage (window) in our programs.
 The code to set
up this two-
stage UI is on
the next slide
§14.3: Our First JavaFX Program
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.stage.Stage;
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); // Put the scene in the stage
primaryStage.show(); // Display the stage

Stage stage = new Stage(); // Create a new 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
}
}
§14.3: Our First JavaFX Program
 By default, stages (windows) are resizeable.
 Note that we have minimize and maximize buttons
 If we want our stage to be of
fixed size (i.e., not resizeable),
we can set that property with
stage.setResizeable(false)
Section 14.4

Panes, UI Controls,
and Shapes
§14.4: Panes, UI Controls, and
Shapes
 In Listing 14.1, we put the button directly on the
scene, which centered the button and made it
occupy the entire window.
 Rarely is this what we really want to do
 One approach is to specify the size and location
of each UI element (like the buttons)
 A better solution is to
put the UI elements
(known as nodes)
into containers called
panes, and then add
the panes to the scene.
§14.4: Panes, UI Controls, and
Shapes
 Panes can even contain other panes:
§14.4: Panes, UI Controls, and
Shapes
 The following slide shows the
code to create this version of
the same UI, with a single
button inside a pane (so that
the button doesn’t occupy the whole stage).
 It uses a StackPane (which we’ll discuss later).
 In order to add something to a pane, we need to
access the list of things IN the pane, much like an
ArrayList.
 The new item we’ll add will be a new child of the
pane, so we’re adding it to the list of the pane’s
children
§14.4: Panes, UI Controls, and
import
Shapes
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)
{
StackPane pane = new StackPane(); // Make a pane to work with

// create a new button, and add it to the pane’s list of children


pane.getChildren().add(new Button("OK"));

// Make a new scene, containing the pane


Scene scene = new Scene(pane, 200, 50);
primaryStage.setTitle("Button in a pane"); // Set the stage title
primaryStage.setScene(scene); // Put scene in the stage
primaryStage.show(); // Display the stage
}
}
§14.4: Panes, UI Controls, and
Shapes
 Beyond the obvious, typical “active” UI elements
(things we can interact with, like buttons, etc.), are
static shapes – lines, circles, etc.
 Before we can do much with shapes, we have to talk
about coordinates within a pane.
 The top-left corner of a scene is always (0, 0), and
the (positive) X-axis goes
to the right, and the (positive) Y-axis goes
down. Visually, we’re in
Cartesian quadrant IV,
but Y stays positive.
 All coordinates are in pixels
§14.4: Panes, UI Controls, and
import
Shapes
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();
circle.setCenterX(100);
circle.setCenterY(100);
circle.setRadius(50);
circle.setStroke(Color.BLACK);
circle.setFill(Color.WHITE);

// Create a pane to hold the circle


Pane pane = new Pane();
pane.getChildren().add(circle);

// Create a 200-x-200 scene from the pane, and place the scene in the stage
Scene scene = new Scene(pane, 200, 200);
primaryStage.setTitle("ShowCircle"); // Set the stage title
primaryStage.setScene(scene); // Place the scene in the stage
primaryStage.show(); // Display the stage
}
}
Section 14.5

Property Binding
§14.5 Property Binding
 In the previous example, the (x, y) location of the
center of the circle was static – it will always be
located at (100, 100).
 What if we want it to be centered in the pane,
such that if we re-size the window, the circle will
move to stay centered?
 In order to do so, the circle’s center has to be
bound to the pane’s height and width, such that a
change to the height or width will force a change
to the x or y value of the circle’s center.
 This is what property binding is all about
§14.5 Property Binding
 Like most things Java-esque, we get more new
terminology
 The target object (called the binding object) gets
bound to the source object (the bindable object)
 When there’s a change to the source, it gets
automatically sent to the target.
 The following listing (14.5) shows how to bind the
circle’s X and Y center values to the pane’s width
(for clarity, the import statements at the top
have been omitted)
§14.5 Property Binding
public class ShowCircleCentered extends Application
{
@Override // Override the start method in the Application class
public void start(Stage primaryStage)
{
// Create a pane to hold the circle
Pane pane = new Pane();

// Create a circle and set its properties


Circle circle = new Circle();
circle.centerXProperty().bind(pane.widthProperty().divide(2));
circle.centerYProperty().bind(pane.heightProperty().divide(2));
circle.setRadius(50);
circle.setStroke(Color.BLACK);
circle.setFill(Color.WHITE);
pane.getChildren().add(circle); // Add circle to the pane

// Create a scene and place it in the stage


Scene scene = new Scene(pane, 200, 200);
primaryStage.setTitle("ShowCircleCentered"); // Set the stage title
primaryStage.setScene(scene); // Put scene in stage
primaryStage.show(); // Display the stage
}
}
§14.5 Property Binding
 The target listens for changes in the source and
updates itself when the source changes
 Remember, the binding syntax is
target.bind(source);
 Realize that with a setter, we specify a value;
with binding, we specify the property itself, rather
than the value of the property
 That’s why we have to use the special
methods .add, .subtract, .multiply, and
.divide, rather than the numeric operators; the
methods return property objects, rather than
numeric values (see p.543).
§14.5 Property Binding
 Listing 14.6 (p.544) drives this distinction home:
 A pair of simple double property objects (not
double values) are created with different values,
and then one is bound to the other
 Their values are printed out (showing that they
are different), the value of one is changed, and
then they are both printed again, showing that
changing one changed the other.
 See next slide
§14.5 Property Binding
import javafx.beans.property.DoubleProperty;
import javafx.beans.property.SimpleDoubleProperty;

public class BindingDemo


{
public static void main(String[] args)
{
DoubleProperty d1 = new SimpleDoubleProperty(1);
DoubleProperty d2 = new SimpleDoubleProperty(2);
d1.bind(d2);

System.out.println("d1 is " + d1.getValue()


+ " and d2 is " + d2.getValue());

d2.setValue(70.2);

System.out.println("d1 is " + d1.getValue()


+ " and d2 is " + d2.getValue());
}
}
§14.5 Property Binding
 So far, all of the bindings we have done are one-
way – a change in the source causes a change
in the target, but not vice versa
 If the source and the target are both binding
properties and observable properties, then they
can serve as both a source and a target, and
they can be bound bidirectionally, using the
.bindBidirectional method
 When two properties are bidirectionally bound,
changing either changes the other; both act as
sources, and both act as targets.
Section 14.6

Common
Properties and
Methods for
§14.6 Common Node Properties &
Methods
 Nodes share many common properties
 This section introduces two – style and rotate
 JavaFX style properties are a lot like CSS
(Cascading Style Sheets) use to specify styles in
HTML (Web) pages.
For more on HTML and CSS, see Liang supplements
V.A and V.B (on the text’s companion website)
 Thus, it’s known as JavaFX CSS
 The official Java documentation on these
properties can be found here
§14.6 Common Node Properties &
Methods
 In Matlab, we could set both the color and style
of a line at once
 Similarly, in JavaFX CSS, we can set more than
one property at a time
 Each property begins with the prefix –fx–, and
is of the form styleName:value, with multiple
settings separated by semicolons.
 For example:
circle.setStyle(“-fx-stroke: black; -fx-fill: red;”);
 Is equivalent to:
circle.setStroke(Color.BLACK);
circle.setFill(Color.RED);
§14.6 Common Node Properties &
Methods
 Listing 14.7 (pp. 545 – 546) and next slide shows
a program that creates a button with a blue
border, uses JavaFX CSS to set its pane’s style
to a red border and a light gray fill, and then
rotates the button 45 degrees
Note: positive rotation is clockwise;
negative is CCW
§14.6 Common Node Properties &
Methods
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.stage.Stage;
import javafx.scene.layout.StackPane;

public class NodeStyleRotateDemo 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();
Button btOK = new Button("OK");
btOK.setStyle("-fx-border-color: blue;"); // create blue-bordered button
pane.getChildren().add(btOK);

pane.setRotate(45); // rotate pane and set its style before adding to scene
pane.setStyle("-fx-border-color: red; -fx-background-color: lightgray;");

Scene scene = new Scene(pane, 200, 250);


primaryStage.setTitle("NodeStyleRotateDemo"); // Set the stage title
primaryStage.setScene(scene); // Place the scene in the stage
primaryStage.show(); // Display the stage
}
}
Section 14.7

The Color Class


§14.7 The Color Class
 In EECS 1000, we said that images are made up
of pixels, and each pixel is made up of a red
component, a green component, and a blue
component, and that mixing these three
components allows us to produce a huge
number of colors
 JavaFX uses this same color model, but adds a
fourth “component” to a pixel – its opacity.
 In some image processing literature, this opacity
is sometimes referred to as the Alpha channel
§14.7 The Color Class
 There are 3 sets of color constructors (“mixers”):
The ones named Color (or color) require double
values  [0.0, 1.0] for the R/G/B/A components
The ones named rgb require int values  [0, 255]
The hsb / hsba color models are also supported
 Just like String, Color is immutable.
 If we want a lighter version of this Color, we can
use .lighter(), but we get a NEW color, rather
than changing the value of the current color, just
like .toUpperCase doesn’t change a String; it
gives us a new one with upper case characters.
§14.7 The Color Class
+Color(r: double, g: double, B:double, opacity:double)
+brighter(): color
+darker(): color
+color(r: double, g: double, B:double, opacity:double): Color
+color(r: double, g: double, B:double ): Color
+rgb(r: int, g: int, b: int, opacity: int): Color
+rgb(r: int, g: int, b: int ): Color

 The color() and rgb() methods are static,


and don’t require instantiating a color
 Also, we can use named color constants:
BEIGE, BLACK, BLUE, BROWN, CYAN, DARKGRAY, …
There are about 150 of them. See here
Section 14.8

The Font Class


§14.8: The Font Class
 We tend to think of “font” as being “Arial”, “Times
New Roman”, “Calibri”, etc., but those are font
names (more precisely, they’re typeface names)
 A full font specification requires the font name,
weight, posture, and size
§14.8: The Font Class
 We typically use just “NORMAL” or “BOLD” for the
FontWeights, but there’s a whole spectrum:
THIN
EXTRA_LIGHT
LIGHT FontPosture, however,
NORMAL comes in exactly two flavors:
MEDIUM REGULAR and ITALIC
SEMI_BOLD You can get a listing of all of
BOLD the font family names
EXTRA_BOLD installed on the computer
BLACK with .getFamilies()
Section 14.9

The Image and


ImageView Classes
§14.9: The Image & ImageView
Classes
 We used the File class to hold information
about a file, but not to actually read / write to it
 For that we used a Scanner / PrintWriter,
connected to the File object
 Similarly, the Image class is a container for an
image, but can’t be used to actually display an
image
 For that, we use the ImageView node (and attach it to
a scene)
§14.9: The Image & ImageView
Classes
 The Image class (the data types should be
ReadOnlyDoubleProperty for all except error):

 We construct an Image from a filename (or a


URL), and then we can give the Image to an
ImageView object to actually display it
§14.9: The Image & ImageView
Classes
 The ImageView class:

 Listing 14.9 (pp. 550 – 551, and next slide) show


how to use an ImageView to display an image
§14.9: The Image & ImageView
Classes
// Bunch of omitted Import statements, Class header, and start() header
{
// This is just the BODY of start()
// Create a pane to hold the image views
Pane pane = new HBox(10); // HBox is covered in next section
pane.setPadding(new Insets(5, 5, 5, 5));
Image image = new Image("image/us.gif"); // Load image from file
pane.getChildren().add(new ImageView(image)); // 1st IV gets image as-is
ImageView imageView2 = new ImageView(image); // 2nd IV forces image to
imageView2.setFitHeight(100); // fit into 100-x-100
imageView2.setFitWidth(100); // pixel area
pane.getChildren().add(imageView2);
ImageView imageView3 = new ImageView(image); // 3rd IV leaves size as-is,
imageView3.setRotate(90); // but rotates (CW) 90 deg,
pane.getChildren().add(imageView3);

// Create a scene and place it in the stage


Scene scene = new Scene(pane);
primaryStage.setTitle("ShowImage"); // Set the stage title
primaryStage.setScene(scene); // Place scene in stage
primaryStage.show(); // Display the stage
}
§14.9: The Image & ImageView
Classes
 The HBox is a pane that handles placement
of multiple nodes for us automatically.
 As we add nodes to the HBox, they are
automatically added in a row (horizontally)

 Notes:
 setRotate is a method in the Node class, so all nodes can
be rotated.
 If you use the URL-based constructor for Image, it must
include “http://”
 Java assumes the image is located in the same directory
as the .class file. If it’s located elsewhere, you must use
either a full path or a relative path to specify where
Section 14.10

Layout Panes
§14.10: Layout Panes
 As we’ve said (and have been doing), we add
our Nodes to a Pane, and then add the Pane to a
Scene, and then the Scene to a Stage (probably
the primary stage).
 How do we arrange (i.e., lay out) the Nodes on
the pane?
 Java has several different kinds of Panes that do
a lot of the layout work for us.
 This section examines these layout panes in
more detail
 We’ve already used the Pane , HBox, and
StackPane; we’ll start with the FlowPane…
§14.10: Layout Panes
Name Description
Pane Base class for layout panes. Use its getChildren() method to
return the list of nodes on the pane (or add to that list)
Provides no particular layout capabilities – it’s a “blank canvas”
typically used to draw shapes on

StackPane Places nodes on top of each other in the center of the pane
FlowPane Places the notes row-by-row horizontally or column-by-column
vertically (reading order)

GridPane Provide a 2-D grid of cells, into which we can place nodes
BorderPane Divides pane into top, bottom, left, right, and center regions
HBox Places nodes in a single (horizontal) row
VBox Places nodes in a single (vertical) column
§14.10.1: The FlowPane
 The FlowPane can be set up to work in “reading
order” (sequential rows left-to-right), by using
Orientation.HORIZONTAL or in sequential top-
to-bottom columns (Orientation.VERTICAL)
 You can also specify the gap between nodes (in
pixels)
 So far, we have seen putting Button and
ImageView nodes on a pane.
 Listing 14.10 (p. 553 and next slide) uses the
FlowPane and Label & TextField nodes.
 Let’s take a closer look…
§14.10.1: The FlowPane
public void start(Stage primaryStage) // From Listing 14.10 (p. 553)
{
// Create a pane and set its properties
FlowPane pane = new FlowPane();
pane.setPadding(new Insets(11, 12, 13, 14));
pane.setHgap(5);
pane.setVgap(5); Setting the padding with an Insets object gives us
a margin inside the pane. Just as angles are
always clockwise, the Insets are specified in
// Place nodes in the pane
clockwise
pane.getChildren().addAll(new order from the
Label("First top, so this pane will have
Name:"),
new TextField(), new Label("MI:"));
an 11-pixel gap between the top of the pane and
TextField tfMi = new TextField();
the first row, a 12-pixel gap between the right-most
tfMi.setPrefColumnCount(1);
node and the right side of the pane, 13 pixels at
pane.getChildren().addAll(tfMi,
the bottom,newand
Label("Last
14 pixels on Name:"),
the left side.
new TextField());

// Create a scene and place Hgap


The it theVgap
inand properties specify the gap
stage
between
Scene scene = new Scene(pane, elements
200, 250); on the same row, or between
rows
primaryStage.setTitle("ShowFlowPane"); // Set the stage title
primaryStage.setScene(scene); // Put scene in stage
primaryStage.show(); // “re-flows”
Resizing the window Display the stagejust as
the nodes,
} changing the page size in Word re-flows your text.
§14.10.1: The FlowPane
public void start(Stage primaryStage)
{ example introduces two new nodes: Label (which just lets us display text on a
This
// and
pane), Create a pane(which
TextField and set its aproperties
provides box into which the user can type text).
FlowPane pane = new FlowPane();
TextField nodes typically have
pane.setPadding(new a corresponding
Insets(11, 12, 13,Label,
14));so the user can tell what’s
supposed to go IN the TextField
pane.setHgap(5);
pane.setVgap(5);

// Place nodes in the pane


pane.getChildren().addAll(new Label("First Name:"),
new TextField(), new Label("MI:"));
TextField tfMi = new TextField();
tfMi.setPrefColumnCount(1);
pane.getChildren().addAll(tfMi, new Label("Last Name:"),
new TextField());
We can .add() individual
// Create a scene and nodes to a pane,
place it inor the
we can .addAll() to add a list of
stage
nodes, as isscene
Scene done here.
= new Scene(pane, 200, 250);
primaryStage.setTitle("ShowFlowPane"); // Set the stage title
We add a Label of “First Name:”, and then a TextField
primaryStage.setScene(scene); into scene
// Put which the
in user
stagecan type
theirprimaryStage.show(); // Display
first name, and then another Label for “MI:” (“Middle Initial”). the stage
}
§14.10.1: The FlowPane
public void start(Stage primaryStage)
{
// Create a pane and set its properties
FlowPane pane = new FlowPane();
pane.setPadding(new Insets(11, 12, 13, 14));
pane.setHgap(5);
pane.setVgap(5);

// Place nodes in the pane


pane.getChildren().addAll(new Label("First Name:"),
new TextField(), new Label("MI:"));
TextField tfMi = new TextField();
tfMi.setPrefColumnCount(1);
pane.getChildren().addAll(tfMi, new Label("Last Name:"),
new TextField());
Next,
//weCreate a sceneTextField
create another and placeforitthein Middle
the Initial,
stageand set its preferred column
count to 1 (ifscene
Scene it’s only
= going to hold an initial,
new Scene(pane, 200,why250);
make a “wide” box to hold it?)
primaryStage.setTitle("ShowFlowPane"); // Set the stage title
Note: the TextField’s variable is prefixed with “tf”. //
primaryStage.setScene(scene); NodePutvariables arestage
scene in typically
primaryStage.show();
prefixed with an abbreviation of its type, so we can tell//from
Display
lookingthe stage
at the variable
}
what kind of variable it is
§14.10.1: The FlowPane
public void start(Stage primaryStage)
{
// Create a pane and set its properties
FlowPane pane = new FlowPane();
pane.setPadding(new Insets(11, 12, 13, 14));
pane.setHgap(5);
pane.setVgap(5);

// Place nodes in the pane


pane.getChildren().addAll(new Label("First Name:"),
new TextField(), new Label("MI:"));
TextField tfMi = new TextField();
tfMi.setPrefColumnCount(1);
pane.getChildren().addAll(tfMi, new Label("Last Name:"),
new TextField());
Finally,
// we go back
Create to the task
a scene and of adding
place itthe
in(narrow) Middle Initial TextField, plus a
the stage
Label
Scene TextField
and ascene = newfor the last name200,
Scene(pane, to the250);
pane.
primaryStage.setTitle("ShowFlowPane"); // Set the stage title
we have Label / TextField pairs for First Name,
NowprimaryStage.setScene(scene); // Middle Initialin
Put scene (a one-character-
stage
wideprimaryStage.show();
TextField), and Last Name // Display the stage
}
§14.10.1: The FlowPane
 This is the stage we have built:

 Because we went in “reading order”, and added


the nodes in the order we did, we got this – the
“MI:” label is next to the tfMi TextField in
reading order, but this isn’t visually appealing.
§14.10.1: The FlowPane
 If we make the scene wider (enlarge the window)

 The elements “re-flow”, and now the MI TextField


fits on the same row as its Label
§14.10.2: The GridPane
 The GridPane divides the pane’s area into a 2-D
grid of rows and columns.
 Listing 14.11 shows the previous example
redone, with the three Labels in the left column,
and the three TextFields (note that the author
did not bother to make the MI TextField narrow
in this example)
§14.10.2: The GridPane

 A few notes:
The “Add” button is right-aligned within its cell (l. 31)
The whole frame is centered (l. 17)
The labels get the default horizontal alignment of “left”
We specify the column first (backwards from arrays)
Not every cell needs to be filled
Elements can be moved from one cell to another
§14.10.3: The BorderPane
 The BorderPane divides the
pane into five “regions”
 The program in Listing 14.12
places a CustomPane in each
region.
 The CustomPane is an extension of StackPane,
which is used to display the labels
 Note that a Pane is also a Node, so a Pane can
contain another Pane
 If a region is empty, it’s simply not shown
 We can clear a region with set<region>(null)
§14.10.4: HBox and VBox
 The FlowPane gave us rows and columns (in
reading order)
 The HBox and VBox panes give us a single row
or column (respectively)
 The program in Listing 14.13 (p. 559) illustrates
the use of a BorderPane, an HBox, and a VBox
 It creates a BorderPane with only the Top and
Left regions used (the others are empty)
 The Top region contains an HBox with two
buttons and an ImageView
 The Left region contains a VBox with 5 labels
§14.10.4: HBox and VBox
 The result:
Section 14.11

Shapes
§14.11: Shapes
 Beyond the Labels, TextFields, and other
kinds of nodes (which we’ll get to in due time)
that the user will interact with as part of our
interface, sometimes our GUIs need a little
“artwork”
 Shapes let us draw on a pane
§14.11: Shapes
 Liang shows us 8 shapes we can use to dress up
our panes:
§14.11: Shapes
 All of the shapes have some common properties:
fill (color)
stroke (line color)
strokeWidth (how heavy the stroke line is)
§14.11.1: Text
 The Text shape lets us put text on a pane
 “Wait, doesn’t a Label let us do the same thing?”
 Well, yes and no.
 They’re two different kinds of text, with two
different inheritance paths.
 For more information, see here:
It’s pretty well summed up in the paragraph that starts
with “In general”.
§14.11.1: Text
 Listing 14.14 (pp. 561 – 562) shows placing
three Text shapes on a pane, each time using
the (double, double, String) form of the
constructor to specify the x and y locations for
the String.
 The text we place as a Shape can have its color,
font (typeface, weight, size, and posture),
underline, and strikethrough properties set.
This is different from a Label’s JavaFX CSS properties
 Once placed, we can move text by using setX()
and setY() to give it a new location
§14.11.2: Line
 Listing 14.15 (pp. 562 – 563) shows how to draw
a pair of Line shapes on a pane
 Each line is specified by its two endpoints:
startX, startY and endX, endY (all doubles, in
pixels)
§14.11.3: Rectangle
 The Rectangle shape is specified by its top-left
corner (x, y) and its width and height.
 Optionally, we can specify the arcWidth and
arcHeight (in pixels) of the corners, to create
rounded corners (arc measurements of 0 make
squared-off corners)
 See Listing 14-16
and Figure 14.31
§14.11.4: Circle and Ellipse
 The Circle and Ellipse shapes are very
similar, as you might expect
 Both are specified by their center point (centerX,
centerY)
 The Circle has a single radius
 The Ellipse has two radii (radiusX & radiusY)
 See
Listing 14.17
(pp. 566 – 7)
§14.11.5: Arc
 An Arc is just part of an Ellipse
 An Arc is specified by its center point, radii, start
angle (in degrees), and length (in degrees)
If the two radii are equal, then it’s a circular arc
Angles may be negative (clockwise sweep)
§14.11.5: Arc
 Once specified, an Arc can be drawn in any of
three styles: ArcType.OPEN, ArcType.CHORD, or
ArcType.ROUND
 See Listing 14.18 (pp. 568 – 569) for the code
§14.11.6: Polygon and
Polyline
 The Polygon and Polyline shapes are
identical, except that the Polyline isn’t closed
 Both are specified by a list of (x, y) pairs
§14.11.6: Polygon and
Polyline
 If we know all of the points up-front, we can
specify them as a variable-length parameter list:
Polygon p = new Polygon(x1, y1, x2, y2, …);
 If we don’t know all of the points a priori, the
Polygon exposes an ObservableList to which
we can add points (i.e., generate the points on-
the-fly and add them to the list as we go)
This latter approach is taken by the program to create
a hexagon (Listing 14.19, pp. 570 – 1, and next slide)
§14.11.6: Polygon and
Polyline
Pane pane = new Pane(); // create a pane
Polygon polygon = new Polygon(); // create a polygon
pane.getChildren().add(polygon); // add the polygon to the pane
polygon.setFill(Color.WHITE); // polygon will be filled in white
polygon.setStroke(Color.BLACK); // with a black border
ObservableList<Double> list = polygon.getPoints(); // get its vertex list

final double WIDTH = 200, HEIGHT = 200; // See Fig. 14.40 (a)
double centerX = WIDTH / 2, centerY = HEIGHT / 2; //
double radius = Math.min(WIDTH, HEIGHT) * 0.4; //

// Generated and add (x, y) points to the polygon’s vertex list


for (int i = 0; i < 6; i++)
{
list.add(centerX + radius * Math.cos(2 * i * Math.PI / 6));
list.add(centerY - radius * Math.sin(2 * i * Math.PI / 6));
}

// Create a scene and place it in the stage


Scene scene = new Scene(pane, WIDTH, HEIGHT);
primaryStage.setTitle("ShowPolygon"); // Set the stage title
primaryStage.setScene(scene); // Put scene in stage
primaryStage.show(); // Display the stage
§14.11.6: Polygon and
Polyline
 In the preceding code, if we change Polygon to
Polyline, everything else stays the same,
except the last line segment to close the figure
isn’t drawn, and rather than this…

…we get this


Section 14.12

Case Study: The


ClockPane Class
§14.12: The ClockPane Class
 In this section, we’re going to develop a class to
display an analog clock face
 In keeping with good coding practices, we’re not
going to start by writing any code
 First, we start with a “napkin sketch” of what we
would like to end up with
§14.12: The ClockPane Class
 [Aside] About the “napkin sketch”:
When the IBM PC first came out in the early ‘80’s,
“computer” meant either “mainframe” or “desktop” –
there was no such thing as “portable”, and virtually
nobody owned one at home

But executives and mid-level


managers wanted to be able
to take work home in the
evenings, but much of their
work involved spreadsheets
and other computer-related data.
§14.12: The ClockPane Class
 [Aside] About the term “napkin sketch”:
In 1982, three senior managers from TI invested
$1,000 each to form their own company
They met at Houston’s “House
of Pies” to brainstorm ideas.
One turned over a paper
placemat and started drawing
§14.12: The ClockPane Class
 [Aside] About the term “napkin sketch”:
The result was the Compaq Portable Computer
The first portable fully compatible with the IBM PC
§14.12: The ClockPane Class
 [Aside] About the term “napkin sketch”:
It was “portable”, but it was often
described as “transportable”
or “luggable”
It required 110 VAC (no battery)
It weighed 28 pounds, and was the
size of a suitcase
In its first three years, Compaq
Computer Corporation did OK:
1982 - $111 million in revenue
1983 - $329 million
1984 - $504 million
They hit $1 billion in sales in 6 years – a record
§14.12: The ClockPane Class
 The bottom line of this tangent is that we should
be able to describe something pretty fully before
we ever start to build it.
 Now, back to the analog ClockPane class…
 We want it to have a circular face,
with colored hands that show the
hour, minute, & second
 It should have markers at 12, 3,
6, & 9 o’clock as visual references
 It should display the time digitally at the bottom,
below the clock face
§14.12: The ClockPane Class
 This description
gives us enough
of an idea of
what this thing
should do that
we can create
its UML diagram:
 Now that we know what properties it will need,
and what methods it will expose, we can write a
program that will use one of these (even before
we build one)
§14.12: The ClockPane Class
public void start(Stage primaryStage)
{
// Create a clock and a label
ClockPane clock = new ClockPane();
String timeString = clock.getHour() + ":" + clock.getMinute()
+ ":" + clock.getSecond();
Label lblCurrentTime = new Label(timeString);

// Place clock and label in border pane


BorderPane pane = new BorderPane(); // Use a border layout
pane.setCenter(clock); // Clock in center
pane.setBottom(lblCurrentTime); // "digital" time at bottom
BorderPane.setAlignment(lblCurrentTime, Pos.TOP_CENTER);

// Create a scene and place our pane in the stage


Scene scene = new Scene(pane, 250, 250);
primaryStage.setTitle("DisplayClock"); // Set the stage title
primaryStage.setScene(scene); // Put scene in stage
primaryStage.show(); // Display the stage
}
§14.12: The ClockPane Class
 Now, armed with a description of what it should
do, its UML diagram, and a program to test it,
we can actually implement the ClockPane class
 The first thing the text does is work through
the trigonometry to determine the angles and
endpoints of each of the hands, for a given time
of day (pp. 573 – 574)
 From there, the rest is rather straightforward (if a
bit long, at 144 lines).
 See Listing 14.21 (pp. 574 – 576), as well as the
discussion after the listing (pp. 576 – 577)
End of Chapter 14

Any Questions?

You might also like