Articles
JavaFX Technologies
|
|
| By Chris Wright and James L. (Jim) Weaver, May 2009 |
|
This article is the first in a series of articles that will introduce new features in the recent release of JavaFX 1.2 technology and show you how to use them. But first, here's a top 10 list of many of the new features:
Screen class and Alerts.BoxBlur effect -- nearly 20 effects are available now!HttpRequest.Math and Properties classes.Behavior class.Area, Bar, Bubble, Line, Pie, Scatter, and X/Y.This article introduces the new layout classes in the javafx.scene.layout package -- ClipView, Flow, Stack, and Tile -- and the new effect, BoxBlur, introduced in JavaFX 1.2 technology. Future articles will cover other new features in this release.
|
Contents
|
|
| - | New Layouts in JavaFX 1.2 Technology |
| - | The ClipView Layout |
| - | The Flow Layout |
| - | The Stack Layout |
| - | The Tile Layout |
| - | The BoxBlur Effect |
| - | Conclusion |
| - | For More Information |
In addition to the current layout classes of VBox and HBox, the JavaFX team has added a number of new classes to give you more flexibility when positioning nodes. The code examples that follow demonstrate the use of the four new layout classes in version 1.2: ClipView, Flow, Stack, and Tile.
Note: This article uses the term node to mean an item in a scene graph, which is any subclass of the Node class in the javafx.scene package. As you may know, a Group extends Node, so any reference to a node in this article can mean a single node or multiple nodes.
ClipView LayoutA ClipView is a window through which a user can see a node. Take, for instance, a Google map of your location. Zoomed in, the window is too small for the user to see the entire state, country, or world. The map is clipped, or cropped, to a specific rectangular viewing area, and the user can pan across the map to view the parts of the geographical area. This is exactly what the ClipView does.
In the following code example, the node in view -- in this case, an image -- is 460 pixels wide by 460 pixels high, and the size of the ClipView is 400 pixels by 400 pixels, smaller than the node. The variable named pannable is assigned the value of true, which allows the user to drag the mouse to view the entire image.
/*
* ClipViewExampleMain.fx -
*
* Developed 2009 by Chris Wright (chris.wright at veriana.com)
*/
package mypackage;
import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.scene.image.*;
import javafx.scene.layout.ClipView;
import javafx.scene.paint.Color;
Stage {
scene: Scene {
fill: Color.LIGHTGRAY
width: 400
height: 400
content: [
ClipView {
pannable: true
width: 300
height: 300
node: ImageView {
image: Image {
url: "{__DIR__}images/NodeHierarchy.png"
}
}
}
]
}
}
The preceding code yields the image in Figure 1.

ClipView ExampleBy clicking on and dragging the image inside the ClipView, the end user can pan across the image. Two other useful variables associated with ClipView are clipX and clipY. These variables define the location within the node that corresponds with the upper left corner of the ClipView. For example, if you assign the value of 10 to both clipX and clipY, the visible portion of the node starts at (10, 10).
Table 1 contains the commonly used instance variables of the ClipView class, as well as a description of each.
|
Name
|
Type
|
Description
|
|---|---|---|
clipX |
Number |
The horizontal location within the node that corresponds with the left side of the viewing area.
|
clipY |
Number |
The vertical location within the node that corresponds with top of the viewing area.
|
node |
Node |
The node that will be displayed within the viewing area.
|
pannable |
Boolean |
If the value is set to
true, the end user will be able to use the mouse to pan the node within the viewing area. |
Now that you've been introduced to the ClipView layout, let's move on to the new Flow layout class.
Flow LayoutThe Flow layout class provides a linear view to the nodes within its content. The Flow itself has a width and height, and you can control the orientation of the Flow by using the Boolean variable vertical. Take, for instance, a horizontal Flow. The nodes within the content of the Flow are laid out from left to right. When a row reaches the width of the Flow, the next node wraps below the previous row. On the other hand, if the Flow is vertical, nodes are laid out from top to bottom. When a column reaches the height of the Flow, a new column is created to the right of the previous column.
You should note some other variables: hgap and vgap, hpos and vpos, and nodeHPos and nodeVPos. The variables nodeHPos and nodeVPos will be discussed in the context of the Stack layout in the next section.
In a horizontal Flow layout, hgap defines the horizontal space between each node, and vgap determines the vertical space between each row. Likewise, if the Flow is vertical, vgap controls the vertical space between each node, and hgap defines the horizontal space between each column.
The instance variables hpos and vpos control where the content will appear relative to the bounds of the Flow container. Take a look at the following two code examples to understand how to use this class and its variables.
/*
* FlowExampleMain.fx -
*
* Developed 2009 by Chris Wright (chris.wright at veriana.com)
*/
package mypackage;
import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.scene.layout.Flow;
import javafx.scene.shape.Rectangle;
import javafx.scene.shape.Circle;
import javafx.scene.paint.Color;
Stage {
scene: Scene {
width: 200
content: Flow {
width: 200
content: [
Circle {
radius: 15
fill: Color.YELLOW
},
Rectangle {
width: 50
height: 50
fill: Color.BLUE
},
Circle {
radius: 30
fill: Color.GREEN
},
Rectangle {
width: 25
height: 50
fill: Color.RED
},
Circle {
radius: 20
fill: Color.PURPLE
},
Rectangle {
width: 50
height: 25
fill: Color.ORANGE
}
]
}
}
}
The preceding code yields the output shown in Figure 2.

Flow ExampleIf a node breaks past the Flow's width of 200, it will then wrap beneath the previous node or nodes. Use the hpos and vpos instance variables to control the position of the nodes within the Flow. For example, to right-align the nodes inside Flow, assign hpos the value HPos.RIGHT, as shown in the following code example. You will find additional information about the values available to hpos and vpos later in this section. The following code also demonstrates the use of the hgap and vgap variables, which were discussed previously.
import javafx.geometry.*;
import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.scene.layout.Flow;
import javafx.scene.shape.Rectangle;
import javafx.scene.shape.Circle;
import javafx.scene.paint.Color;
Stage {
scene: Scene {
width: 200
content: Flow {
hpos: HPos.RIGHT
hgap: 5
vgap: 5
width: 200
content: [
Circle {
radius: 15
fill: Color.YELLOW
},
Rectangle {
width: 50
height: 50
fill: Color.BLUE
},
Circle {
radius: 30
fill: Color.GREEN
},
Rectangle {
width: 25
height: 50
fill: Color.RED
},
Circle {
radius: 20
fill: Color.PURPLE
},
Rectangle {
width: 50
height: 25
fill: Color.ORANGE
}
]
}
}
}
Running this code yields the output shown in Figure 3.

Flow Example That Controls Position and SpacingTable 2 contains a description of the instance variables in the Flow layout class.
|
Name
|
Type
|
Description
|
|---|---|---|
hgap |
Number |
The amount of horizontal gap or space between each node. If the
Flow is horizontal, this is the space between each node in the row. If the Flow is vertical, this is the space between each column of nodes. |
vgap |
Number |
The amount of vertical gap or space between each node. If the
Flow is vertical, this is the space between each node in the row. If the Flow is horizontal, this is the space between each row of nodes. |
hpos |
HPos |
The horizontal position of each flow within the container's width. See Table 3.
|
vpos |
VPos |
The vertical position of each flow within the container's height. See Table 4.
|
nodeHPos |
HPos |
The horizontal position of each node within its own layout space. See Table 3.
|
nodeVPos |
VPos |
The vertical position of each node within its own layout space. See Table 4.
|
vertical |
Boolean |
Defines the orientation of the
Flow. If vertical is set to true, nodes in the Flow will run top to bottom before wrapping to the next column. |
Although the HPos and VPos classes are from the Java programming language and are not currently included in the JavaFX API, they provide useful functionality for users. Table 3 and Table 4 outline the different variables available to you when you use the hpos, vpos, nodeHPos, and nodeVPos variables mentioned earlier.
|
Name
|
Description
|
|---|---|
LEADING |
Leading horizontal position: left in left-to-right context, and right in a right-to-left context
|
LEFT |
Left horizontal position
|
CENTER |
Centered horizontal position
|
RIGHT |
Right horizontal position
|
TRAILING |
Trailing horizontal position: right in left-to-right context and left in a right-to-left context
|
|
Name
|
Description
|
|---|---|
PAGE_START |
Position at the start of the page: top in a top-to-bottom context, and bottom in a bottom-to-top context
|
TOP |
Top vertical position
|
CENTER |
Centered vertical position
|
BASELINE |
Baseline vertical position
|
BOTTOM |
Bottom vertical position
|
PAGE_END |
Position at the end of the page: bottom in a top-to-bottom context, and top in a bottom-to-top context
|
Stack LayoutAs with the previous examples, the class name describes itself very well. A Stack layout consists of a stack of nodes, ordered from back to front, with alignment using the nodeVPos and nodeHPos variables mentioned previously. With the Stack, you can easily center nodes within a container.
The StackExampleMain code following this paragraph also illustrates how easy it is to align text atop other nodes. This layout can be useful for many applications, such as creating your own custom buttons and controls. The following code sample demonstrates how to use this new class:
/*
* StackExampleMain.fx
*
* Developed 2009 by Chris Wright (chris.wright at veriana.com)
*/
package mypackage;
import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.scene.layout.Stack;
import javafx.scene.shape.Rectangle;
import javafx.scene.shape.Circle;
import javafx.scene.paint.Color;
import javafx.scene.text.*;
Stage {
scene: Scene {
content: Stack {
content: [
Rectangle {
width: 300
height: 300
fill: Color.BLACK
},
Circle {
radius: 75
fill: Color.RED
},
Text {
content: "This is a Stack example"
textOrigin: TextOrigin.TOP
font: Font.font("Arial", FontWeight.BOLD, 16)
fill: Color.WHITE
}
]
}
}
}
The preceding code yields the image in Figure 4.

Stack ExampleNotice that the default behavior is for the nodes to be centered on top of each other, because the default nodeHPos value of the Stack layout is HPos.CENTERING. However, you can use the other values available to nodeHPos and nodeVPos to manipulate the layout according to your desires. For example, left-aligning the nodes within the stack is as simple as changing the value of nodeHPos to HPos.LEFT, as shown here:
import javafx.scene.Scene;
. . .
. . .
import javafx.geometry.*;
Stage {
scene: Scene {
content: Stack {
nodeHPos: HPos.LEFT
content: [
Rectangle {
. . .
. . .
}
]
}
}
}
The previous code yields the image in Figure 5.

Stack Example, Left-Aligned With HPos.LEFTThat was easy! Vertical positioning uses the same procedure, except that it requires the nodeVPos instance variable instead of nodeHPos. For more options on positioning with nodeVPos and nodeHPos, refer to Table 3 and Table 4.
Table 5 contains a description of the instance variables in the Stack class.
|
Name
|
Type
|
Description
|
|---|---|---|
nodeHPos |
HPos |
The horizontal position of each node within the stack's width. See Table 3.
|
nodeVPos |
VPos |
The vertical position of each node within the stack's height. See Table 4.
|
Content |
Node[] |
In order of sequence, the
Nodes that will be rendered in the Stack. |
Now, let's look at the final new layout class featured in this article: Tile.
Tile LayoutThe title says it all. Think of a tile floor, which typically consists of square tiles arranged in columns and rows. This is precisely the Tile class. The Tile layout allows you to specify the number of rows and columns, as well as the horizontal and vertical gap between each tile ( hgap and vgap).
You can include other variables: tileWidth and tileHeight, vertical, and hpos and vpos. The tileWidth and tileHeight variables control the size of each tile. The vertical attribute changes the direction in which the content of Tile is laid out. For instance, if vertical is set to true, the nodes will be laid out from top to bottom, then wrap to the next column. If vertical is set to false, the nodes will be laid out from left to right, then wrap to the next row.
The following code example shows these variables in action:
/*
* TileExampleMain.fx -
*
* Developed 2009 by Chris Wright (chris.wright at veriana.com)
*/
package mypackage;
import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.scene.image.*;
import javafx.scene.layout.Tile;
import javafx.scene.paint.Color;
Stage {
scene: Scene {
fill: Color.BLACK
width: 300
height: 300
content: Tile {
columns: 6
rows: 3
hgap: 3
vgap: 3
content: [
ImageView {
image: Image {
url: "{__DIR__}images/JFX_1.png"
}
},
ImageView {
image: Image {
url: "{__DIR__}images/JFX_2.png"
}
},
. . . .
//Some code has been omitted.
. . . .
ImageView {
image: Image {
url: "{__DIR__}images/JFX_17.png"
}
},
ImageView {
image: Image {
url: "{__DIR__}images/JFX_18.png"
}
}
]
}
}
}
The preceding code yields the image in Figure 6.

Tile ExampleAs you saw in the previous example, the use of hgap and vgap -- the space between each tile and between each row and column -- accentuates the effect of tiles. Similar to the Flow layout class, the Tile class also uses the nodeHPos and nodeVPos instance variables. These variables are used to position each node within the space of its own tile, using the same values available from HPos and VPos.
Table 6 contains a description of the instance variables in the Tile class.
|
Name
|
Type
|
Description
|
|---|---|---|
columns |
Integer |
The number of columns used to lay out the tiles.
|
hgap |
Number |
The horizontal gap between each tile in the row. If the orientation of the
Tile layout is vertical, this is the amount of space between each column. |
hpos |
HPos |
The horizontal position of the rows within the width of the container. See Table 3.
|
nodeHPos |
HPos |
The horizontal position of each node within its tile. See Table 3.
|
nodeVPos |
VPos |
The vertical position of each node within its tile. See Table 4.
|
rows |
Integer |
The number of rows used to lay out the tiles.
|
tileHeight |
Number |
The height of each tile.
|
tileWidth |
Number |
The width of each tile.
|
vertical |
Boolean |
The orientation of the
Tile layout. If vertical is set to true, tiles will be laid out top to bottom, then wrap to the next column. Otherwise, tiles will be laid out in a horizontal direction. |
vgap |
Number |
The vertical gap between each tile in the column. If the orientation of the
Tile layout is horizontal, this is the amount of space between each row. |
vpos |
VPos |
The vertical position of the columns within the container's height. See Table 4.
|
Each new layout class has unique features that make positioning nodes easier and fun! Now that you have a better idea of how to use the new classes in javafx.scene.layout, let's move on to the final example in this article.
BoxBlur EffectThe javafx.scene.effects package now has 22 classes, with BoxBlur as the most recent addition. When you add BoxBlur to a node, the color in each pixel of the node is spread to the left, right, top, and bottom based on the width and height of the blur that you specify. For instance, if you set the width and height values both to 5, a single pixel's color will be blurred five pixels to the left, right, top, and bottom. The iterations variable controls the number of times that the blur effect is added to the node. The higher the iterations number, the more smooth, or blurry, the node will become. Here is an example of the code:
/*
* BoxBlurExampleMain.fx -
*
* Developed 2009 by Chris Wright (chris.wright at veriana.com)
*/
package mypackage;
import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.scene.effect.BoxBlur;
import javafx.scene.image.*;
Stage {
scene: Scene {
content: ImageView {
effect: BoxBlur {
width: 20
height: 20
iterations: 1
}
image: Image {
url: "{__DIR__}images/who_is_it.jpg"
}
}
}
}
The preceding code yields the image shown in Figure 7. Can you name that person?

BoxBlur ExampleDid you get it? Here's your virtual pat on the back!
As with other effects, the input variable has been included in JavaFX 1.2 technology. This allows you to link or "chain" effects together on a single node. For instance, the following code adds the SepiaTone effect to Barack Obama's image, and it lightens the width and height values on the blur to 10.
import javafx.scene.Scene;
. . .
. . .
import javafx.scene.effect.SepiaTone;
Stage {
scene: Scene {
content: ImageView {
effect: BoxBlur {
width: 10
height: 10
iterations: 1
input: SepiaTone {
level: 1.0
}
}
image: Image {
url: "{__DIR__}images/celeb.jpg"
}
}
}
}
Running this code yields the output shown in Figure 8.

BoxBlur Effect With SepiaTone Effect Added to the input VariableTable 7 contains a description of the instance variables in the BoxBlur class.
|
Name
|
Type
|
Description
|
|---|---|---|
height |
Number |
The vertical dimension of the blur effect
|
input |
Effect |
The input for this
Effect |
iterations |
Integer |
The number of times to iterate the blur effect to improve its quality or smoothness -- that is, to create more of a blur
|
width |
Number |
The horizontal dimension of the blur effect
|
This article concentrated on the fun yet convenient layout and effect classes included in JavaFX 1.2 technology. And with the addition of the HPos and VPos classes, these new classes are definitely a step in the right direction for the JavaFX platform. One final note: the HBox and VBox layout classes carried over from version 1.1 have been expanded to include HPos and VPos instance variables so that the user can better position content.
We welcome your participation in our community. Please keep your comments civil and on point. You can optionally provide your email address to be notified of replies—your information is not used for any other purpose. By submitting a comment, you agree to these Terms of Use.