Define constants and variables

Step 1: Define constants and variables

in the custom layout. You want the PlayingCardLayout class to be able to support three different layout arrangements, so define three constants to do the job:

public def VERTICAL_ARRANGEMENT:Integer = 0; public def HORIZONTAL_ ARRANGEMENT:Integer = 1; public def FAN_ARRANGEMENT:Integer = 2;

If you’re working through the code for PlayingCardLayoutA, add the FAN_ARRANGEMENT definition to your PlayingCardLayout.fx script under the existing VERTICAL_ARRANGEMENT and HORIZONTAL_ARRANGEMENT statements.

In the body of the PlayingCardLayout

package playingcard.ui; import javafx.scene.*; import javafx.scene.input.*;

public class PlayingCard extends CustomNode {

public var node:Node; override public var blocksMouse = true; override var children = Group {

content: bind node // Demonstrate the results of unmanaging a node onMousePressed: function(me:MouseEvent):Void {

managed = false; toFront();

} onMouseReleased: function(me:MouseEvent):Void {

managed = true;

Code Listing 1: PlayingCard.fx script—class definition for PlayingCard nodes

class definition is a public instance variable,

Code Listing 2: PlayingCardMain.fx script

arrangementStyle, whose definition includes

a replace trigger that automatically runs

/* PlayingCardMain.fx - to demonstrate PlayingCardLayout custom layout */

whenever the value of the variable changes:

package playingcard.ui;

public var arrangementStyle:Integer =

import javafx.stage.Stage;

VERTICAL_ARRANGEMENT on replace {

import javafx.scene.Scene;

preferredDirty(true);

import javafx.scene.image.*; import javafx.scene.layout.*;

requestLayout();

import playingcard.layout.PlayingCardLayout;

The variable is initialized with the

var firstPile:PlayingCard[] = for (i in [1..10])

VERTICAL_ARRANGEMENT constant, but PlayingCard {

node: ImageView {

the associated trigger is activated whenever

image: Image {

this variable value changes, setting the

url: "{__DIR__}images/{i}.png"

preferredDirty variable to true and calling

the requestLayout() function, another

Container class function. (As you’ll discover in subsequent steps, the preferredDirty

var secondPile:PlayingCard[] = for (i in [11..24])

PlayingCard {

variable acts as a flag throughout the

node: ImageView {

PlayingCardLayout code.)

image: Image {

The requestLayout() function tells the

url: "{__DIR__}images/{i}.png"

JavaFX runtime to make a layout pass run

before rendering the next scene. This trig-

gering mechanism, in conjunction with code in the doLayout() function, facilitates var thirdPile:PlayingCard[] = for (i in [25..54])

PlayingCard {

the rendering of the three layouts.

node: ImageView {

Note that the content variable is being

image: Image {

overridden, also through use of a replace url: "{__DIR__}images/{i}.png"

trigger. Each time the designated layout

(horizontal, vertical, or fan-shaped) changes,

the value of the variable changes.

Stage {

var sceneRef:Scene;

override var content on replace {

title: "PlayingCardLayout Example" scene: sceneRef = Scene {

preferredDirty = true;

width: 600

height: 400 content: [

All layout managers have a content HBox {

layoutX: 20

instance variable, inherited from the

layoutY: 20

Container class, whose purpose is to

spacing: 20

be assigned a sequence of nodes to be

content: [

PlayingCardLayout {

managed. The custom layout class uses this

arrangementStyle: PlayingCardLayout.VERTICAL_ARRANGEMENT

variable in the overridden doLayout() func-

content: firstPile

tion in a subsequent step.

}, PlayingCardLayout {

The calcPreferredSize() function is a

arrangementStyle: PlayingCardLayout.HORIZONTAL_ARRANGEMENT

helper function in PlayingCardLayout that

content: secondPile

calculates the preferred width and height

for the nodes it is processing for the calling PlayingCardLayout {

arrangementStyle: PlayingCardLayout.FAN_ARRANGEMENT

function and returns the dimensions that

content: thirdPile

will be required for the layout. When it’s

finished, the function sets the value of the ]

preferredDirty variable to false. If you’re

working through the example, add the fol-

lowing code to the calcPreferredSize() func- }

NOVEMBER/DECEMBER 2010 ORACLE.COM/ORACLEMAGAzINE NOVEMBER/DECEMBER 2010 ORACLE.COM/ORACLEMAGAzINE

documentation (download.oracle.com/ for the fan-shaped layout:

if (arrangementStyle == VERTICAL_

ARRANGEMENT) {

docs/cd/E17802_01/javafx/javafx/1.3/

docs/api) for complete details. else { // arrangementStyle == FAN_

for (node in getManaged(content)) {

• getNodePrefWidth() —determines the pre- ARRANGEMENT

layoutNode(node, 0,

ferred width of a node. preferredWidth = Math.sqrt(

indexof node * verticalOffset,

• getNodePrefHeight() —determines the pre- Math.pow(lastNodeWidth, 2) +

getNodePrefWidth(node),

ferred height of a node. Math.pow(lastNodeHeight, 2)) * 2;

getNodePrefHeight(node));

The online version of this article, at oracle preferredHeight = preferredWidth;

.com/technetwork/issue-archive/2010/ }

else if (arrangementStyle ==

10-nov/o60javafx-170536.html, concludes

with information on force recalculation And be sure to also change the ELSE for

HORIZONTAL_ARRANGEMENT) {

of the containing layout manager’s the arrangementStyle == HORIZONTAL_

for (node in getManaged(content)) {

width and height and how to modify the ARRANGEMENT statement to an ELSE IF for

layoutNode(node,

PlayingCardMain.fx script. proper syntax.

indexof node * horizontalOffset,

Step 2: Override the doLayout() function.

getNodePrefWidth(node),

CONCLUSION

The doLayout() function contains the rules

JavaFX includes several built-in layout man- for how nodes should be laid out. For the

getNodePrefHeight(node));

agers, but occasionally they don’t meet the example projects, the overridden doLayout()

requirements of an application. When this function iterates over the managed nodes

happens, consider creating your own, fol- and affects their sizes and positions.

else if (arrangementStyle ==

FAN_ARRANGEMENT) {

lowing the steps detailed in this article. 

def startAngle = (sizeof

override function doLayout():Void {

getManaged(content)) * -0.5 * fanAngle;

James L. Weaver has been a developer

if (preferredDirty) {

for (node in getManaged(content)) {

for more than 25 years. since 2000 he has

calcPreferredSize();

def rot = Rotate.rotate(

specialized in Java, object-oriented, and Web-

startAngle + (indexof node *

based technologies. He is the author of Pro

JavaFX Platform: Script, Desktop and Mobile When the JavaFX runtime calls the

fanAngle), 0,

RIA with Java Technology (Apress, 2009) and doLayout() function, it first determines

node.layoutBounds.height);

JavaFX Script: Dynamic Java Scripting for Rich if the arrangement of a layout manager’s

delete node.transforms;

Internet/Client-Side Applications (Apress, 2007). nodes should be re-evaluated by checking

insert rot into node.transforms;

var ph = getNodePrefHeight(node);

the value of the preferredDirty variable.

var pw = getNodePrefWidth(node);

NEXT STEpS

When preferredDirty is set to true,

layoutNode(node, ph, pw, pw, pw);

doLayout() calls the calcPreferredSize()

DOWNLOAD the sample code for

helper function to calculate the width and

this article

the height based on the arrangement style,

oracle.com/technetwork/issue-archive/ size, and number of cards to be arranged, 2010/10-nov/o60javafx-168643.zip

READ as well as the offset value. online-only article content Within the overridden doLayout() func- oracle.com/technetwork/issue-archive/ The calcPreferredSize() function returns

2010/10-nov/o60javafx-170536.html these values for the card stack in question

tion are several convenience functions (from

Container) for managing nodes:

READ more technical articles about JavaFX

oracle.com/technetwork/java/ to false, so that when the processing control index-141532.html#javafx (sequence) of nodes being managed

and then resets the preferredDirty variable

• getManaged() —returns the group

returns back to the calling function (in this “Building GUI Applications With JavaFX” by the container—that is, those nodes download.oracle.com/javafx/1.3/tutorials/ui case, doLayout()), the returned values will be

whose managed instance variable is true.

“Learning the JavaFX Script programming

handled by the appropriate IF statement in

By default, all nodes are created with the

Language”

the function. In other words, the playing card

download.oracle.com/javafx/1.3/tutorials/core will be positioned properly within its desig-

default value, but if you want a node to

be exempt from the policies of the layout

LEARN how to get started with NetBeans IDE

nated arrangement (horizontal, vertical, or 6.9 for JavaFX manager, set its managed variable to false. download.oracle.com/javafx/1.3/getstarted fan-shaped).

• layoutNode() —sets the position of a node

more about the JavaFX 1.3.1 ApI

and attempts to resize it. This is an over-

download.oracle.com/docs/cd/E17802_01/

DOWNLOAD the JavaFX 1.3.1 ApI and

loaded function that has several variations

javafx/javafx/1.3/docs/api

NetBeans IDE 6.9.1 VISIT the JavaFX resources site

from which you can choose, depending on your needs. Check the JavaFX API reference oracle.com/technetwork/java/javafx/overview

javafx.com/downloads/all.jsp

ORACLE MAGAzINE NOVEMBER/DECEMBER 2010

Create cutting edge reports with the complete set of

tools from Altova ®

Experience how the Altova MissionKit ® , the integrated suite of XML, database, and data integration tools, lets you display and analyze data through enhanced chart and report generation.

Report generation is finally easy – and affordable – with Altova MissionKit reporting tools:

StyleVision ® – stylesheet and report design tool • Consolidated reporting based on XML,

database and/or XBRL data • Dynamic data selection and rendering • HTML, Microsoft Word, PDF, and e-Form report creation

New in XMLSpy ® – advanced XML editor Version 2011:

• Instant creation of charts to analyze XML data

Ground-breaking

• One-click export of charts to XSLT, XQuery, or image files

support for chart creation

MapForce ® – any-to-any data mapping tool

• Integration with StyleVision for rendering attractive reports • Report generation for virtually any data format:

XML, databases, EDI, flat files, Excel 2007+, and more

Download a 30 day free trial!