Understanding the Hello Earthrise Program (Getting a Jump Start in JavaFX) Part 1

Now that you’ve run the application, let’s walk through the program listing together. The code for the Hello Earthrise application is shown in Listing 1-1.

Listing 1-1. The HelloEarthRiseMain.java Program

Now that you’ve seen the code, let’s take a look at its constructs and concepts in detail.

Declarative Code That Defines the User Interface

One of the most exciting features of JavaFX is its ability to express a graphical user interface (GUI) using simple, consistent, and powerful builder classes.

■ Note As we show a little later, JavaFX supports data binding, which is characterized by binding the value of a property (such as the height of a rectangle) to an expression. Data binding is a major enabler of using declarative code.

In this example, some of the program is declarative in that it contains a large expression. This expression begins by defining a Scene object with the SceneBuilder class. Nested within that are properties of the Scene object, such as its width and height. A Scene also has a property named root that holds the graphical elements that are displayed in the Scene, in this case a Group instance that contains an ImageView instance (which displays an image) and a Group instance. Nested within the latter Group is a Text instance (which is a graphical element, usually called a graphical node, or simply node).

The build() method of builder classes creates an instance (also known as an object) of the Java class it is responsible for building.

Using the Stage Class

A Stage contains the user interface of a JavaFX app, whether it is deployed on the desktop, within a browser, or on other devices. On the desktop, for example, a Stage has its own top-level window, which typically includes a border and title bar. In the browser the Stage doesn’t have a window, but is rendered as an applet within a rectangular area of the browser.

The Stage class has a set of properties and methods. Some of these properties and methods, as shown in the following code snippet from the listing, are as follows.

• A scene that contains the graphical nodes in the user interface

• A title that appears in the title bar of the window (when deployed on the desktop)

• The visibility of the Stage

Using the Scene Class

As mentioned previously, a Scene holds the graphical elements that are displayed on the Stage. Every element in a Scene is a graphical node, which is any class that extends the javafx.scene.Node. Take another look at the declarative code that creates the Scene in our example program:

Notice that the root property of the Scene contains an instance of the Group class, created by the build() method of the GroupBuilder class. The root property may contain any subclass of javafx.scene.Node, and typically contains a subclass that is capable of holding its own set of Node instances. Take a look at the JavaFX API documentation that we showed you how to access in the "Accessing the JavaFX SDK API" section earlier and check out the Node class to see the properties and methods available to any graphical node. Also, take a look at the ImageView class in the javafx.scene.image package and the Group class in the javafx.scene package. In both cases, they inherit from the Node class.

■ Tip We can’t emphasize enough the importance of having the JavaFX API documentation handy while reading this topic. As classes, variables, and functions are mentioned, it’s often a good idea to look at the documentation to get more information. In addition, this habit helps you become more familiar with what is available to you in the API.

Displaying Images

As shown in the following code, displaying an image entails using an ImageView instance in conjunction with an Image instance.

The Image instance identifies the image resource and loads it from the URL assigned to its URL variable. Both of these classes are located in the javafx.scene.image package.

Working with Graphical Nodes as a Group

One powerful graphical feature of JavaFX is the ability to create scene graphs, which consist of a tree of graphical nodes. You can then assign values to properties of a Group located in the hierarchy, and the nodes contained in the Group will be affected. In our current example from Listing 1-1, we’re using a Group to contain a Text node and to clip a specific rectangular region within the Group so that the text doesn’t appear on the moon or the Earth as it animates upward. Here’s the relevant code snippet:

Notice that the Group is located 50 pixels to the right and 180 pixels down, from where it would have been located by default. This is due to the values assigned to the layoutX and layoutY variables of the Group instance. Because this Group is contained directly by the Scene, its upper-left corner’s location is 50 pixels to the right and 180 pixels down from the upper-left corner of the Scene. Take a look at Figure 1-5 to see this example illustrated as you read the rest of the explanation.

Figure 1-5. The Scene, Group, Text, and clip illustrated

A Group instance contains instances of Node subclasses by assigning a collection of them to itself via the children() method. In the previous code snippet, the Group contains a Text instance that has a value assigned to its layoutY property. Because this Text is contained by a Group, it assumes the two-dimensional space (also called the co-ordinate space) of the Group, with the origin of the Text node (0,0) coincident with the top-left corner of the Group. Assigning a value of 100 to the layoutY property causes the Text to be located 100 pixels down from the top of the Group, which is just below the bottom of the clip region, thus causing it to be out of view until the animation begins. Because a value isn’t assigned to the layoutX variable, its value is 0 (the default).

The layoutX and layoutY properties of the Group just described are examples of our earlier statement that nodes contained in a Group will be affected by values assigned to properties of the Group. Another example is setting the opacity property of a Group instance to 0.5, which causes all of the nodes contained in that Group to become translucent. If the JavaFX API documentation is handy, look at the properties available in the javafx.scene.Group class. Then look at the properties available in the javafx.scene.Node class properties, which is where you’ll find the layoutX, layoutY, and opacity variables that are inherited by the Group class.