0% found this document useful (0 votes)
6 views55 pages

Unit 5 Material

JavaFX is a modern GUI framework for Java that simplifies the creation of visually appealing applications. It offers a comprehensive API, supports FXML for UI design, and provides advanced features like 2D/3D graphics and multimedia. The document outlines JavaFX's structure, including its packages, core classes like Stage and Scene, layout management, application lifecycle, and basic controls such as buttons and labels.

Uploaded by

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

Unit 5 Material

JavaFX is a modern GUI framework for Java that simplifies the creation of visually appealing applications. It offers a comprehensive API, supports FXML for UI design, and provides advanced features like 2D/3D graphics and multimedia. The document outlines JavaFX's structure, including its packages, core classes like Stage and Scene, layout management, application lifecycle, and basic controls such as buttons and labels.

Uploaded by

forothpurpose
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd

Introducing GUI Programming with JavaFX

JavaFX is one of the Java’s client platforms and GUI framework. JavaFX provides a
powerful, streamlined, flexible framework that simplifies the creation of modern, visually
exciting GUIs.

The original version of JavaFX was built on a scripting language called JavaFX Script, which
has since been discontinued. Starting with the release of JavaFX 2.0, JavaFX has been
developed using Java itself and now offers a comprehensive API. Additionally, JavaFX
supports FXML, a markup language that can be used (though it is not mandatory) to define
the user interface.

JavaFX vs Swings

JavaFX Swing
Modern library for rich, media-intensive Legacy library for basic desktop
GUIs. applications.
Supports CSS for styling and FXML for
Requires manual coding for customization.
declarative UI.
Built-in support for 2D/3D graphics, Limited graphics capabilities, no media
animations, and multimedia. support.
Actively developed as a standalone module. No active development; considered legacy.
Can embed Swing components using Cannot embed JavaFX components; less
SwingNode. flexible.

The JavaFX Packages


JavaFX elements are organized into packages that start with the "javafx" prefix. As of now,
there are over 30 JavaFX packages available in its API library. Here are four examples:
`[Link]`, `[Link]`, `[Link]`, and `[Link]`. JavaFX
provides a wide range of functionalities.

The Stage and Scene Classes


In JavaFX, the Stage and Scene classes are fundamental to creating graphical user interfaces
(GUIs).

Stage:
 A Stage represents the primary window or container for a JavaFX application.
 It's like the "frame" in which the entire user interface is displayed.
 The primary stage is provided by JavaFX and is created automatically when the
application starts. You can also create additional stages for pop-ups or secondary
windows.
 Important methods:
o setTitle(String title): Sets the title of the window.
o setScene(Scene scene): Assigns a scene to the stage.
o show(): Makes the stage visible.
o close(): Closes the stage.
Scene:
 A Scene represents the content inside a stage. It serves as the container for all visual
elements (like buttons, labels, and layouts).
 It is constructed using a root node, which is usually a layout container (e.g., VBox,
HBox, Pane).
 A stage can only display one scene at a time, but you can switch scenes dynamically.
 Important methods:
o setRoot(Parent root): Sets or changes the root node.
o setFill(Paint color): Sets the background fill color of the scene.
o getWidth() and getHeight(): Retrieve the dimensions of the scene.

Nodes and Scene Graphs

Nodes:
 A Node is the fundamental building block of a JavaFX user interface. Each visual
element in a JavaFX application (e.g., buttons, labels, shapes, etc.) is a subclass of the
Node class.
 Nodes can represent graphical elements, shapes, text, images, or even entire
containers (layouts).
 Every node has properties such as:
o Position and Size: layoutX, layoutY, width, height
o Transforms: rotate, scaleX, translateY, etc.
o Style: setStyle(String css)
o Event Handling: Nodes can respond to user interactions like mouse clicks or
key presses.
Scene Graph:
 The Scene Graph is a hierarchical data structure that represents all the elements in a
JavaFX scene.
 It is organized as a tree, with a single root node and child nodes branching out.
 Parent nodes (like layouts) can have children, while leaf nodes (like a button or a
shape) cannot have children.
 The Scene Graph forms the structure of the UI, ensuring a logical and organized
arrangement of nodes.
Characteristics Scene Graph:
 Hierarchy: Nodes are arranged in a parent-child relationship. The root node is at the
top of the hierarchy.
 Traversal: Operations on the scene graph, like rendering or event dispatching, traverse
this hierarchical structure.
 Dynamic Updates: You can add, remove, or modify nodes dynamically, and the UI
will update accordingly.

Layouts

1. Types of Layouts:
JavaFX provides several built-in layout panes, such as Pane, HBox, VBox, GridPane,
BorderPane, StackPane, and FlowPane. Each serves a specific purpose in organizing UI
components.
2. Automatic Layout Management:
Layouts in JavaFX automatically resize and reposition their children based on the available
space and the child nodes' properties, like maxWidth, maxHeight, and alignment.
3. Nested Layouts:
Layouts can be nested to create complex UI designs. For instance, you can place an HBox
inside a GridPane or use a StackPane within a BorderPane.

4. Responsive Design:
JavaFX layouts are designed to adapt to changes in the window size. Containers like
GridPane supports flexible grid resizing, making it easier to create responsive applications.

The layout panes are packaged in [Link].

The Application Class and the Life-cycle Methods


A JavaFX application must define a class that extends Application class, which is packaged
in [Link].

The Application class in JavaFX is the entry point for JavaFX applications. It provides a
framework for the JavaFX runtime to launch and manage the application's lifecycle.

Life-cycle Methods of the Application Class:


init():
 Called before the application starts and before the start() method.
 Used for initializing resources that the application might need.
 Does not run on the JavaFX Application Thread, so it is not suitable for UI-related
tasks. Example: Loading configurations, initializing data models, etc.

start(Stage primaryStage):
 The main entry point for a JavaFX application.
 Called after init() and is responsible for setting up the primary stage and the UI.
 You must override this method in your subclass of Application.
 The primaryStage represents the main window of the application.
Example: Setting the scene, adding components, and displaying the stage.
stop():
Called when the application is about to shut down.
 Used for cleaning up resources, saving application state, or closing connections.
 Can be triggered by the user closing the application or programmatically using
[Link]().

Application Lifecycle Flow:


init() → 2. start() → (Application runs) → 3. stop()

Launching a JavaFX Application


To start a free-standing JavaFX application, you must call the launch( ) method defined by
Application.

public static void launch(String ... args)

Here, args is a possibly empty list of strings that typically specify command-line arguments.
When called, launch( ) causes the application to be constructed, followed by calls to init( )
and start( ). The launch( ) method will not return until after the application has terminated.
This version of launch( ) starts the subclass of Application from which launch( ) is called.
A JavaFX Application Skeleton(Demonstration of life cycle methods)
All JavaFX applications share the same basic skeleton. In addition to showing the general
form of a JavaFX application, the skeleton also illustrates how to launch the application and
demonstrates when the life-cycle methods are called. A message noting when each life-cycle
method is called is displayed on the console. The complete skeleton is shown here:

// A JavaFX application skeleton.


import [Link].*;
import [Link].*;
import [Link].*;
import [Link].*;
public class JavaFXSkel extends Application {
public static void main(String[] args) {
[Link]("Launching JavaFX application.");
// Start the JavaFX application by calling launch().
launch(args);
}
// Override the init() method.
public void init() { [Link]("Inside the init() method.");
}
// Override the start() method.
public void start(Stage myStage) {
[Link]("Inside the start() method.");
// Give the stage a title.
[Link]("JavaFX Skeleton.");
// Create a root node. In this case, a flow layout pane is used, but several alternatives exist.
FlowPane rootNode = new FlowPane();
// Create a scene.
Scene myScene = new Scene(rootNode, 300, 200);
// Set the scene on the stage.
[Link](myScene);
// Show the stage and its scene.
[Link]();
}
// Override the stop() method.
public void stop() {
[Link]("Inside the stop() method.");
}
}
Although the skeleton is quite short, it can be compiled and run. It produces the window
shown here:

It also produces the following output on the console:


Launching JavaFX application.
Inside the init() method.
Inside the start() method. When you close the window, this message is displayed on the
console:
Inside the stop() method.

A Simple JavaFX Control: Label


JavaFX supplies a rich set of controls. The simplest control is the label because it just
displays a message, which, in this example, is text. The JavaFX label is an instance of the
Label class, which is packaged in [Link].
Label defines three constructors. The one we will use here is

Label(String str)
Here, str is the string that is displayed.

Once you have created a label (or any other control), it must be added to the scene’s content,
which means adding it to the scene graph. To do this, you will first call getChildren( ) on the
root node of the scene graph. It returns a list of the child nodes in the form of an
ObservableList<Node>. ObservableList is packaged in [Link], and it inherits
[Link]. Using the returned list of child nodes, you can add the label to the list by
calling add( ), passing in a reference to the label.

Example:
// Demonstrate a JavaFX label.
import [Link].*;
import [Link].*;
import [Link].*;
import [Link].*;
import [Link].*;
public class JavaFXLabelDemo extends Application {
public static void main(String[] args) {
// Start the JavaFX application by calling launch().
launch(args);
}
// Override the start() method.
public void start(Stage myStage) {
// Give the stage a title.
[Link]("Demonstrate a JavaFX label.");
// Use a FlowPane for the root node.
FlowPane rootNode = new FlowPane();
// Create a scene.
Scene myScene = new Scene(rootNode, 300, 200);
// Set the scene on the stage.
[Link](myScene);
// Create a label.
Label myLabel = new Label("This is a JavaFX label");
// Add the label to the scene graph.
[Link]().add(myLabel);
// Show the stage and its scene.
[Link]();
}
}
This program produces the following window:

ObservableList provides a method called addAll( ) that can be used to add two or more
children to the scene graph in a single call. To remove a control from the scene graph, call
remove( ) on the ObservableList. For example,
[Link]().remove(myLabel);
removes myLabel from the scene.

Using Buttons and Events


Most GUI controls generate events that are handled by your program. For example, buttons,
check boxes, and lists all generate events when they are used. One commonly used control is
the button. This makes button events one of the most frequently handled. Therefore, a button
is a good way to demonstrate the fundamentals of event handling in JavaFX. For this reason,
the fundamentals of event handling and the button are introduced together.

Introducing the Button Control


In JavaFX, the push button control is provided by the Button class, which is in
[Link].- control. Button inherits a fairly long list of base classes that include
ButtonBase, Labeled, Region, Control, Parent, and Node.

Button defines three constructors. The one we will use is shown here:
Button(String str)
In this case, str is the message that is displayed in the button. When a button is pressed, an
ActionEvent is generated. ActionEvent is packaged in [Link]. You can register a
listener for this event by using setOnAction( ), which has this general form:

final void setOnAction(EventHandler<ActionEvent>handler)

Here, handler is the handler being registered. We can use an anonymous I nner class or
lambda expression for the handler. The setOnAction( ) method sets the property onAction,
which stores a reference to the handler.

Demonstrating Event Handling and the Button


The following program demonstrates event handling. It uses two buttons and a label. Each
time a button is pressed, the label is set to display which button was pressed.

package application;

//Demonstrate JavaFX events and buttons.


import [Link].*;
import [Link].*;
import [Link].*;
import [Link].*;
import [Link].*;
import [Link].*;
import [Link].*;
public class javaFXEvent extends Application {
Label response;
public static void main(String[] args) {
//Start the JavaFX application by calling launch().
launch(args);
}
//Override the start() method.
public void start(Stage myStage) {
//Give the stage a title.
[Link]("Demonstrate JavaFX Buttons and Events.");
//Use a FlowPane for the root node. In this case,
//vertical and horizontal gaps of 10.
FlowPane rootNode = new FlowPane(10, 10);
//Center the controls in the scene.
[Link]([Link]);
//Create a scene.
Scene myScene = new Scene(rootNode, 300, 100);
//Set the scene on the stage.
[Link](myScene);
//Create a label.
response = new Label("Push a Button");
//Create two push buttons.
Button btnAlpha = new Button("Alpha");
Button btnBeta = new Button("Beta");
//Handle the action events for the Alpha button using Anonymous Inner Class
Implementation.
[Link](new EventHandler<ActionEvent>() {
public void handle(ActionEvent ae) {
[Link]("Alpha was pressed.");
}
});
//Handle the action events for the Beta button using Lambda expression .
[Link]((ae) ->
[Link]("Beta was pressed.")
);
//Add the label and buttons to the scene graph.
[Link]().addAll(btnAlpha, btnBeta, response);
//Show the stage and its scene.
[Link]();
}
}
Sample output from this program is shown here:
Let’s examine a few key portions of this program. First, notice how buttons are created by
these two lines:
Button btnAlpha = new Button("Alpha");
Button btnBeta = new Button("Beta");
This creates two text-based buttons. The first displays the string Alpha; the second displays
Beta.
Next, an action event handler is set for each of these buttons. The sequence for the Alpha
button is shown here:
// Handle the action events for the Alpha button.
[Link](new EventHandler<ActionEvent>() {
public void handle(ActionEvent ae) {
[Link]("Alpha was pressed.");
}
});

Drawing Directly on a Canvas

JavaFX’s graphics methods are found in the GraphicsContext class, which is part of
[Link]. These methods can be used to draw directly on the surface of a canvas,
which is encapsulated by the Canvas class in [Link]. When you draw something,
such as a line, on a canvas, JavaFX automatically renders it whenever it needs to be
redisplayed.

Before you can draw on a canvas, you must perform two steps. First, you must create a
Canvas instance. Second, you must obtain a GraphicsContext object that refers to that
canvas. You can then use the GraphicsContext to draw output on the canvas. The Canvas
class is derived from Node; thus it can be used as a node in a scene graph.
Canvas defines two constructors. One is the default constructor, and the other is the one
shown here:

Canvas(double width, double height)


Here, width and height specify the dimensions of the canvas.

To obtain a GraphicsContext that refers to a canvas, call getGraphicsContext2D( ).Here is


its general form:

GraphicsContext getGraphicsContext2D( )

The graphics context for the canvas is returned.

GraphicsContext defines a large number of methods that draw shapes, text, and images, and
support effects and transforms. A few of its methods are described here.

You can draw a line using strokeLine( ), shown here:

void strokeLine(double startX, double startY, double endX, double endY)

It draws a line from startX, startY to endX,endY, using the current stroke, which can be a
solid color or some more complex style.
To draw a rectangle, use either strokeRect( ) or fillRect( ), shown here:

void strokeRect(double topX, double topY, double width, double height)


void fillRect(double topX, double topY, double width, double height)

The upper-left corner of the rectangle is at topX, topY. The width and height parameters
specify its width and height. The strokeRect( ) method draws the outline of a rectangle using
stroke, and fillRect( ) fills the rectangle with the current fill. The current fill can be as simple
as a solid color or something more complex.
To draw an ellipse, use either strokeOval( ) or fillOval( ), shown next:

void strokeOval(double topX, double topY, double width, double height)


void fillOval(double topX, double topY, double width, double height)

The upper-left corner of the rectangle that bounds the ellipse is at topX, topY. The width and
height parameters specify its width and height. The strokeOval( ) method draws the outline
of an ellipse using the current stroke, and fillOval( ) fills the oval with the current fill. To
draw a circle, pass the same value for width and height.
You can draw text on a canvas by using the strokeText( ) and fillText( ) methods. We will
use this version of fillText( ):

void fillText(String str, double topX, double topY)

It displays str starting at the location specified by topX, topY, filling the text with the current
fill. You can set the font and font size of the text being displayed by using setFont( ). You
can obtain the font used by the canvas by calling getFont( ). By default, the system font is
used. You can create a new font by constructing a Font object. Font is packaged in
[Link]. For example, you can create a default font of a specified size by using this
constructor:
Font(double fontSize)
Here, fontSize specifies the size of the font.

You can specify the fill and stroke using these two methods defined by Canvas:
void setFill(Paint newFill)
void setStroke(Paint newStroke)

Notice that the parameter of both methods is of type Paint. This is an abstract class packaged
in [Link]. Its subclasses define fills and strokes. The one we will use is Color,
which simply describes a solid color. Color defines several static fields that specify a wide
array of colors, such as [Link], [Link], [Link], and so on.

The following program uses the aforementioned methods to demonstrate drawing on a


canvas. It first displays a few graphic objects on the canvas. Then, each time the Change
Color button is pressed, the color of three of the objects changes color. If you run the
program, you will see that the shapes whose color is not changed are unaffected by the
change in color of the other objects. Furthermore, if you try covering and then uncovering the
window,
you will see that the canvas is automatically repainted, without any other actions on the part
of your program. Sample output is shown here:
// Demonstrate drawing.
import [Link].*;
import [Link].*;
import [Link].*;
import [Link].*;
import [Link].*;
import [Link].*;
import [Link].*;
import [Link].*;
import [Link].*;
import [Link].*;
import [Link].*;
public class DirectDrawDemo extends Application {
GraphicsContext gc;
Color[] colors = { [Link], [Link], [Link], [Link] };
int colorIdx = 0;
public static void main(String[] args) {
// Start the JavaFX application by calling launch().
launch(args);
}
// Override the start() method.
public void start(Stage myStage) {
// Give the stage a title.
[Link]("Draw Directly to a Canvas.");
// Use a FlowPane for the root node.
FlowPane rootNode = new FlowPane();
// Center the nodes in the scene.
[Link]([Link]);
// Create a scene.
Scene myScene = new Scene(rootNode, 450, 450);
// Set the scene on the stage.
[Link](myScene);
// Create a canvas.
Canvas myCanvas = new Canvas(400, 400);
// Get the graphics context for the canvas.
gc = myCanvas.getGraphicsContext2D();
// Create a push button.
Button btnChangeColor = new Button("Change Color");
// Handle the action events for the Change Color button.
[Link](new EventHandler<ActionEvent>() {
public void handle(ActionEvent ae) {
// Set the stroke and fill color.
[Link](colors[colorIdx]);
[Link](colors[colorIdx]);
// Redraw the line, text, and filled rectangle in the new color. This leaves the color of the
other //nodes unchanged.
[Link](0, 0, 200, 200);
[Link]("This is drawn on the canvas.", 60, 50);
[Link](100, 320, 300, 40);
// Change the color.
colorIdx++;
if(colorIdx == [Link]) colorIdx= 0;
}
});
// Draw initial output on the canvas.
[Link](0, 0, 200, 200);
[Link](100, 100, 200, 200);
[Link](0, 200, 50, 200);
[Link](0, 0, 20, 20);
[Link](100, 320, 300, 40);
// Set the font size to 20 and draw text.
[Link](new Font(20));
[Link]("This is drawn on the canvas.", 60, 50);
// Add the canvas and button to the scene graph.
[Link]().addAll(myCanvas, btnChangeColor);
// Show the stage and its scene.
[Link]();
}
}

It is important to emphasize that GraphicsContext supports many more operations than


those demonstrated by the preceding program. For example, you can apply various
transforms, rotations, and effects. Despite its power, its various features are easy to master
and use. One other point: A canvas is transparent. Therefore, if you stack canvases, the
contents of both will show. This may be useful in some situations.
NOTE [Link] contains several classes that can also be used to draw various
types of graphical shapes, such as circles, arcs, and lines. These are represented by nodes and
can, therefore,be directly part of the scene graph. You will want to explore these on your
own.

Exploring JavaFXControls

Using Image and ImageView


Several of JavaFX’s controls let you include an image. For example, in addition to text, you
can specify an image in a label or a button. Furthermore, you can embed stand-alone images
in a scene directly. At the foundation for JavaFX’s support for images are two classes: Image
and ImageView. Image encapsulates the image, itself, and ImageView manages the display
of an image. Both classes are packaged in [Link]. The Image class loads an
image from either an InputStream, a URL, or a path to the image file. Image defines several
constructors; this is the one we will use:

Image(String url)

Here, url specifies a URL or a path to a file that supplies the image. The argument is assumed
to refer to a path if it does not constitute a properly formed URL. Otherwise, the image is
loaded from the URL. The examples that follow will load images from files on the local
filesystem. Other constructors let you specify various options, such as the image’s width and
height. One other point: Image is not derived from Node. Thus, it cannot, itself, be part of a
scene graph. Once you have an Image, you will use ImageView to display it. ImageView is
derived from Node, which means that it can be part of a scene graph. ImageView defines
three constructors. The first one we will use is shown here:

ImageView(Image image)

This constructor creates an ImageView that uses image for its image. Putting the preceding
discussion into action, here is a program that loads an image of an hourglass and displays it
via ImageView. The hourglass image is contained in a file called [Link], which is
assumed to be in the local directory.
// Load and display an image.
import [Link].*;
import [Link].*;
import [Link].*;
import [Link].*;
import [Link].*;
import [Link].*;
public class ImageDemo extends Application {
public static void main(String[] args) {
// Start the JavaFX application by calling launch().
launch(args);
}
// Override the start() method.
public void start(Stage myStage) {
// Give the stage a title.
[Link]("Display an Image");
// Use a FlowPane for the root node.
FlowPane rootNode = new FlowPane();
// Use center alignment.
[Link]([Link]);
// Create a scene.
Scene myScene = new Scene(rootNode, 300, 200);
// Set the scene on the stage.
[Link](myScene);
// Create an image.
Image hourglass = new Image("[Link]");
// Create an image view that uses the image.
ImageView hourglassIV = new ImageView(hourglass);
// Add the image to the scene graph.
[Link]().add(hourglassIV);
// Show the stage and its scene.
[Link]();
}
}
Sample output from the program is shown here:

In the program, pay close attention to the following sequence that loads the image andthen
creates an ImageView that uses that image:
// Create an image.
Image hourglass = new Image("[Link]");
// Create an image view that uses the image.
ImageView hourglassIV = new ImageView(hourglass);
As explained, an image by itself cannot be added to the scene graph. It must first beembedded
in an [Link] cases in which you won’t make further use of the image, you can specify
a URL orfilename when creating an ImageView. In this case, there is no need to explicitly
create anImage. Instead, an Image instance containing the specified image is constructed
automaticallyand embedded in the ImageView. Here is the ImageView constructor that does
this:
ImageView(String url)
Here, url specifies the URL or the path to a file that contains the image.

Adding an Image to a Label


As explained in the previous chapter, the Label class encapsulates a label. It can display a
text message, a graphic, or both. So far, we have used it to display only text, but it is easy to
add an image. To do so, use this form of Label’s constructor:

Label(String str, Node image)

Here, str specifies the text message and image specifies the image. Notice that the image is of
type Node. This allows great flexibility in the type of image added to the label, but for our
purposes, the image type will be ImageView. Here is a program that demonstrates a label
that includes a graphic. It creates a label that displays the string "Hourglass" and shows the
image of an hourglass that is loaded from
the [Link] file.
// Demonstrate an image in a label.
import [Link].*;
import [Link].*;
import [Link].*;
import [Link].*;
import [Link].*;
import [Link].*;
import [Link].*;
public class LabelImageDemo extends Application {
public static void main(String[] args) {
// Start the JavaFX application by calling launch().
launch(args);
}
// Override the start() method.
public void start(Stage myStage) {
// Give the stage a title.
[Link]("Use an Image in a Label");
// Use a FlowPane for the root node.
FlowPane rootNode = new FlowPane();
// Use center alignment.
[Link]([Link]);
// Create a scene.
Scene myScene = new Scene(rootNode, 300, 200);
// Set the scene on the stage.
[Link](myScene);
// Create an ImageView that contains the specified image.
ImageView hourglassIV = new ImageView("[Link]");
// Create a label that contains both an image and text.
Label hourglassLabel = new Label("Hourglass", hourglassIV);
// Add the label to the scene graph.
[Link]().add(hourglassLabel);
// Show the stage and its scene.
[Link]();
}
}
Here is the window produced by the program:

As you can see, both the image and the text are displayed. Notice that the text is to the right
of the image. This is the default. You can change the relative positions of the image and text
by calling setContentDisplay( ) on the label. It is shown here:
final void setContentDisplay(ContentDisplay position)
The value passed to position determines how the text and image is displayed. It must be one
of these values, which are defined by the ContentDisplay enumeration:

With the exception of TEXT_ONLY and GRAPHIC_ONLY, the values specify the
location of the image. For example, if you add this line to the preceding program:
[Link]([Link]); the image of the hourglass will be
above the text, as shown here:

The other two values let you display either just the text or just the image. This might be
useful if your application wants to use an image at some times, and not at others, for example.
(If you want only an image, you can simply display it without using a label, as described in
the previous section.)You can also add an image to a label after it has been constructed by
using the setGraphic( ) method. It is shown here:

final void setGraphic(Node image)


Here, image specifies the image to add.

Using an Image with a Button


Button is JavaFX’s class for push buttons. The procedure for adding an image to a button is
similar to that used to add an image to a label. First obtain an ImageView of the image. Then
add it to the button. One way to add the image is to use this constructor:

Button(String str, Node image)

Here, str specifies the text that is displayed within the button and image specifies the image.
You can specify the position of the image relative to the text by using
setContentDisplay( )in the same way as just described for Label. Here is an example that
displays two buttons that contain images. The first shows an hourglass. The second shows an
analog clock. When a button is pressed, the selected timepiece is reported. Notice that the text
is displayed beneath the image.
// Use an image with a button.
import [Link].*;
import [Link].*;
import [Link].*;
import [Link].*;
import [Link].*;
import [Link].*;
import [Link].*;
import [Link].*;
public class ButtonImageDemo extends Application {
Label response;
public static void main(String[] args) {
// Start the JavaFX application by calling launch().
launch(args);
}
// Override the start() method.
public void start(Stage myStage) {
// Give the stage a title.
[Link]("Use Images with Buttons");
// Use a FlowPane for the root node. In this case,
// vertical and horizontal gaps of 10.
FlowPane rootNode = new FlowPane(10, 10);
// Center the controls in the scene.
[Link]([Link]);
// Create a scene.
Scene myScene = new Scene(rootNode, 250, 450);
// Set the scene on the stage.
[Link](myScene);
// Create a label.
response = new Label("Push a Button");
// Create two image-based buttons.
Button btnHourglass = new Button("Hourglass",new ImageView("[Link]"));
Button btnAnalogClock = new Button("Analog Clock", new ImageView("[Link]"));
// Position the text under the image.
[Link]([Link]);
[Link]([Link]);
// Handle the action events for the hourglass button.
[Link](new EventHandler<ActionEvent>() {
public void handle(ActionEvent ae) {
[Link]("Hourglass Pressed");
}
});
// Handle the action events for the analog clock button.
[Link](new EventHandler<ActionEvent>() {
public void handle(ActionEvent ae) {
[Link]("Analog Clock Pressed");
}
});
// Add the label and buttons to the scene graph.
[Link]().addAll(btnHourglass, btnAnalogClock, response);
// Show the stage and its scene.
[Link]();
}
}
The output produced by this program is shown here:
If you want a button that contains only the image, pass a null string for the text when
constructing the button and then call setContentDisplay(), passing in the parameter
ContentDisplay.GRAPHIC_ONLY. For example, if you make these modifications to
theprevious program, the output will look like this:

ToggleButton

A useful variation on the push button is called the toggle button. A toggle button looks just
like a push button, but it acts differently because it has two states: pushed and released. That
is, when you press a toggle button, it stays pressed rather than popping back up as a regular
push button does. When you press the toggle button a second time, it releases(pops up).
Therefore, each time a toggle button is pushed, it toggles between these two states. In
JavaFX, a toggle button is encapsulated in the ToggleButton class. Like Button,
ToggleButton is also derived from ButtonBase. It implements the Toggle interface, which
defines functionality common to all types of two-state buttons.
ToggleButton defines three constructors. This is the one we will use:

ToggleButton(String str)

Here, str is the text displayed in the button. Another constructor allows you to include an
image. Like other buttons, a ToggleButton generates an action event when it is pressed.
Because ToggleButton defines a two-state control, it is commonly used to let the user select
an option. When the button is pressed, the option is selected. When the button is released, the
option is deselected. For this reason, a program usually needs to determine the toggle button’s
state. To do this, use the isSelected( ) method, shown here:

final boolean isSelected( )


It returns true if the button is pressed and false otherwise.

Here is a short program that demonstrates ToggleButton:


// Demonstrate a toggle button.
import [Link].*;
import [Link].*;
import [Link].*;
import [Link].*;
import [Link].*;
import [Link].*;
import [Link].*;
public class ToggleButtonDemo extends Application {
ToggleButton tbOnOff;
Label response;
public static void main(String[] args) {
// Start the JavaFX application by calling launch().
launch(args);
}
// Override the start() method.
public void start(Stage myStage) {
// Give the stage a title.
[Link]("Demonstrate a Toggle Button");
// Use a FlowPane for the root node. In this case,
// vertical and horizontal gaps of 10.
FlowPane rootNode = new FlowPane(10, 10);
// Center the controls in the scene.
[Link]([Link]);
// Create a scene.
Scene myScene = new Scene(rootNode, 220, 120);
// Set the scene on the stage.
[Link](myScene);
// Create a label.
response = new Label("Push the Button.");
// Create the toggle button.
tbOnOff = new ToggleButton("On/Off");
// Handle action events for the toggle button.
[Link](new EventHandler<ActionEvent>() {
public void handle(ActionEvent ae) {
if([Link]()) [Link]("Button is on.");
else [Link]("Button is off.");
}
});
// Add the label and buttons to the scene graph.
[Link]().addAll(tbOnOff, response);
// Show the stage and its scene.
[Link]();
}
}

RadioButton
Another type of button provided by JavaFX is the radio button. Radio buttons are a group of
mutually exclusive buttons, in which only one button can be selected at any time. To create a
radio button, we will use the following constructor:

RadioButton(String str)
Here, str is the label for the button. Like other buttons, when a RadioButton is used, an
action event is generated. Radio buttons must be configured into a group for their mutually
exclusive nature to be activated. Only one of the buttons in the group can be selected at any
time. For example, if a user presses a radio button in a group, any previously selected button
in that group is automatically deselected. A button group is created by the ToggleGroup
class, which is packaged in [Link]. ToggleGroup provides only a default
constructor. Radio buttons are added to the toggle group by calling the setToggleGroup( )
method, defined by ToggleButton, on the button. It is shown here:

final void setToggleGroup(ToggleGroup tg)

Here, tg is a reference to the toggle button group to which the button is added. After all radio
buttons have been added to the same group, their mutually exclusive behavior will be
enabled. In general, when radio buttons are used in a group, one of the buttons is selected
when the group is first displayed in the GUI. Here are two ways to do this.
First, you can call setSelected( ) on the button that you want to select. It is defined by
ToggleButton (which is a superclass of RadioButton). It is shown here:

final void setSelected(boolean state)


If state is true, the button is selected. Otherwise, it is deselected. Although the button is
selected, no action event is generated. A second way to initially select a radio button is to call
fire( ) on the button. It is shown here:

void fire( )

This method results in an action event being generated for the button if the button was
previously not selected.
There are a number of different ways to use radio buttons. Perhaps the simplest is to simply
respond to the action event that is generated when one is selected. The following program
shows an example of this approach. It uses radio buttons to allow the user to select a type of
transportation.
// A simple demonstration of Radio Buttons. This program responds to the action events
generated by a radio button selection. It also shows how to fire the button under program
control.
package application;
import [Link].*;
import [Link].*;
import [Link].*;
import [Link].*;
import [Link].*;
import [Link].*;
import [Link].*;
public class RadioButtonDemo extends Application {
Label response;
public static void main(String[] args) {
//Start the JavaFX application by calling launch().
launch(args);
}
//Override the start() method.
public void start(Stage myStage) {
//Give the stage a title.
[Link]("Demonstrate Radio Buttons");
//Use a FlowPane for the root node. In this case, vertical and horizontal gaps of 10.
FlowPane rootNode = new FlowPane(10, 10);
//Center the controls in the scene.
[Link]([Link]);
//Create a scene.
Scene myScene = new Scene(rootNode, 220, 120);
//Set the scene on the stage.
[Link](myScene);
//Create a label that will report the selection.
response = new Label("Select transport");
//Create the radio buttons.
RadioButton rbTrain = new RadioButton("Train");
RadioButton rbCar = new RadioButton("Car");
RadioButton rbPlane = new RadioButton("Airplane");
//Create a toggle group.
ToggleGroup tg = new ToggleGroup();
//Add each button to a toggle group.
[Link](tg);
[Link](tg);
[Link](tg);
//Handle action events for the radio buttons.
[Link]((ae)-> {
[Link]("Transport selected is train.");
});
[Link]((ae)-> {
[Link]("Transport selected is car.");
});
[Link]((ae)-> {
[Link]("Transport selected is airplane.");
});
//Fire the event for the first selection. This causes that radio button to be selected and an
action //event for that button to occur.
[Link]();
//Add the label and buttons to the scene graph.
[Link]().addAll(rbTrain, rbCar, rbPlane, response);
//Show the stage and its scene.
[Link]();
}
}
Sample output is shown here:

An Alternative Way to Handle Radio Buttons


Although handling events generated by radio buttons is often useful, sometimes it is more
appropriate to ignore those events and simply obtain the currently selected button when that
information is needed. This approach is demonstrated by the following program. It adds a
button called Confirm Transport Selection. When this button is pressed, the currently selected
radio button is obtained and then the selected transport is displayed in a label. When you try
the program, notice that changing the selected radio button does not cause the confirmed
transport to change until you press the Confirm Transport Selection button.

/* This radio button example demonstrates how the currently selected button in a group can
be obtained under program control, when it is needed, rather than responding to action or
change events. In this example, no events related to the radio buttons are handled. Instead, the
current selection is simply obtained when the Confirm Transport Selection push button is
pressed.*/
package application;
import [Link].*;
import [Link].*;
import [Link].*;
import [Link].*;
import [Link].*;
import [Link].*;
import [Link].*;
public class RadioButtonDemo2 extends Application {
Label response;
ToggleGroup tg;
public static void main(String[] args) {
// Start the JavaFX application by calling launch().
launch(args);
}
// Override the start() method.
public void start(Stage myStage) {
// Give the stage a title.
[Link]("Demonstrate Radio Buttons");
// Use a FlowPane for the root node. In this case, vertical and horizontal gaps of 10.
FlowPane rootNode = new FlowPane(10, 10);
// Center the controls in the scene.
[Link]([Link]);
// Create a scene.
Scene myScene = new Scene(rootNode, 500, 400);
// Set the scene on the stage.
[Link](myScene);
// Create two labels.
Label choose = new Label(" Select a Transport Type ");
response = new Label("No transport confirmed");
// Create push button used to confirm the selection.
Button btnConfirm = new Button("Confirm Transport Selection");
// Create the radio buttons.
RadioButton rbTrain = new RadioButton("Train");
RadioButton rbCar = new RadioButton("Car");
RadioButton rbPlane = new RadioButton("Airplane");
// Create a toggle group.
tg = new ToggleGroup();
// Add each button to a toggle group.
[Link](tg);
[Link](tg);
[Link](tg);
// Initially select one of the radio buttons.
[Link](true);
// Handle action events for the confirm button.
[Link]((ae)->{
// Get the radio button that is currently selected.
RadioButton rb = (RadioButton) [Link]();
// Display the selection.
[Link]([Link]() + " is confirmed.");
});
// Use a separator to better organize the layout.
Separator separator = new Separator();
[Link](500);
// Add the label and buttons to the scene graph.
[Link]().addAll(choose,rbTrain,rbCar,rbPlane,separator,btnConfirm,response);
// Show the stage and its scene.
[Link]();
}
}
The output from the program is shown here:
Inside the action event handler for the btnConfirm button, notice that the selected radio
button is obtained by the following line:
RadioButton rb = (RadioButton) [Link]();

Here, the getSelectedToggle( ) method (defined by ToggleGroup) obtains the current


selection for the toggle group (which, in this case, is a group of radio buttons). It is shown
here:

final Toggle getSelectedToggle( )

It returns a reference to the Toggle that is selected. In this case, the return value is cast to
RadioButton because this is the type of button in the group. The second thing to notice is the
use of a visual separator, which is created by this sequence:

Exercise 1
package example;
/
***************************************************************************
**
* (Traffic lights) Write a program that simulates a traffic light. The program *
* lets the user select one of three lights: red, yellow, or green. When a radio *
* button is selected, the light is turned on. Only one light can be on at a time *
*. No light is on when the program starts. *
***************************************************************************
******/
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];

public class TrafficLight extends Application {


public void start(Stage primaryStage) {
// Create a vbox
VBox paneForCircles = new VBox(5);
[Link]([Link]);

// Create three circles


Circle c1 = getCircle();
Circle c2 = getCircle();
Circle c3 = getCircle();
[Link]([Link]);

// Place circles in vbox


[Link]().addAll(c1, c2, c3);

// Create a rectangle
Rectangle rectangle = new Rectangle();
[Link]([Link]);
[Link](30);
[Link](100);
[Link]([Link]);
[Link](2);
StackPane stopSign = new StackPane(rectangle, paneForCircles);

// Create a hbox
HBox paneForRadioButtons = new HBox(5);
[Link]([Link]);

// Create radio buttons


RadioButton rbRed = new RadioButton("Red");
RadioButton rbYellow = new RadioButton("Yellow");
RadioButton rbGreen = new RadioButton("Green");

// Create a toggle group


ToggleGroup group = new ToggleGroup();
[Link](group);
[Link](group);
[Link](group);
[Link](true);
[Link]().addAll(rbRed, rbYellow, rbGreen);

// Create a border pane


BorderPane pane = new BorderPane();
[Link](stopSign);
[Link](paneForRadioButtons);

// Create and register handlers


[Link](e -> {
if ([Link]()) {
[Link]([Link]);
[Link]([Link]);
[Link]([Link]);
}
});

[Link](e -> {
if ([Link]()) {
[Link]([Link]);
[Link]([Link]);
[Link]([Link]);
}
});

[Link](e -> {
if ([Link]()) {
[Link]([Link]);
[Link]([Link]);
[Link]([Link]);
}
});

// Create a scene and place it in the stage


Scene scene = new Scene(pane, 200, 150);
[Link]("Traffic Light"); // Set the stage title
[Link](scene); // Place the scene in the stage
[Link](); // Display the stage
}

/** Return a circle */


private Circle getCircle() {
Circle c = new Circle(10);
[Link]([Link]);
[Link]([Link]);
return c;
}
}
CheckBox
The CheckBox class encapsulates the functionality of a check box. Its immediate superclass
is ButtonBase. CheckBox supports three states. The first two are checked or unchecked The
third state is indeterminate (also called undefined). It is typically used to indicate that the
state of the check box has not been set or that it is not relevant to a specific situation. If you
need the indeterminate state, you will need to explicitly enable it.
CheckBox defines two constructors. The first is the default constructor. The second lets you
specify a string that identifies the box. It is shown here:

CheckBox(String str)

It creates a check box that has the text specified by str as a label. As with other buttons, a
CheckBox generates an action event when it is selected. Here is a program that demonstrates
check boxes. It displays check boxes that let the user select various deployment options,
which are Web, Desktop, and Mobile. Each time a check box state changes, an action event is
generated and handled by displaying the new state (selected or cleared) and by displaying a
list of all selected boxes.
package application;

package application;

//Demonstrate Check Boxes.


import [Link].*;
import [Link].*;
import [Link].*;
import [Link].*;
import [Link].*;
import [Link].*;
import [Link].*;
public class CheckBoxDemo extends Application {
CheckBox cbWeb;
CheckBox cbDesktop;
CheckBox cbMobile;
Label response;
Label allTargets;
String targets = "";
public static void main(String[] args) {
//Start the JavaFX application by calling launch().
launch(args);
}
//Override the start() method.
public void start(Stage myStage) {
//Give the stage a title.
[Link]("Demonstrate Checkboxes");
//Use a FlowPane for the root node. In this case,
//vertical and horizontal gaps of 10.
FlowPane rootNode = new FlowPane(10, 10);
//Center the controls in the scene.
[Link]([Link]);
//Create a scene.
Scene myScene = new Scene(rootNode, 230, 140);
//Set the scene on the stage.
[Link](myScene);
Label heading = new Label("Select Subjects");
//Create a label that will report the state of the
//selected check box.
response = new Label(" No Subjects Selected ");
//Create a label that will report all targets selected.
allTargets = new Label("Target List: <none>");
//Create the check boxes.
cbWeb = new CheckBox("C++");
cbDesktop = new CheckBox("Java");
cbMobile = new CheckBox("Python");
//Handle action events for the check boxes.
[Link]((ae) ->{
if([Link]())
[Link](" C++ selected.");
else
[Link](" C++ cleared.");
showAll();
});
[Link]((ae)-> {
if([Link]())
[Link]("Java selected.");
else
[Link]("Java cleared.");
showAll();
});
[Link]((ae)-> {
if([Link]())
[Link](" Python selected.");
else
[Link]("Python cleared.");
showAll();
});
//Use a separator to better organize the layout.
Separator separator= new Separator();
[Link](200);
//Add controls to the scene graph.
[Link]().addAll(heading, separator, cbWeb, cbDesktop,
cbMobile, response, allTargets);
//Show the stage and its scene.
[Link]();
}
//Update and show the targets list.
void showAll() {
targets = "";
if([Link]()) targets = "C++ ";
if([Link]()) targets += "Java ";
if([Link]()) targets += "Python";
if([Link]("")) targets = "<none>";
[Link]("Target List: " + targets);
}
}

Sample output is shown here:

The operation of this program is straightforward. Each time a check box is changed, an action
command is generated. To determine if the box is checked or unchecked, the isSelected( )
method is called. As mentioned, by default, CheckBox implements two states: checked and
unchecked. If you want to add the indeterminate state, it must be explicitly enabled. To do
this, call setAllowIndeterminate( ), shown here:

final void setAllowIndeterminate(boolean enable)

In this case, if enable is true, the indeterminate state is enabled. Otherwise, it is disabled.
When the indeterminate state is enabled, the user can select between checked, unchecked, and
indeterminate. You can determine if a check box is in the indeterminate state by calling
isIndeterminate( ), shown here:

final boolean isIndeterminate( )


It returns true if the checkbox state is indeterminate and false otherwise. You can see the
effect of a three-state check box by modifying the preceding program. First, enable the
indeterminate state on the check boxes by calling setAllowIndeterminate( )on each check
box, as shown here:

[Link](true);
[Link](true);
[Link](true);

Next, handle the indeterminate state inside the action event handlers. For example, here isthe
modified handler for cbWeb:
[Link](new EventHandler<ActionEvent>() {
public void handle(ActionEvent ae) {
if([Link]())
[Link]("Web deployment indeterminate.");else if([Link]())
[Link]("Web deployment selected.");
else
[Link]("Web deployment cleared.");
showAll();
}
});
Now, all three states are tested. Update the other two handlers in the same way. After making
these changes, the indeterminate state can be selected, as this sample output shows:

Here, the Web check box is indeterminate.

ListView
Another commonly used control is the list view, which in JavaFX is encapsulated by
ListView. List views are controls that display a list of entries from which you can select one
or more. Because of their ability to make efficient use of limited screen space, list views are
popular alternatives to other types of selection controls.
ListView is a generic class that is declared like this:
class ListView<T>

Here, T specifies the type of entries stored in the list view. Often, these are entries of type
String, but other types are also allowed.
ListView defines two constructors. The first is the default constructor, which creates an
empty ListView. The second lets you specify the list of entries in the list. It is shown here:

ListView(ObservableList<T>list)

Here, list specifies a list of the items that will be displayed. It is an object of type
ObservableList, which defines a list of observable objects. It inherits [Link]. Thus, it
supports the standard collection methods. ObservableList is packaged in [Link].
Probably the easiest way to create an ObservableList for use in a ListView is to use the
factory method observableArrayList( ), which is a static method defined by the
FXCollections class (which is also packaged in [Link]). The version we will use
is shown here:

static <E> ObservableList<E> observableArrayList( E ... elements)

In this case, E specifies the type of elements, which are passed via elements. By default, a
ListView allows only one item in the list to be selected at any one time.
However, you can allow multiple selections by changing the selection mode. For now, we
will use the default, single-selection model. Although ListView provides a default size,
sometimes you will want to set the preferred height and/or width to best match your needs.
One way to do this is to call the setPrefHeight( ) and setPrefWidth( ) methods, shown here:

final void setPrefHeight(double height)


final void setPrefWidth(double width)
Alternatively, you can use a single call to set both dimensions at the same time by use of
setPrefSize( ), shown here:

void setPrefSize(double width, double height)

There are two basic ways in which you can use a ListView. First, you can ignore events
generated by the list and simply obtain the selection in the list when your program needs it.
Second, you can monitor the list for changes by registering a change listener. This lets you
respond each time the user changes a selection in the list. This is the approach used here. To
listen for change events, you must first obtain the selection model used by the ListView. This
is done by calling getSelectionModel( ) on the list. It is shown here:

final MultipleSelectionModel<T> getSelectionModel( )

It returns a reference to the model. MultipleSelectionModel is a class that defines the model
used for multiple selections, and it inherits SelectionModel. However, multiple selections are
allowed in a ListView only if multiple-selection mode is turned on. Using the model returned
by getSelectionModel( ), you will obtain a reference to the selected item property that
defines what takes place when an element in the list is selected. This is done by calling
selectedItemProperty( ), shown next:

final ReadOnlyObjectProperty<T> selectedItemProperty( )

You will add the change listener to this property.


The following example puts the preceding discussion into action. It creates a list view that
displays various types of transportation, allowing the user to select one. When one is chosen,
the selection is displayed.
// Demonstrate a list view.
import [Link].*;
import [Link].*;
import [Link].*;
import [Link].*;
import [Link].*;
import [Link].*;
import [Link].*;
import [Link].*;
public class ListViewDemo extends Application {
Label response;
public static void main(String[] args) {
// Start the JavaFX application by calling launch().
launch(args);
}
// Override the start() method.
public void start(Stage myStage) {
// Give the stage a title.
[Link]("ListView Demo");
// Use a FlowPane for the root node. In this case,
// vertical and horizontal gaps of 10.
FlowPane rootNode = new FlowPane(10, 10);
// Center the controls in the scene.
[Link]([Link]);
// Create a scene.
Scene myScene = new Scene(rootNode, 200, 120);
// Set the scene on the stage.
[Link](myScene);
// Create a label.
response = new Label("Select Transport Type");
// Create an ObservableList of entries for the list view.
ObservableList<String> transportTypes =
[Link]( "Train", "Car", "Airplane" );
// Create the list view.
ListView<String> lvTransport = new ListView<String>(transportTypes);
// Set the preferred height and width.
[Link](80, 80);
// Get the list view selection model.
MultipleSelectionModel<String> lvSelModel =[Link]();
// Use a change listener to respond to a change of selection within a list view.
[Link]().addListener(
new ChangeListener<String>() {
public void changed(ObservableValue<? extends String> changed, String oldVal, String
newVal) {
// Display the selection.
[Link]("Transport selected is " + newVal);
}
});
[Link]().addAll(lvTransport, response);
// Show the stage and its scene.
[Link]();
}
}
Sample output is shown here:

In the program, pay special attention to how the ListView is constructed. First, an
ObservableList is created by this line:
ObservableList<String> transportTypes =
[Link]( "Train", "Car", "Airplane" );
It uses the observableArrayList( ) method to create a list of strings. Then, the
ObservableList
is used to initialize a ListView, as shown here:
ListView<String> lvTransport = new ListView<String>(transportTypes);

The program then sets the preferred width and height of the [Link], notice how the
selection model is obtained for lvTransport:
MultipleSelectionModel<String> lvSelModel =[Link]();

As explained, ListView uses MultipleSelectionModel, even when only a single selection


isallowed. The selectedItemProperty( ) method is then called on the model and a
changelistener is registered to the returned item.

ListView Scrollbars
One very useful feature of ListView is that when the number of items in the list exceeds the
number that can be displayed within its dimensions, scrollbars are automatically added. For
example, if you change the declaration of transportTypes so that it includes "Bicycle"
and"Walking", as shown here:

ObservableList<String> transportTypes =
[Link]( "Train", "Car", "Airplane",
"Bicycle", "Walking" );
the lvTransport control now looks like the one shown here:

Enabling Multiple Selections


If you want to allow more than one item to be selected, you must explicitly request [Link] do
so, you must set the selection mode to [Link] by calling
setSelectionMode( ) on the ListView model. It is shown here:

final void setSelectionMode(SelectionMode mode)

In this case, mode must be either [Link] or


[Link] multiple-selection mode is enabled, you can obtain the list of
the selections twoways: as a list of selected indices or as a list of selected items. We will use
a list of selecteditems, but the procedure is similar when using a list of the indices of the
selected items.(Note, indexing of items in a ListView begins at zero.). To get a list of the
selected items, call getSelectedItems( ) on the selection model. It is shown here:

ObservableList<T> getSelectedItems( )

It returns an ObservableList of the items. Because ObservableList extends


[Link],you can access the items in the list just as you would any other List
[Link] experiment with multiple selections, you can modify the preceding program
asfollows. First, make lvTransport final so it can be accessed within the change event
[Link], add this line:

[Link]().setSelectionMode([Link]);
It enables multiple-selection mode for lvTransport. Finally, replace the change eventhandler
with the one shown here:

[Link]().addListener(
new ChangeListener<String>() {
public void changed(ObservableValue<? extends String> changed,String oldVal, String
newVal) {
String selItems = "";
ObservableList<String> selected =
[Link]().getSelectedItems();
// Display the selections.
for(int i=0; i < [Link](); i++)
selItems += "\n " + [Link](i);
[Link]("All transports selected: " + selItems);
}
});

After making these changes, the program will display all selected forms of transports, as
the following output shows:

Assignments

1. Write javafx program to simulate traffic signal


2. Write javafx program to create a registration form with different controls

ComboBox

A control related to the list view is the combo box, which is implemented in JavaFX by the
ComboBox class. A combo box displays one selection, but it will also display a drop-down
list that allows the user to select a different item. You can also allow the user to edit a
selection.

ComboBox inherits ComboBoxBase, which provides much of its functionality. Unlike the
ListView, which can allow multiple selections, ComboBox is designed for single-selection.
ComboBox is a generic class that is declared like this:

class ComboBox<T>

Here, T specifies the type of entries. Often, these are entries of type String, but other types
are also allowed.

ComboBox defines two constructors. The first is the default constructor, which creates an
empty ComboBox. The second lets you specify the list of entries. It is shown here:

ComboBox(ObservableList<T> list)

In this case, list specifies a list of the items that will be displayed. It is an object of type
ObservableList, which defines a list of observable objects. ObservableList inherits
[Link]. An easy way to create an ObservableList is to use the factory method
observableArrayList( ), which is a static method defined by the FXCollections class.

A ComboBox generates an action event when its selection changes. It will also generate a
change event. Alternatively, it is also possible to ignore events and simply obtain the current
selection when needed.

You can obtain the current selection by calling getValue( ), shown here:

final T getValue( )

If the value of a combo box has not yet been set (by the user or under program control), then
getValue( ) will return null. To set the value of a ComboBox under program control,

call setValue( ):

final void setValue(T newVal)

Here, newVal becomes the new value.

The following program demonstrates a combo box by reworking the previous list view
example. It handles the action event generated by the combo box.

// Demonstrate a combo box.


import [Link].*;
import [Link].*;
import [Link].*;
import [Link].*;
import [Link].*;
import [Link].*;
import [Link].*;
import [Link].*;
public class ComboBoxDemo extends Application {
ComboBox<String> cbTransport;
Label response;
public static void main(String[] args) {
// Start the JavaFX application by calling launch().
launch(args);
}
// Override the start() method.
public void start(Stage myStage) {
// Give the stage a title.
[Link]("ComboBox Demo");
// Use a FlowPane for the root node. In this case,
// vertical and horizontal gaps of 10.
FlowPane rootNode = new FlowPane(10, 10);
// Center the controls in the scene.
[Link]([Link]);
// Create a scene.
Scene myScene = new Scene(rootNode, 280, 120);
// Set the scene on the stage.
[Link](myScene);
// Create a label.
response = new Label();
// Create an ObservableList of entries for the combo box.
ObservableList<String> transportTypes =
[Link]( "Train", "Car", "Airplane" );
// Create a combo box.
cbTransport = new ComboBox<String>(transportTypes);
// Set the default value.
[Link]("Train");
// Set the response label to indicate the default selection.
[Link]("Selected Transport is " + [Link]());
// Listen for action events on the combo box.
[Link](ae-> {
[Link]("Selected Transport is " + [Link]());
});
// Add the label and combo box to the scene graph.
[Link]().addAll(cbTransport, response);
// Show the stage and its scene.
[Link]();
}
}
Sample output is shown here:
As mentioned, ComboBox can be configured to allow the user to edit a selection. Assuming
that it contains only entries of type String, it is easy to enable editing capabilities.

Simply call setEditable( ), shown here:

final void setEditable(boolean enable)

If enable is true, editing is enabled. Otherwise, it is disabled. To see the effects of editing, add
this line to the preceding program:

[Link](true);

After making this addition, you will be able to edit the selection.

TextField

TextField allows one line of text to be entered. Thus, it is useful for obtaining names, ID
strings, addresses, etc. Like all text controls, TextField inherits TextInputControl, which
defines much of its functionality.

TextField defines two constructors. The first is the default constructor, which creates an
empty text field that has the default size. The second lets you specify the initial contents of
the field. Here, we will use the default constructor.

Although the default size is sometimes adequate, often you will want to specify its size. This
is done by calling setPrefColumnCount( ), shown here:

final void setPrefColumnCount(int columns)

The columns value is used by TextField to determine its size.


You can set the text in a text field by calling setText( ). You can obtain the current text by
calling getText( ). In addition to these fundamental operations, TextField supports several
other capabilities that you might want to explore, such as cut, paste, and append.

You can also select a portion of the text under program control.

One especially useful TextField option is the ability to set a prompting message inside the
text field when the user attempts to use a blank field. To do this, call setPromptText( ), shown
here:

final void setPromptText(String str)

In this case, str is the string displayed in the text field when no text has been entered. It is
displayed using low-intensity (such as a gray tone).

When the user presses enter while inside a TextField, an action event is generated.

Although handling this event is often helpful, in some cases, your program will simply obtain
the text when it is needed, rather than handling action events. Both approaches are
demonstrated by the following program. It creates a text field that requests a search string.

When the user presses enter while the text field has input focus, or presses the Get Search
String button, the string is obtained and displayed. Notice that a prompting message is also
included.

// Demonstrate a text field.


import [Link].*;
import [Link].*;
import [Link].*;
import [Link].*;
import [Link].*;
import [Link].*;
import [Link].*;
public class TextFieldDemo extends Application {
TextField tf;
Label response;
public static void main(String[] args) {
// Start the JavaFX application by calling launch().
launch(args);
}
// Override the start() method.
public void start(Stage myStage) {
// Give the stage a title.
[Link]("Demonstrate a TextField");
// Use a FlowPane for the root node. In this case,
// vertical and horizontal gaps of 10.
FlowPane rootNode = new FlowPane(10, 10);
// Center the controls in the scene.
[Link]([Link]);
// Create a scene.
Scene myScene = new Scene(rootNode, 230, 140);
// Set the scene on the stage.
[Link](myScene);
// Create a label that will report the contents of the
// text field.
response = new Label("Search String: ");
// Create a button that gets the text.
Button btnGetText = new Button("Get Search String");
// Create a text field.
tf = new TextField();
// Set the prompt.
[Link]("Enter Search String");
// Set preferred column count.
[Link](15);
// Handle action events for the text field. Action
// events are generated when ENTER is pressed while
// the text field has input focus. In this case, the
// text in the field is obtained and displayed.
[Link](new EventHandler<ActionEvent>() {
public void handle(ActionEvent ae) {
[Link]("Search String: " + [Link]());
}
});
// Get text from the text field when the button is pressed
// and display it.
[Link](new EventHandler<ActionEvent>() {
public void handle(ActionEvent ae) {
[Link]("Search String: " + [Link]());
}
});
// Use a separator to better organize the layout.
Separator separator = new Separator();
[Link](180);
// Add controls to the scene graph.
[Link]().addAll(tf, btnGetText, separator, response);
// Show the stage and its scene.
[Link]();
}
}
Sample output is shown here:
Other text controls that you will want to examine include TextArea, which supports multiline
text, and PasswordField, which can be used to input passwords. You might also find
HTMLEditor helpful.

PasswordField
PasswordField is a Text field that masks entered characters (the characters that are entered
are not shown to the user). It allows the user to enter a single-line of unformatted text, hence
it does not allow multi-line input.

// Java program to create a passwordfield


import [Link];
import [Link];
import [Link].*;
import [Link].*;
import [Link];
import [Link];
import [Link];
import [Link];
public class Passwordfield extends Application
{

// launch the application


public void start(Stage s)
{
// set title for the stage
[Link]("creating Passwordfield");

// create a Passwordfield
PasswordField b =new PasswordField();

// create a tile pane


FlowPane r = new FlowPane();
// add password field
[Link]().add(b);
// create a scene
Scene sc =new Scene(r,200,200);
// set the scene
[Link](sc);
[Link]();
}
public static void main(String args[])
{
// launch the application
launch(args);
}
}

1. Output:

Exercise

Write a JavaFX program for login page with validation.

package application;
//LOGIN PAGE WITH VALIDATION
import [Link];
import [Link].*;
import [Link].*;
import [Link].*;
import [Link].*;
import [Link].*;
import [Link];
import [Link];
public class LoginpageValidation extends Application {
//Start the JavaFX application by calling launch().
public static void main(String[] args) {
launch(args);
}
//Override the start() method.
public void start(Stage myStage) {
//Give the stage a title.
[Link]("Demonstrate a Toggle Button");
FlowPane rootNode = new FlowPane(100,10);
[Link]([Link]);
Scene myScene = new Scene(rootNode, 300, 300);
[Link](myScene);
Label response=new Label("enter username and password");
TextField t= new TextField("username");
PasswordField p= new PasswordField();
Button btnlogin=new Button("LOGIN");
[Link]((ae)-> {
if([Link]().equals("NITTE") && [Link]().equals("NITTE123"))
[Link]("LOGIN SUCCESSFUL. WELCOME "+
[Link]());
else [Link]("LOGIN FAILED. INVALID USERNAME OR
PASSWORD");
});
[Link]().addAll(t,p,btnlogin, response);
[Link]();
}
}

ScrollPane

Sometimes, the contents of a control will exceed the amount of screen space that you want to
give to it. Here are two examples: A large image may not fit within reasonable boundaries, or
you might want to display text that is longer than will fit within a small window. Whatever
the reason, JavaFX makes it easy to provide scrolling capabilities to any node in a scene
graph. This is accomplished by wrapping the node in a ScrollPane. When a ScrollPane is
used, scrollbars are automatically implemented that scroll the contents of the wrapped node.
No further action is required on your part.

ScrollPane defines two constructors. The first is the default constructor. The second lets you
specify a node that you want to scroll. It is shown here:

ScrollPane(Node content)

In this case, content specifies the information to be scrolled. When using the default
constructor, you will add the node to be scrolled by calling setContent( ). It is shown here:

final void setContent(Node content)


After you have set the content, add the scroll pane to the scene graph. When displayed, the
content can be scrolled.

NOTE You can also use setContent( ) to change the content being scrolled by the scroll pane.
Thus, what is being scrolled can be changed during the execution of your program. Although
a default size is provided, as a general rule, you will want to set the dimensions of the
viewport. The viewport is the viewable area of a scroll pane. It is the area in which the
content being scrolled is displayed. Thus, the viewport displays the visible portion of the
content. The scrollbars scroll the content through the viewport. Thus, by moving a scrollbar,
you change what part of the content is visible.

You can set the viewport dimensions by using these two methods:

final void setPrefViewportHeight(double height)

final void setPrefViewportWidth(double width)

In its default behavior, a ScrollPane will dynamically add or remove a scrollbar as needed.
For example, if the component is taller than the viewport, a vertical scrollbar is added. If the
component will completely fit within the viewport, the scrollbars are removed. One nice
feature of ScrollPane is its ability to pan the contents by dragging the mouse.

By default, this feature is off. To turn it on, use setPannable( ), shown here:

final void setPannable(boolean enable)

If enable is true, then panning is allowed. Otherwise, it is disabled. You can set the position
of the scrollbars under program control using setHvalue( ) and setVvalue( ), shown here:

final void setHvalue(double newHval)

final void setVvalue(double newVval)

The new horizontal position is specified by newHval, and the new vertical position is
specified by newVval. By default, scrollbar positions start at zero.

ScrollPane supports various other options. For example, it is possible to set the minimum and
maximum scrollbar positions. You can also specify when and if the scrollbars are shown by
setting a scrollbar policy. The current position of the scrollbars can be obtained by calling

getHvalue( ) and getVvalue( ).

The following program demonstrates ScrollPane by using one to scroll the contents

of a multiline label. Notice that it also enables panning.

// Demonstrate a scroll pane.


// This program scrolls the contents of a multiline
// label, but any node can be scrolled.
import [Link].*;
import [Link].*;
import [Link].*;
import [Link].*;
import [Link].*;
import [Link].*;
import [Link].*;
public class ScrollPaneDemo extends Application {
ScrollPane scrlPane;
public static void main(String[] args) {
// Start the JavaFX application by calling launch().
launch(args);
}
// Override the start() method.
public void start(Stage myStage) {
// Give the stage a title.
[Link]("Demonstrate a ScrollPane");
// Use a FlowPane for the root node.
FlowPane rootNode = new FlowPane(10, 10);
// Center the controls in the scene.
[Link]([Link]);
// Create a scene.
Scene myScene = new Scene(rootNode, 200, 200);
// Set the scene on the stage.
[Link](myScene);
// Create a label that will be scrolled.
Label scrlLabel = new Label(
"A ScrollPane streamlines the process of\n" +
"adding scroll bars to a window whose\n" +
"contents exceed the window's dimensions.\n" +
"It also enables a control to fit in a\n" +
"smaller space than it otherwise would.\n" +
"As such, it often provides a superior\n" +
"approach over using individual scroll bars.");
// Create a scroll pane, setting scrlLabel as the content.
scrlPane = new ScrollPane(scrlLabel);
// Set the viewport width and height.
[Link](130);
[Link](80);
// Enable panning.
[Link](true);
// Create a reset label.
Button btnReset = new Button("Reset Scroll Bar Positions");
// Handle action events for the reset button.
[Link](new EventHandler<ActionEvent>() {
public void handle(ActionEvent ae) {
// Set the scroll bars to their zero position.
[Link](0);
[Link](0);
}
});
// Add the label to the scene graph.
[Link]().addAll(scrlPane, btnReset);
// Show the stage and its scene.
[Link]();
}
}
Sample output is shown here:

TreeView
TreeView presents a hierarchical view of data in a tree-like format. In this context, the term
hierarchical means some items are subordinate to others. For example, a tree is commonly
used to display the contents of a file system. In this case, the individual files are subordinate
to the directory that contains them. In a TreeView, branches can be expanded or collapsed on
demand by the user.
TreeView implements a conceptually simple, tree-based data structure. A tree begins with a
single root node that indicates the start of the tree. Under the root are one or more child nodes
There are two types of child nodes: leaf nodes (also called terminal nodes), which have no
children, and branch nodes, which form the root nodes of subtrees. A subtree is simply a tree
that is part of a larger tree. The sequence of nodes that leads from the root to specific node is
called a path.

One very useful feature of TreeView is that it automatically provides scrollbars when the size
of the tree exceeds the dimensions of the view. Although a fully collapsed tree might be quite
small, its expanded form may be quite large. By automatically adding scrollbars as needed,
TreeView lets you use a smaller space than would ordinarily be possible.
TreeView is a generic class that is defined like this:
class TreeView<T>
Here, T specifies the type of value held by an item in the tree. Often, this will be of type
String. TreeView defines two constructors. This is the one we will use:
TreeView(TreeItem<T> rootNode)
Here, rootNode specifies the root of the tree. Because all nodes descend from the root, it is
the only one that needs to be passed to TreeView.
The items that form the tree are objects of type TreeItem. At the outset, it is important to state
that TreeItem does not inherit Node. Thus, TreeItems are not general-purpose objects. They
can be used in a TreeView, but not as stand-alone controls. TreeItem is a generic class, as
shown here:
class TreeItem<T>
Here, T specifies the type of value held by the TreeItem.
Before you can use a TreeView, you must construct the tree that it will display. To do this,
you must first create the root. Next, add other nodes to that root. You do this by calling either
add( ) or addAll( ) on the list returned by getChildren( ). These other nodes can be leaf nodes
or subtrees. After the tree has been constructed, you create the TreeView by passing the root
node to its constructor.
You can handle selection events in the TreeView in a way similar to the way that you handle
them in a ListView, through the use of a change listener. To do so, first, obtain the selection
model by calling getSelectionModel( ). Then, call selectedItemProperty( ) to obtain the
property for the selected item. On that return value, call addListener( ) to add a change
listener. Each time a selection is made, a reference to the new selection will be passed to the
changed( ) handler as the new value. (See ListView for more details on handling change
events.)
You can obtain the value of a TreeItem by calling getValue( ). You can also follow the tree
path of an item in either the forward or backward direction. To obtain the parent, call
getParent( ). To obtain the children, call getChildren( ).
The following example shows how to build and use a TreeView. The tree presents a
hierarchy of food. The type of items stored in the tree are strings. The root is labeled Food.
Under it are three direct descendent nodes: Fruit, Vegetables, and Nuts. Under Fruit are three
child nodes: Apples, Pears, and Oranges. Under Apples are three leaf nodes: Fuji, Winesap,
and Jonathan. Each time a selection is made, the name of the item is displayed.
Also, the path from the root to the item is shown. This is done by the repeated use of
getParent( ).
// Demonstrate a TreeView
import [Link].*;
import [Link].*;
import [Link].*;
import [Link].*;
import [Link].*;
import [Link].*;
import [Link].*;
import [Link].*;
public class TreeViewDemo extends Application {
Label response;
public static void main(String[] args) {
// Start the JavaFX application by calling launch().
launch(args);
}
// Override the start() method.
public void start(Stage myStage) {
// Give the stage a title.
[Link]("Demonstrate a TreeView");
// Use a FlowPane for the root node. In this case,
// vertical and horizontal gaps of 10.
FlowPane rootNode = new FlowPane(10, 10);
// Center the controls in the scene.
[Link]([Link]);
// Create a scene.
Scene myScene = new Scene(rootNode, 310, 460);
// Set the scene on the stage.
[Link](myScene);
// Create a label that will report the state of the
// selected tree item.
response = new Label("No Selection");
// Create tree items, starting with the root.
TreeItem<String> tiRoot = new TreeItem<String>("Food");
// Now add subtrees, beginning with fruit.
TreeItem<String> tiFruit = new TreeItem<String>("Fruit");
// Construct the Apple subtree.
TreeItem<String> tiApples = new TreeItem<String>("Apples");
// Add child nodes to the Apple node.
[Link]().add(new TreeItem<String>("Fuji"));
[Link]().add(new TreeItem<String>("Winesap"));
[Link]().add(new TreeItem<String>("Jonathan"));
// Add varieties to the fruit node.
[Link]().add(tiApples);
[Link]().add(new TreeItem<String>("Pears"));
[Link]().add(new TreeItem<String>("Oranges"));
// Finally, add the fruit node to the root.
[Link]().add(tiFruit);
// Now, add vegetables subtree, using the same general process.
TreeItem<String> tiVegetables = new TreeItem<String>("Vegetables");
[Link]().add(new TreeItem<String>("Corn"));
[Link]().add(new TreeItem<String>("Peas"));
[Link]().add(new TreeItem<String>("Broccoli"));
[Link]().add(new TreeItem<String>("Beans"));
[Link]().add(tiVegetables);
// Likewise, add nuts subtree.
TreeItem<String> tiNuts = new TreeItem<String>("Nuts");
[Link]().add(new TreeItem<String>("Walnuts"));
[Link]().add(new TreeItem<String>("Peanuts"));
[Link]().add(new TreeItem<String>("Pecans"));
[Link]().add(tiNuts);
// Create tree view using the tree just created.
TreeView<String> tvFood = new TreeView<String>(tiRoot);
// Get the tree view selection model.
MultipleSelectionModel<TreeItem<String>> tvSelModel =
[Link]();
// Use a change listener to respond to a selection within a tree view
[Link]().addListener(
new ChangeListener<TreeItem<String>>() {
public void changed(
ObservableValue<? extends TreeItem<String>> changed,
TreeItem<String> oldVal, TreeItem<String> newVal) {

// Display the selection and its complete path from the root.
if(newVal != null) {
// Construct the entire path to the selected item.
String path = [Link]();
TreeItem<String> tmp = [Link]();
while(tmp != null) {
path = [Link]() + " -> " + path;
tmp = [Link]();
}
// Display the selection and the entire path.
[Link]("Selection is " + [Link]() +
"\nComplete path is " + path);
}
}
});
// Add controls to the scene graph.
[Link]().addAll(tvFood, response);
// Show the stage and its scene.
[Link]();
}
}
Sample output is shown here:

There are two things to pay special attention to in this program. First, notice how the tree is
constructed. First, the root node is created by this statement:
TreeItem<String> tiRoot = new TreeItem<String>("Food");

Next, the nodes under the root are constructed. These nodes consist of the root nodes of
subtrees: one for fruit, one for vegetables, and one for nuts. Next, the leaves are added to
these subtrees. However, one of these, the fruit subtree, consists of another subtree that
contains varieties of apples. The point here is that each branch in a tree leads either to a leaf
or to the root of a subtree. After all of the nodes have been constructed, the root nodes of each
subtree are added to the root node of the tree. This is done by calling add( ) on the root node.
For example, this is how the Nuts subtree is added to tiRoot.

[Link]().add(tiNuts);

The process is the same for adding any child node to its parent node.

The second thing to notice in the program is the way the path from the root to the selected
node is constructed within the change event handler. It is shown here:

String path = [Link]();

TreeItem<String> tmp = [Link]();

while(tmp != null) {

path = [Link]() + " -> " + path;

tmp = [Link]();

The code works like this: First, the value of the newly selected node is obtained. In this
example, the value will be a string, which is the node’s name. This string is assigned to the
path string. Then, a temporary variable of type TreeItem<String> is created and initialized to
refer to the parent of the newly selected node. If the newly selected node does not have a
parent, then tmp will be null. Otherwise, the loop is entered, within which each parent’s value
(which is its name in this case) is added to path. This process continues until the root node of
the tree (which has no parent) is found. Although the preceding shows the basic mechanism
required to handle a TreeView, it is important to point out that several customizations and
options are supported. TreeView is a powerful control that you will want to examine fully on
your own.
Introducing JavaFX Menus
Menu system.

The JavaFX menu system supports several key elements, including


• The menu bar, which is the main menu for an application.
• The standard menu, which can contain either items to be selected or other
menus(submenus).
• The context menu, which is often activated by right-clicking the mouse. Context
menus are also called popup menus.

Menu Basics
The JavaFX menu system is supported by a group of related classes packaged in
[Link].

To create a main menu for an application, you first need an instance of MenuBar. This class
is a container for menus. To the MenuBar you add instances of Menu. Each Menu object
defines a menu. That is, each Menu object contains one or more selectable items. The items
displayed by a Menu are objects of type MenuItem. Thus, a MenuItem defines a selection
that can be chosen by the user.

An Overview of MenuBar, Menu, and MenuItem


Before you can create a menu, you need to know some specifics about MenuBar, Menu, and
MenuItem. These form the minimum set of classes needed to construct a main menu for an
application. MenuItems are also used by context (i.e., popup) menus. Thus, these classes
form the foundation of the menu system.
MenuBar
MenuBar is essentially a container for menus. It is the control that supplies the main menu of
an application. Like all JavaFX controls, it inherits Node. Thus, it can be added to a scene
graph. MenuBar has only one constructor, which is the default constructor. Therefore,
initially, the menu bar will be empty, and you will need to populate it with menus prior to
use. As a general rule, an application has one and only one menu bar. MenuBar defines
several methods, but often you will use only one: getMenus( ). It returns a list of the menus
managed by the menu bar. It is to this list that you will add the menus that you create. The
getMenus( ) method is shown here:
final ObservableList<Menu> getMenus( )
A Menu instance is added to this list of menus by calling add( ). You can also use addAll( )
to add two or more Menu instances in a single call. The added menus are positioned in the
bar from left to right, in the order in which they are added. If you want to add a menu at a
specific location, then use this version of add( ):
void add(int idx, Menu menu)
Here, menu is added at the index specified by idx. Indexing begins at 0, with 0 being the left-
most menu.
In some cases, you might want to remove a menu that is no longer needed. You can do this
by calling remove( ) on the ObservableList returned by getMenus( ). Here are two of its
forms:
void remove(Menu menu)
void remove(int idx)
Here, menu is a reference to the menu to remove, and idx is the index of the menu to remove.
Indexing begins at zero. It is sometimes useful to obtain a count of the number of items in a
menu bar. To do this, call size( ) on the list returned by getMenus( ).
NOTE Recall that ObservableList implements the List collections interface, which gives you
access to all the methods defined by List.
Once a menu bar has been created and populated, it is added to the scene graph in the normal
way.
Menu

Menu encapsulates a menu, which is populated with MenuItems. As mentioned, Menu is


derived from MenuItem. This means that one Menu can be a selection in another Menu.

This enables one menu to be submenu of another. Menu defines three constructors.

Perhaps the most commonly used is shown here:

Menu(String name)

It creates a menu that has the name specified by name. You can specify an image along with
text with this constructor:

Menu(String name, Node image)

Here, image specifies the image that is displayed. In all cases, the menu is empty until menu
items are added to it. Finally, you don’t have to give a menu a name when it is constructed.

To create an unnamed menu, you can use the default constructor:

Menu( )
In this case, you can add a name and/or image after the fact by calling setText( ) or

setGraphic( ).

Each menu maintains a list of menu items that it contains. To add an item to the menu,add
items to this list. To do so, first call getItems( ), shown here:

final ObservableList<MenuItem> getItems( )

It returns the list of items currently associated with the menu. To this list, add menu items by
calling either add( ) or addAll( ). Among other actions, you can remove an item by calling
remove( ) and obtain the size of the list by calling size( ).

One other point: You can add a menu separator to the list of menu items, which is an object
of type SeparatorMenuItem. Separators help organize long menus by allowing you to group
related items together. A separator can also help set off an important item, such as the Exit
selection in a menu.

MenuItem

MenuItem encapsulates an element in a menu. This element can be either a selection linked to
some program action, such as Save or Close, or it can cause a submenu to be displayed.

MenuItem defines the following three constructors.

MenuItem( )

MenuItem(String name)

MenuItem(String name, Node image)

The first creates an empty menu item. The second lets you specify the name of the item, and
the third enables you to include an image.

A MenuItem generates an action event when selected. You can register an action event
handler for such an event by calling setOnAction( ), just as you did when handling button
events. It is shown again for your convenience:

final void setOnAction(EventHandler<ActionEvent> handler)

Here, handler specifies the event handler. You can fire an action event on a menu item by
calling fire( ).

MenuItem defines several methods. One that is often useful is setDisable( ), which you can
use to enable or disable a menu item. It is shown here:

final void setDisable(boolean disable)


If disable is true, the menu item is disabled and cannot be selected. If disable is false, the item
is enabled. Using setDisable( ), you can turn menu items on or off, depending on program
conditions.

Create a Main Menu

As a general rule, the most commonly used menu is the main menu. This is the menu defined
by the menu bar, and it is the menu that defines all (or nearly all) of the functionality of an
application. As you will see, JavaFX streamlines the process of creating and managing the
main menu. Here, you will see how to construct a simple main menu. Subsequent sections
will show various options.

Constructing the main menu requires several steps. First, create the MenuBar instance that
will hold the menus. Next, construct each menu that will be in the menu bar. In general, a
menu is constructed by first creating a Menu object and then adding MenuItems to it. After
the menus have been created, add them to the menu bar. Then, the menu bar, itself, must be
added to the scene graph. Finally, for each menu item, you must add an action event handler
that responds to the action event fired when a menu item is selected.

Here is a program that creates a simple menu bar that contains three menus. The first is a
standard File menu that contains Open, Close, Save, and Exit selections.

The second menu is called Options, and it contains two submenus called Colors and
Priority.

The third menu is called Help, and it has one item: About. When a menu item is selected, the
name of the selection is displayed in a label.

// Demonstrate Menus

import [Link].*;
import [Link].*;
import [Link].*;
import [Link].*;
import [Link].*;
import [Link].*;
import [Link].*;
public class MenuDemo extends Application {
Label response;
public static void main(String[] args) {
// Start the JavaFX application by calling launch().
launch(args);
}
// Override the start() method.
public void start(Stage myStage) {
// Give the stage a title.
[Link]("Demonstrate Menus");
// Use a BorderPane for the root node.
BorderPane rootNode = new BorderPane();
// Create a scene.
Scene myScene = new Scene(rootNode, 300, 300);
// Set the scene on the stage.
[Link](myScene);
// Create a label that will report the selection.
response = new Label("Menu Demo");
// Create the menu bar.
MenuBar mb = new MenuBar();
// Create the File menu.
Menu fileMenu = new Menu("File");
MenuItem open = new MenuItem("Open");
MenuItem close = new MenuItem("Close");
MenuItem save = new MenuItem("Save");
MenuItem exit = new MenuItem("Exit");
[Link]().addAll(open, close, save,new SeparatorMenuItem(), exit);
// Add File menu to the menu bar.
[Link]().add(fileMenu);
// Create the Options menu.
Menu optionsMenu = new Menu("Options");
// Create the Colors submenu.
Menu colorsMenu = new Menu("Colors");
MenuItem red = new MenuItem("Red");
MenuItem green = new MenuItem("Green");
MenuItem blue = new MenuItem("Blue");
[Link]().addAll(red, green, blue);
[Link]().add(colorsMenu);
// Create the Priority submenu.
Menu priorityMenu = new Menu("Priority");
MenuItem high = new MenuItem("High");
MenuItem low = new MenuItem("Low");
[Link]().addAll(high, low);
[Link]().add(priorityMenu);
// Add a separator.
[Link]().add(new SeparatorMenuItem());
// Create the Reset menu item.
MenuItem reset = new MenuItem("Reset");
[Link]().add(reset);
// Add Options menu to the menu bar.
[Link]().add(optionsMenu);
// Create the Help menu.
Menu helpMenu = new Menu("Help");
MenuItem about = new MenuItem("About");
[Link]().add(about);
// Add Help menu to the menu bar.
[Link]().add(helpMenu);
// Create one event handler that will handle menu action events.
EventHandler<ActionEvent> MEHandler =
new EventHandler<ActionEvent>() {
public void handle(ActionEvent ae) {
String name = ((MenuItem)[Link]()).getText();
// If Exit is chosen, the program is terminated.
if([Link]("Exit")) [Link]();
[Link]( name + " selected");
}
};
// Set action event handlers for the menu items.
[Link](MEHandler);
[Link](MEHandler);
[Link](MEHandler);
[Link](MEHandler);
[Link](MEHandler);
[Link](MEHandler);
[Link](MEHandler);
[Link](MEHandler);
[Link](MEHandler);
[Link](MEHandler);
[Link](MEHandler);

// Add the menu bar to the top of the border pane and
// the response label to the center position.
[Link](mb);
[Link](response);
// Show the stage and its scene.
[Link]();
}
}
Sample output is shown here:

MenuDemo uses a BorderPane instance for the root node. It defines a window that has five
areas: top,bottom, left, right, and center. The following methods set the node assigned to
these areas:

final void setTop(Node node)

final void setBottom(Node node)

final void setLeft(Node node)

final void setRight(Node node)

final void setCenter(Node node)


[Link]( )- The Platform class is defined by JavaFX and packaged in [Link].
Its exit( ) method causes the stop( ) life-cycle method to be called. [Link]( ) does not.

You might also like