What's New in JavaFX 1.2 Technology: New Layouts and Effects

   
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:

  1. Stage infrastructure enhancements, including Screen class and Alerts.
  2. Direct referencing of Java arrays.
  3. Mixin inheritance and the elimination of multiple inheritance.
  4. The BoxBlur effect -- nearly 20 effects are available now!
  5. Improved asynchronous processing model, extended by API classes that require it -- for example, HttpRequest.
  6. The Math and Properties classes.
  7. New layout classes and improved support for creating custom layouts.
  8. More skinnable or CSS-styled controls, and improved support for creating custom UI controls -- for example, the Behavior class.
  9. RSS and Atom feed support.
  10. Charting support, including 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
 

New Layouts in JavaFX 1.2 Technology

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.

The ClipView Layout

A 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.

 
A <code>ClipView</code> Example
Figure 1 - A ClipView Example
 
 

By 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.

Table 1. The ClipView Variables
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.

The Flow Layout

The 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.

 
A <code>Flow</code> Example
Figure 2 - A Flow Example
 
 

If 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.

 
A <code>Flow</code> Example That Controls Position and Spacing
Figure 3 - A Flow Example That Controls Position and Spacing
 
 

Table 2 contains a description of the instance variables in the Flow layout class.

 

Table 2. The Flow Variables
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.

Table 3. The HPos Variables
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
 
Table 4. The VPos Variables
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
 

The Stack Layout

As 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.

 
A <code>Stack</code> Example
Figure 4 - A Stack Example
 
 

Notice 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.

 
A <code>Stack</code> Example, Left-Aligned With <code>HPos.LEFT</code>
Figure 5 - A Stack Example, Left-Aligned With HPos.LEFT
 
 

That 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.

Table 5. The Stack Variables
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.

The Tile Layout

The 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.

 
A <code>Tile</code> Example
Figure 6 - A Tile Example
 
 

As 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.

Table 6. The Tile Variables
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.

The BoxBlur Effect

The 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?

 
A <code>BoxBlur</code> Example
Figure 7 - A BoxBlur Example
 
 

Did 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.

 
The <code>BoxBlur</code> Effect With <code>SepiaTone</code> Effect Added to the <code>input</code> Variable
Figure 8 - The BoxBlur Effect With SepiaTone Effect Added to the input Variable
 
 

Table 7 contains a description of the instance variables in the BoxBlur class.

Table 7. The BoxBlur Variables
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
 

Conclusion

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.

For More Information

 
Rate This Article
 
 
Discussion

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.