What a scene and a scene graph are in a JavaFX application
About different rendering modes of a scene graph
How to set the cursor for a scene
How to determine the focus owner in a scene
How to use the Platform and HostServices classes
What Is a Scene?
A scene represents the visual contents of a stage. The Scene class in the javafx.scene package represents a scene in a JavaFX program. A Scene object is attached to, at the most, one stage at a time. If an already attached scene is attached to another stage, it is first detached from the previous stage. A stage can have, at the most, one scene attached to it at any time.
A scene always has a root node . If the root node is resizable, for example, a Region or a Control, it tracks the size of the scene. That is, if the scene is resized, the resizable root node resizes itself to fill the entire scene. Based on the policy of a root node, the scene graph may be laid out again when the size of the scene changes.
A Group is a nonresizable Parent node that can be set as the root node of a scene. If a Group is the root node of a scene, the content of the scene graph is clipped by the size of the scene. If the scene is resized, the scene graph is not laid out again.
Commonly Used Properties of the Scene Class
Type | Name | Property and Description |
---|---|---|
ObjectProperty<Cursor> | cursor | It defines the mouse cursor for the Scene. |
ObjectProperty<Paint> | fill | It defines the background fill of the Scene. |
ReadOnlyObjectProperty<Node> | focusOwner | It defines the node in the Scene that owns the focus. |
ReadOnlyDoubleProperty | height | It defines the height of the Scene. |
ObjectProperty<Parent> | root | It defines the root Node of the scene graph. |
ReadOnlyDoubleProperty | width | It defines the width of the Scene. |
ReadOnlyObjectProperty<Window> | window | It defines the Window for the Scene. |
ReadOnlyDoubleProperty | x | It defines the horizontal location of the Scene on the Window. |
ReadOnlyDoubleProperty | y | It defines the vertical location of the Scene on the window. |
Graphics Rendering Modes
Immediate mode API
Retained mode API
In the immediate mode API, the application is responsible for issuing the drawing commands when a frame is needed on the screen. The graphics are drawn directly on the screen. When the screen needs to be repainted, the application needs to reissue the drawing commands to the screen. Java2D is an example of the immediate mode graphics-rendering API.
In the retained mode API, the application creates and attaches drawing objects to a graph. The graphics library, not the application code, retains the graph in memory. Graphics are rendered on the screen by the graphics library when needed. The application is responsible only for creating the graphic objects—the “what” part; the graphics library is responsible for storing and rendering the graphics—the “when” and “how” parts. The retained mode rendering API relieves developers of writing the logic for rendering the graphics. For example, adding or removing part of a graphic from a screen is simple by adding or removing a graphic object from the graph using high-level APIs; the graphics library takes care of the rest. In comparison to the immediate mode, the retained mode API uses more memory, as the graph is stored in memory. The JavaFX scene graph uses retained mode APIs.
You might think that using the immediate mode API would always be faster than using the retained mode API because the former renders graphics directly on the screen. However, using the retained mode API opens the door for optimizations by the class library that is not possible in the immediate mode where every developer is in charge of writing the logic as to what and when it should be rendered.
Setting the Cursor for a Scene
The Focus Owner in a Scene
Only one node in a scene can be the focus owner. The focusOwner property of the Scene class tracks the Node class that has the focus. Note that the focusOwner property is read-only. If you want a specific node in a scene to be the focus owner, you need to call the requestFocus() method of the Node class.
You can use the getFocusOwner() method of the Scene class to get the reference of the node having the focus in the scene. A scene may not have a focus owner, and in that case, the getFocusOwner() method returns null. For example, a scene does not have a focus owner when it is created but is not attached to a window.
Methods of the Platform Class
Method | Description |
---|---|
void exit() | It terminates a JavaFX application. |
boolean isFxApplicationThread() | It returns true if the calling thread is the JavaFX Application Thread. Otherwise, it returns false. |
boolean isImplicitExit() | It returns the value of the implicit implicitExit attribute of the application. If it returns true, it means that the application will terminate after the last window is closed. Otherwise, you need to call the exit() method of this class to terminate the application. |
boolean isSupported(ConditionalFeature feature) | It returns true if the specified conditional feature is supported by the platform. Otherwise, it returns false. |
void runLater(Runnable runnable) | It executes the specified Runnable on the JavaFX Application Thread. The timing of the execution is not specified. The method posts the Runnable to an event queue and returns immediately. If multiple Runnables are posted using this method, they are executed in the order they are submitted to the queue. |
void setImplicitExit(boolean value) | It sets the implicitExit attribute to the specified value. |
Understanding the Platform Class
The Platform class in the javafx.application package is a utility class used to support platform-related functionalities. It consists of all static methods, which are listed in Table 5-2.
The runLater() method is used to submit a Runnable task to an event queue, so it is executed on the JavaFX Application Thread. JavaFX allows developers to execute some of the code only on the JavaFX Application Thread. Listing 5-1 creates a task in the init() method that is called on the JavaFX Launcher Thread. It uses the Platform.runLater() method to submit the task to be executed on the JavaFX Application Thread later.
Use the Platform.runLater() method to execute a task that is created on a thread other than the JavaFX Application Thread but needs to run on the JavaFX Application Thread.
Using the Platform.runLater() Method
Constants Defined in the ConditionalFeature Enum
Enum Constant | Description |
---|---|
EFFECT | Indicates the availability of filter effects, for example, reflection, shadow, etc. |
INPUT_METHOD | Indicates the availability of the text input method. |
SCENE3D | Indicates the availability of 3D features. |
SHAPE_CLIP | Indicates the availability of clipping of a node against an arbitrary shape. |
TRANSPARENT_WINDOW | Indicates the availability of the full window transparency. |
Knowing the Host Environment
String getCodeBase()
String getDocumentBase()
String resolveURI(String base, String relativeURI)
void showDocument(String uri)
The getCodeBase() method returns the code base uniform resource identifier (URI) of the application. In a stand-alone mode, it returns the URI of the directory that contains the JAR file used to launch the application. If the application is launched using a class file, it returns an empty string.
The getDocumentBase() method returns the URI of the document base. It returns the URI of the current directory for the application launched in stand-alone mode.
The resolveURI() method resolves the specified relative URI with respect to the specified base URI and returns the resolved URI.
Knowing the Details of the Host Environment for a JavaFX Application
Summary
A scene represents the visual contents of a stage. The Scene class in the javafx.scene package represents a scene in a JavaFX program. A Scene object is attached to at the most one stage at a time. If an already attached scene is attached to another stage, it is first detached from the previous stage. A stage can have at the most one scene attached to it at any time.
A scene contains a scene graph that consists of visual nodes. In this sense, a scene acts as a container for a scene graph. A scene graph is a tree data structure whose elements are known as nodes. Nodes in a scene graph form a parent-child hierarchical relationship. A node in a scene graph is an instance of the javafx.scene.Node class. A node can be a branch node or a leaf node. A branch node can have children nodes, whereas a leaf node cannot. The first node in a scene graph is called the root node. The root node can have children nodes; however, it never has a parent node.
An instance of the javafx.scene.Cursor class represents a mouse cursor. The Cursor class contains many constants, for example, HAND, CLOSED_HAND, DEFAULT, TEXT, NONE, WAIT, for standard mouse cursors. You can set a cursor for the scene using the setCursor() method of the Scene class.
Only one node in a scene can be the focus owner. The read-only focusOwner property of the Scene class tracks the node that has the focus. If you want a specific node in a scene to be the focus owner, you need to call the requestFocus() method of the Node class. Each scene may have a focus owner. For example, if you open two windows, you will have two scenes, and you may have two focus owners. However, only one of the two focus owners can have the focus at a time. The focus owner of the active window will have the focus. To check if the focus owner node also has the focus, you need to use the focused property of the Node class.
The Platform class in the javafx.application package is a utility class used to support platform-related functionalities. It contains methods for terminating the application, checking if the code being executed is executed on the JavaFX Application Thread, and so on.
The HostServices class in the javafx.application package provides services related to the launching environment (desktop for this book) hosting the JavaFX application. You cannot create an instance of the HostServices class directly. The getHostServices() method of the Application class returns an instance of the HostServices class.
The next chapter will discuss nodes in detail.