Lesson 3: Presenting UI Objects in a Graphical Scene
The JavaFX Script Programming language is based on a scene graph. The scene graph is a tree-like data structure which defines a hierarchy of graphical objects in a scene. A single element in the scene graph is called a node. Each node has one parent except for the root node, which has no parent. Each node is either a leaf node or a branch. A leaf node has no children. A branch node has zero or more children.
JavaFX nodes handle different types of content such as UI components, shapes, text, images, and media. Nodes can be transformed and animated. You can also apply various effects to nodes.
In this lesson, you will create an application with three nodes: a circle, text, and an image, as shown below.
The application is created using the common profile API and can be run both on mobile devices and desktop platforms. If you want to learn more about the desktop platform API, refer to the JavaFX API. The screen captures provided in this lesson are taken from a desktop application.
JavaFX renders everything on a scene. You can think of the scene as a drawing surface for graphical content. The scene is a container that holds the scene graph nodes.
In any JavaFX GUI application, you create a scene and add nodes to it. You can modify the graphical scene by applying effects, transformations, and animation. The JavaFX runtime takes care of any changes in the graphical scene and performs any necessary repaints for you.
The javafx.scene.Node
class is the base class for the scene graph nodes. All other node classes, for example javafx.scene.shape.Circle
, inherit from the Node
class. For a complete list of instance variable and functions, see the API documentation for the Node
class.
The Node
class defines a local coordinate system in which the X coordinate increases to the right, and the Y coordinate increases downwards.
Nodes can be changed by applying transformations such as translation, rotation, scaling, and shearing. For example, a translation moves the origin of the node's coordinate system along either the X or Y axis, or both. To define the translation, set the values for the translateX
or translateY
variables or both.
JavaFX provides powerful support for effects available through the javafx.scene.effect
and javafx.scene.effect.light
packages. You can see some of the applied effects as well as transformations in Quick JavaFX GUI Overview. Note that the packages are available only in the desktop profile API.
Nodes can receive mouse and keyboard events. You can define functions to be notified when such events occur. For details, see Bringing Interactivity to GUI Elements.
Nodes can be grouped together and treated as a single entity. If you need to provide common behavior for several nodes, group them, and define the required behavior for the whole group. The javafx.scene.Group
class represents a group of nodes.
Now you will create a simple application as shown in Figure 1. The graphical scene of this application contains three nodes displayed below on separate windows. They are a shape object (a circle), text, and an image.
First you will add the nodes to the scene as separate nodes. Then you will group them and apply a transformation to the whole group.
Create an application window with the title "Nodes". For details, see Using Declarative Syntax. The following code creates the window.
Note: For the mobile version of the application, this step is required to define the scene.
import javafx.stage.Stage; |
A scene is declared using the Scene object literal. You will set the scene's width to 220 pixels, its height to 170 pixels, and give it a light blue background.
- Add import statements for the
javafx.scene.Scene
andjavafx.scene.paint.Color
classes. - Declare the
Scene
object literal. - Define the
fill
variable to set the background for the scene. - Define the
width
, andheight
attributes of theScene
object. This step is required only for the desktop version of the demo to specify the dimension of the application window. For details, see the Using Declarative Syntax lesson.
import javafx.stage.Stage; |
This code produces the following output.
You add a node to the scene by declaring this node as an element of the content
of the scene
. The content
variable of the scene
, which is a sequence of nodes, defines the graphical content of your application.
The first node is a circle. For details on the Circle
class, see Using Declarative Syntax. You will paint the boundary of the circle with yellow color.
- Import the
javafx.scene.shape.Circle
class. - Define the
content
variable of thescene
. - Add the
Circle
object literal to thecontent
variable.
import javafx.stage.Stage; |
The modified code gives you the following output.
- Add an import statement for the
javafx.scene.text.Text
class. - Add the
Text
object literal to thecontent
variable.
By default the text node will be placed at the point (0,0), which means that the left bottom point of the first character will be placed at (0,0). For this reason, the text is not visible in the application window when the code is compiled and run. In the next step, the default location will be changed so that text is visible.
import javafx.stage.Stage; |
Use square brackets to specify a sequence of nodes and commas to separate its elements.
You can change the default location by applying a rotation transformation. The rotation is specified by an anchor point and an angle. The node will be rotated clockwise around the anchor point by the specified angle.
To calculate the necessary values, look at Figure 5. If you take the point (10, 100) as an anchor point and draw a circle with a radius equal to the distance to the left bottom point of the text node, then part of this circle falls inside the circle node. Moving the text node along this circle by 33 degrees clockwise gives the result shown in Figure 5.
- Add an import statement for the
javafx.scene.transform.Transform
class. - Define the
transforms
variable of the text node to rotate the node by 33 degrees around the point (10,100).
import javafx.stage.Stage; |
The modified code provides the following output.
JavaFX applications can display images that are stored either on the Internet or in the local directory of your computer. The images are displayed using the ImageView
and Image
classes, and the url
variable which points to the location of the image. In case you use an image from the Internet, its url
variable which indicates the URL, is specified as a URI. In case you refer to an image from the local directory, its url
variable which indicates the path to the directory, is specified using the __DIR__
variable.
If you keep an image on the Internet, you need an Internet connection in order to display it in the application.
The example from this section uses an image of Duke from the Java Tutorials stored in the local directory. The example specifies the image using the __DIR__
variable. By default, it points to the current directory, so make sure that the image is located in the same directory as the application's compiled classes. To run the application on the mobile emulator, make sure that the image is packed into the application jar file along with the compiled classes.
By default, the left upper point of the image node is placed in the point (0,0). The dimensions of this image fit exactly into the area over the circle node.
For more information about the ImageView and Image classes, see the JavaFX API. For more details on the use of images, see Creating Animated Objects.
- Add import statements for the
Image
andImageView
classes from thejavafx.scene.image
package. - Add the
ImageView
object literal to thecontent
variable.
import javafx.stage.Stage; |
You created an application whose graphical scene contains three nodes. The output is shown in the following image.
Now add the nodes to a group and then add the group to the content
variable of the scene
.
- Add an import statement for the
javafx.scene.Group
class. - Modify the declaration of the
content
variable for thescene
so that it contains theGroup
object literal. - Move all nodes to the
content
variable of theGroup
. The code appears as follows.
import javafx.stage.Stage; |
Note the importance of the order in which you add objects to your group. This order defines how those objects are laid out. If you add the circle node last (after the text and image nodes), then the circle will be drawn over the two other objects. Because the circle has a fill color, these nodes will not be seen.
Finally, define the translation for the group of nodes to move the group to the center of the window as shown in the following code.
import javafx.stage.Stage; |
This modification shifts all three nodes simultaneously as displayed in the following image.
For your reference, here is the complete code of this example application.
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.Group;
import javafx.scene.shape.Circle;
import javafx.scene.paint.Color;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.text.Text;
import javafx.scene.transform.Transform;
Stage {
title: "Nodes"
scene: Scene {
width: 220
height: 170
fill: Color.LIGHTBLUE
content: Group {
translateX: 55
translateY: 10
content: [
Circle {
centerX: 50 centerY: 50 radius: 50
stroke: Color.YELLOW
fill: Color.WHITE
},
Text {
transforms: Transform.rotate(33, 10, 100)
content: "Duke"
},
ImageView {
image: Image {url: "{__DIR__}dukewave.png"}
}//ImageView
]//Content
}//Group
}//Scene
}//Stage
0 comments:
Post a Comment