Newsletter sign-up
View all newsletters

Enterprise Java Newsletter
Stay up to date on the latest tutorials and Java community news posted on JavaWorld

Sponsored Links

Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs

Jump into JavaFX, Part 1: JavaFX Preview SDK

Experience JavaFX with NetBeans 6.1 and Project Nile

  • Print
  • Feedback

Page 6 of 6

If you don't specify a package name, it defaults to result.

Figure 12. If you don't specify a package name, it defaults to result. (Click to enlarge.)

The resulting shapes.fx source file specifies a class that describes a custom node (a developer-defined component that can be plugged into a user interface). Later in this series, you'll learn about custom nodes and how to create them. For now, check out Listing 3 to see the JavaFX Script equivalent of the previous XML-based SVG content. (You'll also learn how to interact with this script later in this series.)

Listing 3. shapes.fx (slightly reformatted for display)

/*
 * Generated by JavaFX svg2fx tool.
 * Created on Wed Sep 10 20:56:16 CDT 2008.
 */
package result;

import javafx.scene.*;
import javafx.scene.geometry.*;
import javafx.scene.image.*;
import javafx.scene.paint.*;
import javafx.scene.text.*;
import javafx.scene.effect.*;
import javafx.scene.transform.*;

public class shapes extends CustomNode {
    public attribute _root: Group;
    public attribute g3423: Group;
    public attribute layer1: Group;
    public attribute linearGradient3213: LinearGradient;
    public attribute linearGradient3217: LinearGradient;
    public attribute path3411: SVGPath;
    public attribute path3413: SVGPath;
    public attribute path3419: SVGPath;
    public attribute path3425: SVGPath;
    public attribute path3427: SVGPath;
    public attribute path3429: SVGPath;
    public attribute path3431: SVGPath;
    public attribute path3433: SVGPath;
    public attribute path3435: SVGPath;
    public attribute rect3415: Rectangle;
    public attribute rect3417: Rectangle;
    public attribute stop3219: Stop;
    public attribute stop3221: Stop;
    public attribute stop3223: Stop;

    protected function initializeCustomNode() : Void {

        _root = Group {
                content: [
                    defs4=metadata7=layer1=Group {
                            content: [
                            path3411=SVGPath {
                                    content: "M 505.71429,316.64789
                                              A 167.14285,167.14285 0 1 1 171.42859,316.64789
                                              A 167.14285,167.14285 0 1 1 505.71429,316.64789 z"
                                    fill: Color.rgb(0xff, 0x00, 0x00, 1.0)
                                    id: "path3411"
                                    opacity: 0.77490779
                                    strokeWidth: 1.0
                                },
                            path3413=SVGPath {
                                    content: "M 565.71429,505.21933 A 110,110 0 1 1 345.71429,505.21933
                                              A 110,110 0 1
                                              1 565.71429,505.21933 z"
                                    fill: Color.rgb(0x00, 0x00, 0xff, 1.0)
                                    id: "path3413"
                                    opacity: 0.77490778999999999
                                    strokeWidth: 1.0
                                },
                            rect3415=Rectangle {
                                    fill: Color.rgb(0xff, 0xff, 0x00, 1.0)
                                    fillRule: FillRule.EVEN_ODD
                                    height: 268.57144
                                    id: "rect3415"
                                    stroke: Color.rgb(0x00, 0x00, 0x00, 1.0)
                                    strokeLineCap: StrokeLineCap.BUTT
                                    strokeLineJoin: StrokeLineJoin.MITER
                                    strokeWidth: 1.0
                                    width: 268.57144
                                    x: 62.857143
                                    y: 680.9336
                                },
                            rect3417=Rectangle {
                                    fill: Color.rgb(0x00, 0x80, 0x00, 1.0)
                                    fillRule: FillRule.EVEN_ODD
                                    height: 242.85716
                                    id: "rect3417"
                                    stroke: Color.rgb(0x00, 0x00, 0x00, 1.0)
                                    strokeLineCap: StrokeLineCap.BUTT
                                    strokeLineJoin: StrokeLineJoin.MITER
                                    strokeWidth: 1.0
                                    width: 242.85716
                                    x: 262.85715
                                    y: 786.64795
                                },
                            path3419=SVGPath {
                                    content: "M 131.42857,89.505038
                                              L 85.578727,95.206748
                                              L 64.282683,136.20914
                                              L 44.691654,94.365272
                                              L -0.88477702,86.781966
                                              L 32.857145,55.219325
                                              L 25.985405,9.5301921
                                              L 66.430089,31.867274
                                              L 107.75955,11.213143
                                              L 99.013819,56.580861
                                              L 131.42857,89.505038 z"
                                    fill: Color.rgb(0xff, 0x00, 0xff, 1.0)
                                    id: "path3419"
                                    opacity: 0.77490778999999999
                                    stroke: Color.rgb(0xff, 0x00, 0xff, 1.0)
                                    strokeWidth: 1.0
                                },
                            g3423=Group {
                                    content: [
                                    path3435=SVGPath {
                                            content: "M 691.14384,421.1672
                                                      L 695.27678,420.53923
                                                      L 695.27678,426.02081
                                                      L 691.14384,426.61619
                                                      L 691.14384,421.1672 z"
                                            fill: Color.rgb(0xe9, 0xe9, 0xff, 1.0)
                                            fillRule: FillRule.EVEN_ODD
                                            id: "path3435"
                                            opacity: 0.77490779
                                            strokeLineCap: StrokeLineCap.BUTT
                                            strokeLineJoin: StrokeLineJoin.ROUND
                                            strokeWidth: 1.0
                                        },
                                    path3425=SVGPath {
                                            content: "M 568.57142,178.0765
                                                      L 568.57142,196.13906
                                                      L 691.14384,426.61619
                                                      L 691.14384,421.1672
                                                      L 568.57142,178.0765 z"
                                            fill: Color.rgb(0x35, 0x35, 0x64, 1.0)
                                            fillRule: FillRule.EVEN_ODD
                                            id: "path3425"
                                            opacity: 0.77490779
                                            strokeLineCap: StrokeLineCap.BUTT
                                            strokeLineJoin: StrokeLineJoin.ROUND
                                            strokeWidth: 1.0
                                        },
                                    path3427=SVGPath {
                                            content: "M 568.57142,178.0765
                                                      L 580.00001,171.07941
                                                      L 695.27678,420.53923
                                                      L 691.14384,421.1672
                                                      L 568.57142,178.0765 z"
                                            fill: Color.rgb(0x4d, 0x4d, 0x9f, 1.0)
                                            fillRule: FillRule.EVEN_ODD
                                            id: "path3427"
                                            opacity: 0.77490779
                                            strokeLineCap: StrokeLineCap.BUTT
                                            strokeLineJoin: StrokeLineJoin.ROUND
                                            strokeWidth: 1.0
                                        },
                                    path3433=SVGPath {
                                            content: "M 568.57142,196.13906
                                                      L 580.00001,189.50505
                                                      L 695.27678,426.02081
                                                      L 691.14384,426.61619
                                                      L 568.57142,196.13906 z"
                                            fill: Color.rgb(0xaf, 0xaf, 0xde, 1.0)
                                            fillRule: FillRule.EVEN_ODD
                                            id: "path3433"
                                            opacity: 0.77490779
                                            strokeLineCap: StrokeLineCap.BUTT
                                            strokeLineJoin: StrokeLineJoin.ROUND
                                            strokeWidth: 1.0
                                        },
                                    path3431=SVGPath {
                                            content: "M 580.00001,171.07941
                                                      L 580.00001,189.50505
                                                      L 695.27678,426.02081
                                                      L 695.27678,420.53923
                                                      L 580.00001,171.07941 z"
                                            fill: Color.rgb(0xd7, 0xd7, 0xff, 1.0)
                                            fillRule: FillRule.EVEN_ODD
                                            id: "path3431"
                                            opacity: 0.77490779
                                            strokeLineCap: StrokeLineCap.BUTT
                                            strokeLineJoin: StrokeLineJoin.ROUND
                                            strokeWidth: 1.0
                                        },
                                    path3429=SVGPath {
                                            content: "M 568.57142,178.0765
                                                      L 580.00001,171.07941
                                                      L 580.00001,189.50505
                                                      L 568.57142,196.13906
                                                      L 568.57142,178.0765 z"
                                            fill: Color.rgb(0x86, 0x86, 0xbf, 1.0)
                                            fillRule: FillRule.EVEN_ODD
                                            id: "path3429"
                                            opacity: 0.77490779
                                            strokeLineCap: StrokeLineCap.BUTT
                                            strokeLineJoin: StrokeLineJoin.ROUND
                                            strokeWidth: 1.0
                                        }
                                    ]
                                }
                            ]
                        }
                ]
            }
    }

    protected function create() : Node {
        if (_root == null) {
            initializeCustomNode();
        }
        return _root;
    }
}
shapes{}

A rendering challenge, and a workaround

To view the original SVG graphic described by shapes.fx, we could introduce a script that places this custom node in a window's content area. Because you're just learning about JavaFX Script and JavaFX APIs, however, it seems more appropriate to use the JavaFX Graphics Viewer for this task. Unfortunately, the tool displays the following error information when asked to render shapes.fx:

file:/c:/prj/jijfx/part1/code/shapes/shapes.fx from StringInputBuffer:41: cannot find symbol
symbol  : variable defs4
location: class result.shapes
compiler.err.cant.resolve.location
file:/c:/prj/jijfx/part1/code/shapes/shapes.fx from StringInputBuffer:41: cannot find symbol
symbol  : variable metadata7
location: class result.shapes
compiler.err.cant.resolve.location
file:/c:/prj/jijfx/part1/code/shapes/shapes.fx from StringInputBuffer:59: cannot find symbol
symbol  : variable fillRule
location: class javafx.scene.geometry.Rectangle
compiler.err.cant.resolve.location
file:/c:/prj/jijfx/part1/code/shapes/shapes.fx from StringInputBuffer:72: cannot find symbol
symbol  : variable fillRule
location: class javafx.scene.geometry.Rectangle
compiler.err.cant.resolve.location
file:/c:/prj/jijfx/part1/code/shapes/shapes.fx from StringInputBuffer:40: incompatible types
found   : Integer
required: javafx.scene.Node
compiler.err.prob.found.req
java.lang.reflect.InvocationTargetException (null)

We're not beaten yet! The solution is to use Converter to convert shapes.svg to shapes.fxd and shapesUI.fx, instead of shapes.fx. The shapes.fxd file can then be identified to the JavaFX Graphics Viewer tool, which will display the graphic. To perform this conversion, specify the .fxd extension instead of .fx when entering the destination filename.

Listing 4 presents shapes.fxd, which provides the JavaFX Script graphic definition equivalent of shapes.svg.

Listing 4. shapes.fxd (slightly reformatted for display)

/*
 * Generated by JavaFX svg2fx tool.
 * Created on Wed Sep 10 20:56:16 CDT 2008.
 */
//@version 0.1

import javafx.scene.*;
import javafx.scene.geometry.*;
import javafx.scene.image.*;
import javafx.scene.paint.*;
import javafx.scene.text.*;
import javafx.scene.effect.*;
import javafx.scene.transform.*;

Group {
    content: [
            Group {
                content: [
                    SVGPath {
                        content: "M 505.71429,316.64789
                                  A 167.14285,167.14285 0 1 1 171.42859,316.64789
                                  A 167.14285,167.14285 0 1 1 505.71429,316.64789 z"
                        fill: Color.rgb(0xff, 0x00, 0x00, 1.0)
                        id: "path3411"
                        opacity: 0.77490779
                        strokeWidth: 1.0
                    },
                    SVGPath {
                        content: "M 565.71429,505.21933
                                  A 110,110 0 1 1 345.71429,505.21933
                                  A 110,110 0 1 1 565.71429,505.21933 z"
                        fill: Color.rgb(0x00, 0x00, 0xff, 1.0)
                        id: "path3413"
                        opacity: 0.77490778999999999
                        strokeWidth: 1.0
                    },
                    Rectangle {
                        fill: Color.rgb(0xff, 0xff, 0x00, 1.0)
                        fillRule: FillRule.EVEN_ODD
                        height: 268.57144
                        id: "rect3415"
                        stroke: Color.rgb(0x00, 0x00, 0x00, 1.0)
                        strokeLineCap: StrokeLineCap.BUTT
                        strokeLineJoin: StrokeLineJoin.MITER
                        strokeWidth: 1.0
                        width: 268.57144
                        x: 62.857143
                        y: 680.9336
                    },
                    Rectangle {
                        fill: Color.rgb(0x00, 0x80, 0x00, 1.0)
                        fillRule: FillRule.EVEN_ODD
                        height: 242.85716
                        id: "rect3417"
                        stroke: Color.rgb(0x00, 0x00, 0x00, 1.0)
                        strokeLineCap: StrokeLineCap.BUTT
                        strokeLineJoin: StrokeLineJoin.MITER
                        strokeWidth: 1.0
                        width: 242.85716
                        x: 262.85715
                        y: 786.64795
                    },
                    SVGPath {
                        content: "M 131.42857,89.505038
                                  L 85.578727,95.206748
                                  L 64.282683,136.20914
                                  L 44.691654,94.365272
                                  L -0.88477702,86.781966
                                  L 32.857145,55.219325
                                  L 25.985405,9.5301921
                                  L 66.430089,31.867274
                                  L 107.75955,11.213143
                                  L 99.013819,56.580861
                                  L 131.42857,89.505038 z"
                        fill: Color.rgb(0xff, 0x00, 0xff, 1.0)
                        id: "path3419"
                        opacity: 0.77490778999999999
                        stroke: Color.rgb(0xff, 0x00, 0xff, 1.0)
                        strokeWidth: 1.0
                    },
                    Group {
                        content: [
                            SVGPath {
                                content: "M 691.14384,421.1672
                                          L 695.27678,420.53923
                                          L 695.27678,426.02081
                                          L 691.14384,426.61619
                                          L 691.14384,421.1672 z"
                                fill: Color.rgb(0xe9, 0xe9, 0xff, 1.0)
                                fillRule: FillRule.EVEN_ODD
                                id: "path3435"
                                opacity: 0.77490779
                                strokeLineCap: StrokeLineCap.BUTT
                                strokeLineJoin: StrokeLineJoin.ROUND
                                strokeWidth: 1.0
                            },
                            SVGPath {
                                content: "M 568.57142,178.0765
                                          L 568.57142,196.13906
                                          L 691.14384,426.61619
                                          L 691.14384,421.1672
                                          L 568.57142,178.0765 z"
                                fill: Color.rgb(0x35, 0x35, 0x64, 1.0)
                                fillRule: FillRule.EVEN_ODD
                                id: "path3425"
                                opacity: 0.77490779
                                strokeLineCap: StrokeLineCap.BUTT
                                strokeLineJoin: StrokeLineJoin.ROUND
                                strokeWidth: 1.0
                            },
                            SVGPath {
                                content: "M 568.57142,178.0765
                                          L 580.00001,171.07941
                                          L 695.27678,420.53923
                                          L 691.14384,421.1672
                                          L 568.57142,178.0765 z"
                                fill: Color.rgb(0x4d, 0x4d, 0x9f, 1.0)
                                fillRule: FillRule.EVEN_ODD
                                id: "path3427"
                                opacity: 0.77490779
                                strokeLineCap: StrokeLineCap.BUTT
                                strokeLineJoin: StrokeLineJoin.ROUND
                                strokeWidth: 1.0
                            },
                            SVGPath {
                                content: "M 568.57142,196.13906
                                          L 580.00001,189.50505
                                          L 695.27678,426.02081
                                          L 691.14384,426.61619
                                          L 568.57142,196.13906 z"
                                fill: Color.rgb(0xaf, 0xaf, 0xde, 1.0)
                                fillRule: FillRule.EVEN_ODD
                                id: "path3433"
                                opacity: 0.77490779
                                strokeLineCap: StrokeLineCap.BUTT
                                strokeLineJoin: StrokeLineJoin.ROUND
                                strokeWidth: 1.0
                            },
                            SVGPath {
                                content: "M 580.00001,171.07941
                                          L 580.00001,189.50505
                                          L 695.27678,426.02081
                                          L 695.27678,420.53923
                                          L 580.00001,171.07941 z"
                                fill: Color.rgb(0xd7, 0xd7, 0xff, 1.0)
                                fillRule: FillRule.EVEN_ODD
                                id: "path3431"
                                opacity: 0.77490779
                                strokeLineCap: StrokeLineCap.BUTT
                                strokeLineJoin: StrokeLineJoin.ROUND
                                strokeWidth: 1.0
                            },
                            SVGPath {
                                content: "M 568.57142,178.0765
                                          L 580.00001,171.07941
                                          L 580.00001,189.50505
                                          L 568.57142,196.13906
                                          L 568.57142,178.0765 z"
                                fill: Color.rgb(0x86, 0x86, 0xbf, 1.0)
                                fillRule: FillRule.EVEN_ODD
                                id: "path3429"
                                opacity: 0.77490779
                                strokeLineCap: StrokeLineCap.BUTT
                                strokeLineJoin: StrokeLineJoin.ROUND
                                strokeWidth: 1.0
                            }
                        ]
                    }
                ]
            }
    ]
}

Listing 5 presents the companion shapesUI.fx, which provides script access to the FXD file's graphic.

Listing 5. shapesUI.fx (slightly reformatted for display)

/*
 * Generated by JavaFX svg2fx tool.
 * UIStub for the file shapes.fxd.
 * Created on Wed Sep 10 20:56:16 CDT 2008.
 */
package result;

import java.lang.Object;
import java.lang.System;
import java.lang.RuntimeException;

import javafx.scene.*;
import javafx.scene.geometry.*;
import javafx.scene.image.*;
import javafx.scene.paint.*;
import javafx.scene.text.*;
import javafx.scene.effect.*;
import javafx.scene.transform.*;

import javafx.tools.fxd.loader.*;
import com.sun.javafx.tools.fxd.*;

public class shapesUI extends UiStub {
    public attribute g3423: Group;
    public attribute layer1: Group;
    public attribute linearGradient3213: LinearGradient;
    public attribute linearGradient3217: LinearGradient;
    public attribute path3411: SVGPath;
    public attribute path3413: SVGPath;
    public attribute path3419: SVGPath;
    public attribute path3425: SVGPath;
    public attribute path3427: SVGPath;
    public attribute path3429: SVGPath;
    public attribute path3431: SVGPath;
    public attribute path3433: SVGPath;
    public attribute path3435: SVGPath;
    public attribute rect3415: Rectangle;
    public attribute rect3417: Rectangle;
    public attribute stop3219: Stop;
    public attribute stop3221: Stop;
    public attribute stop3223: Stop;


    init {
        url = getURL();
    }

    protected function update() {
                g3423=getGroup("g3423");
        layer1=getGroup("layer1");
        linearGradient3213=getNode("linearGradient3213") as LinearGradient;
        linearGradient3217=getNode("linearGradient3217") as LinearGradient;
        path3411=getNode("path3411") as SVGPath;
        path3413=getNode("path3413") as SVGPath;
        path3419=getNode("path3419") as SVGPath;
        path3425=getNode("path3425") as SVGPath;
        path3427=getNode("path3427") as SVGPath;
        path3429=getNode("path3429") as SVGPath;
        path3431=getNode("path3431") as SVGPath;
        path3433=getNode("path3433") as SVGPath;
        path3435=getNode("path3435") as SVGPath;
        rect3415=getNode("rect3415") as Rectangle;
        rect3417=getNode("rect3417") as Rectangle;
        stop3219=getNode("stop3219") as Stop;
        stop3221=getNode("stop3221") as Stop;
        stop3223=getNode("stop3223") as Stop;

    }

    public static function getURL() : String {
        return "{__DIR__}shapes.fxd";
    }
}

Listing 5 refers to javafx.tools.fxd.loader and com.sun.javafx.tools.fxd packages, whose classes are stored in a JAR file named javafx-fxd-1.0-pre1.jar (located in the Project Nile install location's libraries subdirectory). This JAR file must be included in the classpath for scripts that access FXD files. This JAR file isn't required for scripts that access custom node-based FX files.

In addition to being viewable via the JavaFX Graphics Viewer tool, an FXD file contains three advantages over the custom node-based FX file:

  • Unlike an FX file, which must be compiled to Java bytecodes, an FXD file is never compiled, but is loaded as a resource file (it only contains graphics definitions). This gives FXD files a speed advantage.
  • Java Virtual Machine limitations can prevent FX files with large graphics from being compiled. This isn't an issue for FXD files.
  • Separating an FXD file from JavaFX Script code allows the designer and developer to maintain separate ownership. The designer can keep ownership of the FXD file, whereas the developer can keep ownership of the FX file that's also generated with the FXD file.

To view the shapes.fxd graphic, start the Java Graphics Viewer tool, specifying the location and name of this file. This graphic is shown in Figure 13.

A small part of the original graphic (at the bottom and on the right) is missing, possibly due to SVG Converter or Java Graphics Viewer.

Figure 13. A small part of the original graphic (at the bottom and on the right) is missing, possibly due to SVG Converter or Java Graphics Viewer. (Click to enlarge.)

In conclusion

Sun's JavaFX Preview SDK offers a good starting point for simplifying the development and design of RIAs based on JavaFX. As a developer, you primarily benefit from NetBeans IDE 6.1 with JavaFX. If you also dabble in design (or have a stronger interest), you'll appreciate Project Nile's Adobe Illustrator and Photoshop plugins. In this article you've had a look at what JavaFX can do, and also become familiar with using NetBeans 6.1 with JavaFX. That knowledge will come in handy when we explore the JavaFX Script language in Part 2.

About the author

Jeff Friesen is a freelance software developer and educator who specializes in Java technology. Jeff's book, Beginning Java SE 6 Platform: From Novice to Professional was released in October 2007 by Apress. Discover all of his published Java articles and more at javajeff.mb.ca.

Read more about Core Java in JavaWorld's Core Java section.

  • Print
  • Feedback

Resources

More from JavaWorld