JavaFX Script Book Example

May 31, 2009

Getting a Jump Start in JavaFX 1.2 - Excerpt from Pro JavaFX Book Chapter 1

Now that the JavaFX 1.2 SDK is available, we'd like to give you a jump start by posting a large excerpt of Chapter 1 from the Pro JavaFX book (by Jim Weaver, Weiqi Gao, Stephen Chin and Dean Iverson).  This Apress Early Access eBook is the first JavaFX book that includes the newly-introduced 1.2 features, and we are pleased to announce that it will be available on the Apress Pro JavaFX site in the next few days.

Note: If you purchase/download the Pro JavaFX Early Access eBook now (or have already done so), you will be notified when the JavaFX 1.2 updates are available, and will be able to download them at no additional charge.

Pro JavaFX will also be released as in a 500+ page printed book shortly.  By the way, if you're attending any of our JavaFX sessions at JavaOne University or the JavaOne conference, your assignment is to download the JavaFX 1.2 SDK and begin getting up to speed by working through this excerpt (just kidding).  Here ya go:

Developing Your First JavaFX Program: "Hello Earthrise"

On Christmas Eve in 1968 the crew of Apollo 8 entered lunar orbit for the first time in history.  They were the first humans to witness an “Earthrise”, taking the magnificent picture shown in the screenshot in Figure 1-4 below.  This image, and the accompanying audio MIDI file, is dynamically loaded from the Pro JavaFX book website when the program starts, so you’ll need to be connected to the Internet to view/hear it:

18753fig0104

Figure 1-4.  The Hello Earthrise Program

In addition to demonstrating how to dynamically load images over the Internet, and play audio media, this example shows you how to use animation in JavaFX.  Now it’s time for you to compile and run the program.  We’re going to show you two ways to do this: From the command-line, and using NetBeans with the JavaFX plug-in.

Compiling and Running from the Command-Line

We usually use an IDE to build and run JavaFX programs, but to take all of the mystery out of the process we’re going to use the command-line tools first. 

Note        For this exercise, as with most others in the book, you’ll need the source code.  If you’d prefer not to type the source code into a text editor, you can obtain the source code for all of the examples in this book from the code download site.  See the Resources section at the end of this chapter for the location of this site.

Assuming that you’ve downloaded and extracted the source code for this book into a directory, follow the directions in this exercise, performing all of the steps as instructed. We'll dissect the source code after the exercise.

Compiling and Running the Hello Earthrise Program from the Command-Line

You’ll use the javafxc and javafx command-line tools to compile and run the program in this exercise.  From the command-line prompt on your machine:

    1.   Navigate to the Chapter01/Hello directory.

    2.   Execute the following command to compile the HelloEarthRiseMain.fx file.  Note that the javafxc command-line tool for JavaFX is analogous to the javac tool for Java programs.

javafxc -d . HelloEarthRiseMain.fx

Because the –d option was used in this command, the class files generated are placed in directories matching the package statements in the source files.  The root of those directories are specified by the argument given for the –d option, in this case the current directory.  We’ll cover package statements in a bit. 

    3.   To run the program, execute the following command.  Note that the javafx command-line tool for JavaFX is analogous to the java tool for Java programs.  Note as well that we use the fully-qualified name of the script that will be executed, which entails specifying the nodes of the path name and the name of the script, all separated by periods.  Unlike when compiling scripts, running and appending the FX extension will result in an error.

javafx projavafx.helloearthrise.ui.HelloEarthRiseMain

The program should appear as shown in Figure 1-4 above, with the text scrolling slowly upward, reminiscent of the Star Wars opening crawls.

Congratulations on completing your first exercise as you explore JavaFX!

Understanding the Hello Earthrise Program

Now that you’ve run the application, let’s walk through the program listing together. The code for the Hello Earthrise application is shown in Listing 1-1.

Listing 1-1. The HelloEarthRiseMain.fx Program

/*
*  HelloEarthRiseMain.fx - A JavaFX Script "Hello World" style example
*
*  Developed 2009 by James L. Weaver jim.weaver [at] javafxpert.com
*  as a JavaFX Script SDK 1.2 example for the Pro JavaFX book.
*/
package projavafx.helloearthrise.ui;

import javafx.animation.transition.TranslateTransition;
import javafx.animation.*;
import javafx.stage.Stage;
import javafx.scene.*;
import javafx.scene.image.*;
import javafx.scene.media.*;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.scene.text.*;

var textRef:Text;

// Provides the animated scrolling behavior for the text
var transTransition = TranslateTransition {
  duration: 75s
  node: bind textRef
  toY: -820
  interpolator: Interpolator.LINEAR
  repeatCount: Timeline.INDEFINITE
}

Stage {
  title: "Hello Earthrise"
  scene: Scene {
    height: 387
    width: 516
    content: [
      ImageView {
        image: Image {
          url: "http://projavafx.com/images/earthrise.jpg"
        }
      },
      Group {
        layoutX: 50
        layoutY: 180
        content: [
          textRef = Text {
            layoutY: 100
            textOrigin: TextOrigin.TOP
            textAlignment: TextAlignment.JUSTIFY
            wrappingWidth: 380
            // Note that this syntax creates one long string of text
            content:
              "Earthrise at Christmas: "
              "[Forty] years ago this Christmas, a turbulent world "
              "looked to the heavens for a unique view of our home "
              "planet. This photo of Earthrise over the lunar horizon "
              "was taken by the Apollo 8 crew in December 1968, showing "
              "Earth for the first time as it appears from deep space. "
              "Astronauts Frank Borman, Jim Lovell and William Anders "
              "had become the first humans to leave Earth orbit, "
              "entering lunar orbit on Christmas Eve. In a historic live "
              "broadcast that night, the crew took turns reading from "
              "the Book of Genesis, closing with a holiday wish from "
              "Commander Borman: \"We close with good night, good luck, "
              "a Merry Christmas, and God bless all of you -- all of "
              "you on the good Earth.\""
            //The approximate color used in the scrolling Star Wars intro
            fill: Color.web("0xBBC36B")
            font: Font.font("SansSerif", FontWeight.BOLD, 24);
          }
        ]
        clip:
          Rectangle {
            width: 430
            height: 85
          }
      }
    ]
  }
}
// Start playing an audio clip
MediaPlayer {
  autoPlay: true
  repeatCount: MediaPlayer.REPEAT_FOREVER
  media: Media {
    source: "http://projavafx.com/audio/zarathustra.mid"
  }
}
// Start the text animation
transTransition.play();

Now that you’ve seen the code, let’s take a look at its constructs and concepts in detail, beginning with one of the easiest – comments.

Comments

There are two types of comments in JavaFX: multiline comments and single-line comments. Multiline comments begin with the two characters /* and end with the same two characters in reverse order */. JavaFX will ignore anything in between. The beginning of the listing shows an example of a multiline comment. Single-line comments begin with the two characters //. Anything that follows these two characters on a single line will be ignored. An example of a single-line comment is shown near the top of the code listing.

The package Declaration

JavaFX packages are analogous to folders in a file system. They provide namespaces to logically organize the scripts and classes that comprise an application.  Package names may consist of more than one node (e.g., com.apress.projavafx). In fact, it is a common practice for a package name to begin with the domain name of the company or organization that developed the application (in reverse order, beginning with the top-level domain name, such as com or org).

The package declaration is optional, but it is a very good practice to use it in all but the most trivial programs. If used, the package statement must be at the top of the source code (excluding whitespace and comments).

import Statements

JavaFX programs typically use libraries that consist of JavaFX (and optionally Java) code. In this example, each import statement indicates the location (package) of the JavaFX classes that the code in the rest of this HelloEarthRiseMain.fx script depends on for rendering the user interface. An import statement can end with an asterisk (*), indicating that the program may use any of the classes in the package. An alternative form is to specifically name each class being used, as in the example near the top of Listing 1-1:

import javafx.stage.Stage;

All but the most trivial applications should organize their source code via package declarations. A source code file uses import statements to indicate its use of classes contained in source code files that have a different package statement.

Declarative Code That Defines the User Interface

One of the most exciting features of JavaFX is its ability to express a graphical user interface (GUI) using a simple, consistent, and powerful declarative syntax. Declarative code consists of a single expression (rather than multiple expressions that are executed sequentially).

Note        As you’ll see a little later, JavaFX supports data binding which is characterized by binding the value of a variable (e.g. the height of a rectangle) to an expression.  Data binding is a major enabler of using declarative expressions.

In this example, most of the program is declarative, in that it contains a large expression. This declarative expression begins by defining a Stage object followed by an open curly brace, and ends with the matching curly brace near the end of the program.  Nested within that are instance variables of the Stage object, including the scene variable, which is assigned a Scene instance.  A Scene has an instance variable named content that holds the graphical elements that are displayed on the Stage, in this case an ImageView instance (which displays an image) and a Group instance.  Nested within the Group is a content instance variable that holds a Text instance (which is a graphical element, usually called a graphical node, or simply node) and so on.

Note        This declarative expression is an example of object literal syntax, in which instances of these classes are created when the expression is evaluated.

Declarative code automatically creates an instance (also known as an object) of each JavaFX class in the expression. It also assigns values to the variables of the new instance. For example, look at the portion of code that creates an instance of the Rectangle class:

Rectangle {

  width: 430

  height: 85

}

This code creates an instance of the JavaFX Rectangle class and assigns the value 430 to the width variable of the new Rectangle instance, and the value 85 to its height variable. Notice that the instance variable name is always followed by a colon (:), which in JavaFX declarative syntax means “assign the value of the expression on the right to the instance variable on the left.” These same concepts are true for all of the classes (Stage, Scene, ImageView, Image, Group, Text, TranslateTransition, MediaPlayer and Media) in this script. Let’s look at each of these classes individually.

Using the Stage Class

A Stage contains the user interface of a JavaFX app, regardless whether it is deployed on the desktop, within a browser, or on a mobile device.  On the desktop, for example, a Stage has its own top-level window which typically includes a border and title bar.  In the browser the Stage doesn’t have a window, but rather is rendered as an applet within a rectangular area of the browser.

As with any class, the Stage class has a set of instance variables. Some of these variables, as shown in the following code snippet from the listing, are as follows:

    *    A title that appears in the title bar of the window (when deployed on the desktop).

    *    A scene that contains the graphical nodes in the user interface.

Stage {

  title: "Hello Earthrise"

  scene: Scene {

    …some code omitted…

  }

}

Creating String Literals

One of the basic JavaFX data types is the String, which consists of zero or more characters strung together. As shown in the following title variable of the Stage instance, a String literal is defined by enclosing a set of characters in double quotes:

title: "Hello Earthrise"

For convenience, as shown in the content variable of the Text instance in Listing 1-1 above, a String literal may be defined with multiple sets of quoted characters.  Alternatively, String literals may be enclosed in single quotes.  Strings have more capabilities than described here, but we’ll cover them as they occur in code examples.

Using the Scene Class

As mentioned previously, a Scene holds the graphical elements that are displayed on the Stage. Every element in a Scene is a graphical node, which is any class that extends the javafx.scene.Node class.  Take another look at the declarative code, shown below, that creates the Scene in our example program:

scene: Scene {

  content: [

    ImageView {

      …some code omitted…

    },

    Group {

      …some code omitted…

    }

  ]

}

Notice that the content variable of the Scene is followed by a left square bracket “[” which is the literal notation for a sequence.  A sequence is a one-dimensional data structure that is native to JavaFX.  Take a look at the JavaFX API documentation that we showed you how to access in the Accessing the JavaFX SDK API section above.  You’ll see that the content variable of the Scene class is of type Node[], which means that it can reference a sequence of Node instances. 

While you’re looking at the API docs, take a look at the Node class to see the variables and functions available to any graphical node.  Also, take a look at the ImageView class in the javafx.scene.image package, and the Group class in the javafx.scene package.  In both cases, you’ll see that they inherit from the Node class.

Tip           We can’t emphasize enough the importance of having the JavaFX API documentation handy while reading this book.  As classes, variables, and functions are mentioned, it’s often a good idea to look at the documentation to get more information.  In addition, this habit helps you become more familiar with what is available to you in the API.

Displaying Images

As shown in the following code, displaying an image entails using an ImageView instance in conjunction with an Image instance:

ImageView {

  image: Image {

    url: "http://projavafx.com/images/earthrise.jpg"

  }

},

The Image instance identifies the image resource and loads it from the URL assigned to its url variable.  Both of these classes are located in the javafx.scene.image package.

Working with Graphical Nodes as a Group

One very powerful graphical feature of JavaFX is the ability to create scene graphs, which consist of a tree of graphical nodes.  You can then assign values to variables of a Group located in the hierarchy, and the nodes contained in the Group will be affected.  In our current example from Listing 1-1, we’re using a Group to contain a Text node and to clip a specific rectangular region within the Group so that the text doesn’t appear on the moon or the Earth as it animates upward.  See the relevant code snippet below:

Group {

  layoutX: 50

  layoutY: 180

  content: [

    textRef = Text {

      layoutY: 100

      textOrigin: TextOrigin.TOP

      textAlignment: TextAlignment.JUSTIFY

      wrappingWidth: 380

      content:

        "Earthrise at Christmas: "

        ...some code omitted...

      fill: Color.#bbc36b

      font: Font.font("SansSerif", FontWeight.BOLD, 24);

    }

  ]

  clip:

    Rectangle {

      width: 430

      height: 85

    }

}

Notice that the Group is located 50 pixels to the right, and 180 pixels down, from where it would have been located by default.  This is due to the values assigned to the layoutX and layoutY variables of the Group instance.  Because this Group is contained directly by the Scene, its upper left corner’s location is 50 pixels to the right and 180 pixels down from the upper left corner of the Scene.  Take a look at Figure 1-5 below to see this example illustrated as you read the rest of the explanation.

18753fig0105

Figure 1-5.  The Scene, Group, Text, and clip illustrated

 

Like a Scene, a Group instance contains instances of Node subclasses by assigning a sequence of them to the content variable.  In the code snippet above, the Group contains a Text instance which has a value assigned to its layoutY variable.  Because this Text is contained by a Group, it assumes the two-dimensional space (also called the coordinate space) of the Group, with the origin of the Text node (0,0) being coincident with the top left corner of the Group.  Assigning a value of 100 to the layoutY variable causes the Text to be located 100 pixels down from the top of the Group, which is just below the bottom of the clip region causing it to be out of view until the animation begins.  Because a value isn’t assigned to the layoutX variable, its value is 0 (the default).

The layoutX and layoutY variables of the Group described above is an example of the earlier statement that “you can then assign values to variables of a Group located in the hierarchy, and the nodes contained in the Group will be affected.”  Another example of this is setting the opacity variable of a Group instance to 0.5 which causes all of the nodes contained in that Group to become translucent.  If the JavaFX API documentation is handy, look at the variables available in the javafx.scene.Group class.  Then scroll down to see the variables inherited from the java.scene.Node class, which is where you’ll find the layoutX, layoutY, and opacity variables.

Drawing Text

In the snippet above, notice that there are several variables available in the Text class.  This particular example is a little more complicated than the normal use of the Text class.  Let’s first look at a typical case, shown in the snippet below, in which you simply want to draw a string of text characters somewhere in the scene:

Text {

  layoutX: 65

  layoutY: 12

  textOrigin: TextOrigin.TOP

  fill: Color.WHITE

  content: "Audio Configuration"

  font: Font.font("SansSerif", FontWeight.BOLD, 20)

},

This snippet, borrowed from the Audio Configuration example in Figure 1-16 and Listing 1-3, draws the graphical Text string “Audio Configuration” in a bold, Sans Serif font.  The font size is 20, and the color of the text is white.

Referring again to the JavaFX API documentation, you’ll notice that the TextOrigin class (in the javafx.scene.text package) has three fields that serve as constants: BASELINE, BOTTOM, and TOP.  These control the origin of the text with respect to vertical locations on the displayed Text:

    *    The TOP origin, as we’re using it in the code snippet above, places the top of the text (including ascenders) at the layoutY position, relative to the coordinate space in which the Text is located. 

    *    The BOTTOM origin would place the bottom of the text, including descenders (located in a lower case “g” for example) at the layoutY position.

    *    The BASELINE origin would place the baseline of the text (excluding descenders) at the layoutY position.  This is the default value for the textOrigin variable of a Text instance.

While you’re looking at the javafx.scene.text package in the API documentation, take a look at the font function of the Font class, which is used in the snippet above to define the font family, weight and size of the Text.

Turning back again to the Hello Earthrise example in Listing 1-1, we’re using some additional variables of the Text class that enable it to flow from one line to the next:

    *    The wrappingWidth variable enables you to specify at what number of pixels the text will wrap.

    *    The textAlignment variable enables you to control how the text will be justified.  In our example, TextAlignment.JUSTIFY aligns the text on both the left and right sides, expanding the space between words to achieve that.

The text that we’re displaying is sufficiently long to wrap and be drawn on the Earth, so we need to define a rectangular region outside of which that text can’t be seen:

Clipping Graphical Areas

To define a clipping area, we assign a Node subclass to the clip variable that defines the clipping shape, in this case a Rectangle that is 430 pixels wide and 85 pixels high.  In addition to keeping the Text from covering the moon, when the Text scrolls up as a result of animation, the clipping area keeps the Text from covering the earth.

Animating the Text to Make it Scroll Up

When the HelloEarthriseMain.fx script is invoked, the Text begins scrolling up slowly.  To achieve this animation, we’re using the TranslateTransition class located in the javafx.animation.transition package, as shown in the snippet below from Listing 1-1:

// Provides the animated scrolling behavior for the text

var transTransition = TranslateTransition {

  duration: 75s

  node: bind textRef

  toY: -820

  interpolator: Interpolator.LINEAR

  repeatCount: Timeline.INDEFINITE

}

...code omitted...

// Start the text animation

transTransition.play();

The javafx.animation.transition package contains convenience classes for animating nodes.  This TranslateTransition instance translates the Text node from its original Y position of 100 pixels to a Y position of -820 pixels, over a duration of 75 seconds (the duration of the audio clip).  Note that the Text node is referenced by the textRef variable as we’ll explain shortly, and that we’re using the bind operator in the assignment to the node variable (we’ll cover the bind operator later in this chapter).  The Interpolator.LINEAR constant is assigned to the interpolator variable, which causes the animation to proceed in a linear fashion.  Looking at the API docs for the Interpolator class in the javafx.animation package will reveal that there are other forms of interpolation available, one of which is EASEOUT, which slows down the animation toward the end of the specified duration.

Note        Interpolation in this context is the process of calculating the value at any point in time, given a beginning value, an ending value, and a duration.

The last line in the snippet above begins executing the play function of the TranslateTransition instance created earlier in the script, which makes the Text begin scrolling upward.  Because of the value assigned to the repeatCount variable, this transition will repeat indefinitely.

Take a look again at the entire HelloEarthRiseMain.fx script in Listing 1-1 to get an overall picture of how it is processed when invoked:

    *    The first statement declares a variable of type Text, named textRef, which is used to hold a reference to the Text instance that will have a transition applied to it (as we just finished discussing).

    *    The second statement declares a variable named transTransition and creates an instance of the TranslateTransition class, assigning its reference to the transTransition variable.

    *    Next, the declarative expression that comprises most of the rest of the script  is evaluated, which creates an instance of the Stage class and the other classes in the UI scene graph.

    *    The statement at the end of the script is executed, which plays the transition.

Finally, let’s discuss how the audio media is played as the text is scrolling.

Playing Media

The code snippet below from Listing 1-1 demonstrates how to load and play audio media:

MediaPlayer {

  autoPlay: true

  repeatCount: MediaPlayer.REPEAT_FOREVER

  media: Media {

    source: "http://projavafx.com/audio/zarathustra.mid"

  }

}

As shown above, the audio clip automatically begins playing, and repeats indefinitely (until the program exits).  We’ll have a lot more to say about playing audio and video media in Chapter 6, so stay tuned!

Now that you’ve compiled and run this example using the command-line tools, and we’ve walked through the code together, it is time to begin using the NetBeans IDE with the JavaFX plug-in to make the development and deployment process faster and easier.

Building and Running the Program with NetBeans

Assuming that you’ve downloaded and extracted the source code for this book into a directory, follow the directions in this exercise to build and run the Hello Earthrise program in NetBeans with the JavaFX Plug-in.  If you haven’t yet downloaded the version of the JavaFX SDK that contains NetBeans, please do so from the JavaFX downloads page listed in the Resources section at the end of this chapter.

Building and Running Hello Earthrise with NetBeans

To build and run the Hello Earthrise program, perform the following steps:

    1.   Start up the version of NetBeans that is available for download with the JavaFX SDK.         .              

    2.   Choose File ~TRA New Project from the menu bar.  The following dialog in Figure 1-6 should appear:

18753fig0106

Figure 1-6.  The NetBeans New Project Wizard

    3.   Choose JavaFX in the Categories pane, JavaFX Script Application in the Projects pane, and select the Next button.  The next page in the New Project Wizard should appear, as shown in Figure 1-7 below:

18753fig0107

Figure 1-7.  New JavaFX Script Application Dialog

    4.   In the dialog in Figure 1-7, type the Project Name (we used HelloEarthrise) click the Browse button.

    5.   In the Select Project Location dialog box (not shown), navigate to the directory in which you’d like to create this project (we used C:\MyJavaFX), and select the Open button.

    6.   Select the From Sources radio button and click the Add Folder button. 

    7.   In the Browse Source Packages Editor dialog (not shown), navigate to the Chapter01/HelloEarthrise/src directory subordinate to where you expanded this book’s code download bundle, and select the Open button.

Note: These instructions are for creating a new NetBeans project from JavaFX source code.  Step 7 above won’t be successful if NetBeans finds a directory named nbproject and/or a build.xml file.  This is because Netbeans assumes that the src directory is part of another project and refuses to add them to the new project.  The build/run instructions in the Audio Configuration example later in this chapter demonstrate how to work with a NetBeans JavaFX project that already exists.

    8.   Select the Finish button.  The HelloEarthrise project should now be created, and you’re ready to run it.

    9.  Right-click on the HelloEarthrise project in the Projects pane and select Run Project from the context menu.

    10. The Run Project dialog, shown in Figure 1-8 below, will appear the first time you run the project, asking for the main class.  Choose the projavafx.helloearthrise.ui.HelloEarthRiseMain class (the only class in the list for this simple example), and select the OK button.

18753fig0108

Figure 1-8.  Choosing the main class for a project

The HelloEarthRise program should begin executing, with an appearance similar to the screenshot in Figure 1-4, shown earlier in the chapter.

At this point, you’ve built and run the “Hello Earthrise” program application – both from the command line, and using NetBeans.  Now we’re going to show you how to deploy this program using Java Web Start, and then as an applet in a browser.

Deploying JavaFX Applications

As mentioned earlier in this chapter, the JavaFX and Java SE 6 update 10 technologies are working together to restore rich client Java.  In this section you’ll configure and deploy the Hello Earthrise application with Java Web Start, and as a JavaFX applet.  The underlying features of Java SE 6 Update 10 will be leveraged in this process.

Deploying JavaFX Applications with Java Web Start

To build the “Hello Earthrise” program with NetBeans to deploy as a Java Web Start application, you need to create a configuration for that purpose.   The following exercise walks you through this process.

Deploying the Hello Earthrise program with Java Web Start

To create a configuration for deploying the Hello Earthrise program with Java Web Start, perform the following steps:

    1.   Right-click on the HelloEarthrise project in the Projects pane and select Set Configuration ~TRA Customize from the context menu, as shown in Figure 1-9 below:

18753fig0109

Figure 1-9.  Customizing a configuration from the context menu

    2.   The Project Properties dialog, shown in Figure 1-10 below, will appear.  Choose Run from the Categories pane, and the Web Start Execution radio button from the Application Execution Model options.

18753fig0110

Figure 1-10.  Selecting Web Start Execution

    3.   While still in the Project Properties dialog, choose Application from Categories pane as shown in Figure 1-11 below.  Select the Self Signed Jar and Pack200 Compression check boxes.  The Applet specific properties are not applicable for Web Start execution, so you can safely ignore these for now.  Select the OK button to close this dialog.

18753fig0111

Figure 1-11.  Choosing Web Start specific properties

Caution   Selecting Self Signed Jar signs the Web-started application, but it doesn’t use an authoritative certificate.  A security dialog will appear, but it will indicate that the signature can’t be verified.  For this reason, posting (or executing) JavaFX applications with self-signed JARs on the Internet is not a good practice.  If the application doesn’t require access outside the sandbox (e.g. to the Nasa website as this one does), then there is no need to sign the code anyway.  If the application needs access outside the sandbox and you want to put your application on the Internet, then we suggest that you get a code-signing certificate (e.g. from VeriSign or Thawte).

Because of the configuration that you just performed, when you run the project as described previously, it should be invoked via Java Web Start, with its appearance as shown in Figure 1-4 above.

Now that you’ve configured and run Hello Earthrise as a Java Web Start application, let’s deploy it as an applet inside your Web browser.

Deploying JavaFX Applets

To deploy the “Hello Earthrise” program as a Java Web Start application, you need to create a configuration in the NetBeans project for that purpose.   The following exercise walks you through this process:

Deploying the Hello Earthrise program as an Applet in a Web Browser

To create a configuration for deploying the Hello Earthrise program as an applet in a browser, perform the following steps:

    1.   Right-click on the HelloEarthrise project in the Projects pane and select Set Configuration ~TRA Customize from the context menu, as shown in Figure 1-9 previously.

    2.   The Project Properties dialog, shown in Figure 1-12 below, will appear.  Choose Run from the Categories pane, and the Run in Browser radio button from the Application Execution Model options.

18753fig0112

Figure 1-12.  Choosing to Run in Browser

    3.   While still in the Project Properties dialog, choose Application from Categories pane as shown in Figure 1-13 below.  Select the Self Signed Jar and Pack 200 Compression check boxes.  In Applet specific properties, enter 516 in the Width field, 387 in the Height field, and select the Draggable Applet check box.  The reason for these particular width and height numbers is that these are the dimensions of the image which fills the scene.  Choosing to make the applet draggable, when run in a browser on which Java SE 6 Update 10 is installed, allows that applet to be dragged from the browser onto the desktop.  Select the OK button to close this dialog.

18753fig0113

Figure 1-13.  Choosing Applet specific properties

Because of the configuration that you just performed, when you run the project as described previously, it should be invoked in your default browser.  If you have Java SE 6 update 10 installed, then hold the ALT key down while clicking and dragging the applet onto the desktop as shown in Figure 1-14 below.

18753fig0114

Figure 1-14.  Dragging the Hello Earthrise applet onto the desktop

Before leaving this example, we’d like to show you another way to clip the scrolling Text node.  There is a class in the javafx.scene.layout package named ClipView whose purpose is to provide a clipped view of a node that is typically larger than the view.  In addition, the user can drag the node being viewed within the clipped area.  Figure 1-15 below is a screenshot of the Hello Earthrise program after being modified to use the ClipView layout container.

18753fig0115

Figure 1-15.  Using the ClipView layout container to clip the Text node

Notice that the move cursor is visible, signifying that the user can drag the node around the clipped area.  Note: The screenshot in Figure 1-15 is of the program running on Windows, and the move cursor has a different appearance on other platforms.  Listing 1-2 below contains the code for this example, named HelloClipViewExample:

Listing 1-2. The HelloClipViewExample.fx Program

package projavafx.helloclipview.ui;

import javafx.animation.transition.TranslateTransition;
import javafx.animation.*;
import javafx.stage.Stage;
import javafx.scene.*;
import javafx.scene.image.*;
import javafx.scene.layout.ClipView;
import javafx.scene.media.*;
import javafx.scene.paint.Color;
import javafx.scene.text.*;

var textRef:Text;

// Provides the animated scrolling behavior for the text
var transTransition = TranslateTransition {
  duration: 75s
  node: bind textRef
  toY: -820
  interpolator: Interpolator.LINEAR
  repeatCount: Timeline.INDEFINITE
}

Stage {
  title: "Hello ClipView"
  scene: Scene {
    height: 387
    width: 516
    content: [
      ImageView {
        image: Image {
          url: "http://projavafx.com/images/earthrise.jpg"
        }
      },
      ClipView {
        layoutX: 50
        layoutY: 180
        width: 430
        height: 85
        node:
          textRef = Text {
            layoutY: 100
            textOrigin: TextOrigin.TOP
            textAlignment: TextAlignment.JUSTIFY
            wrappingWidth: 380
            // Note that this syntax creates one long string of text
            content: "Earthrise at Christmas: "
                     "[Forty] years ago this Christmas, a turbulent world "
                     "looked to the heavens for a unique view of our home "
                     "planet. This photo of Earthrise over the lunar horizon "
                     "was taken by the Apollo 8 crew in December 1968, showing "
                     "Earth for the first time as it appears from deep space. "
                     "Astronauts Frank Borman, Jim Lovell and William Anders "
                     "had become the first humans to leave Earth orbit, "
                     "entering lunar orbit on Christmas Eve. In a historic live "
                     "broadcast that night, the crew took turns reading from "
                     "the Book of Genesis, closing with a holiday wish from "
                     "Commander Borman: \"We close with good night, good luck, "
                     "a Merry Christmas, and God bless all of you -- all of "
                     "you on the good Earth.\""
            // The approximate color used in the scrolling Star Wars intro
            fill: Color.web("0xBBC36B")
            font: Font.font("SansSerif", FontWeight.BOLD, 24);
          }
      }
    ]
  }
}
// Start playing an audio clip
MediaPlayer {
  autoPlay: true
  repeatCount: MediaPlayer.REPEAT_FOREVER
  media: Media {
    source: "http://projavafx.com/audio/zarathustra.mid"
  }
}
// Start the text animation
transTransition.play();

Later chapters will cover other layout containers in the javafx.scene.layout package, such as HBox, VBox, Flow, Tile, and Stack.  For now, let’s examine another JavaFX example application to help you learn more JavaFX Script concepts and constructs.

Developing Your Second JavaFX Program: "More Cowbell!"

If you're familiar with the Saturday Night Live television show, you may have seen the More Cowbell sketch, in which Christopher Walken's character keeps asking for "more cowbell" during a Blue Oyster Cult recording session.  The following JavaFX example program covers some of the simple but powerful concepts of JavaFX in the context of an imaginary application that lets you select a music genre and control the volume.  Of course, "Cowbell Metal", shortened to "Cowbell", is one of the available genres.  Figure 1-16 shows a screenshot of this application, which has a sort of iPhone application look.

18753fig0116

Figure 1-16.  The Audio Configuration “More Cowbell” Program

Building and Running the Audio Configuration Program

Earlier in the chapter, we showed you how to create a new JavaFX project in NetBeans, and how to add a folder that contains source code files to the project.

For this example (and the rest of the examples in the book), we’ll take advantage of the fact that the code download bundle for the book contains both NetBeans and Eclipse project files for each example.  Follow the instructions in the exercise below to build and run the Audio Configuration application.

Building and Running the Audio Configuration Program using NetBeans

To build and execute this program using NetBeans, perform the following steps:

    1.   From the File menu, select the Open Project menu item.  In the Open Project dialog, navigate to the Chapter01 directory subordinate to where you extracted the book’s code download bundle, as shown in figure 1-17 below:

18753fig0117

Figure 1-17.  Opening an existing project in NetBeans

    2.   Select the AudioConfig project in the pane on the left, and select the Open Project button.

    3.   Run the project as discussed previously.

The application should appear as shown in Figure 1-16 above.

The Behavior of the Audio Configuration Program

When you run the application, notice that adjusting the volume slider changes the associated decibel (dB) level displayed.  Also, selecting the Muting checkbox disables the slider, and selecting various genres changes the volume slider.  This behavior is enabled by concepts that you'll see in the code below, such as binding to a class that contains a model, on replace triggers, and sequences.

Understanding the Audio Configuration Program

The Audio Configuration program contains two source code files, shown below in Listing 1-3 and Listing 1-4:

    *    The AudioConfigMain.fx file in Listing 1-3 contains the main script, and expresses the UI in a manner that you are familiar with from the Hello Earthrise example in Listing 1-1.

    *    The AudioConfigModel.fx file in Listing 1-4 contains a model for this program, which holds the state of the application, to which the UI is bound. 

Take a look at the AudioConfigMain.fx source code in Listing 1-3, and then we’ll examine it together, focusing on concepts not covered in the previous example:

Listing 1-3. The AudioConfigMain.fx Program

package projavafx.audioconfig.ui;

import javafx.ext.swing.SwingComboBox;
import javafx.ext.swing.SwingComboBoxItem;
import javafx.scene.*;
import javafx.scene.control.Slider;
import javafx.scene.control.CheckBox;
import javafx.scene.paint.*;
import javafx.scene.shape.*;
import javafx.scene.text.*;
import javafx.stage.Stage;
import projavafx.audioconfig.model.AudioConfigModel;

Stage {
  def acModel = AudioConfigModel {
    selectedDecibels: 35
  }
  title: "Audio Configuration"
  scene: Scene {
    content: [
      Rectangle {
        // No need to assign 0 to x and y, because 0 is the default
        width: 320
        height: 45
        fill: LinearGradient {
          // No need to assign 0 to startX and startY, because 0 is default
          endX: 0.0
          endY: 1.0
          stops: [
            Stop {
              color: Color.web("0xAEBBCC")
              offset: 0.0
            },
            Stop {
              color: Color.web("0x6D84A3")
              offset: 1.0
            }
          ]
        }
      },
      Text {
        layoutX: 65
        layoutY: 12
        textOrigin: TextOrigin.TOP
        fill: Color.WHITE
        content: "Audio Configuration"
        font: Font.font("SansSerif", FontWeight.BOLD, 20)
      },
      Rectangle {
        x: 0  // 0 is default, so assigning here just for clarity
        y: 43
        width: 320
        height: 300
        fill: Color.web("0xC7CED5")
      },
      Rectangle {
        x: 9
        y: 54
        width: 300
        height: 130
        arcWidth: 20
        arcHeight: 20
        fill: Color.WHITE
        stroke: Color.color(0.66, 0.67, 0.69)
      },
      Text {
        layoutX: 18
        layoutY: 69
        textOrigin: TextOrigin.TOP
        fill: Color.web("0x131021")
        content: bind "{%1.0f acModel.selectedDecibels} dB"
        font: Font.font("SansSerif", FontWeight.BOLD, 18)
      },
      Slider {
        layoutX: 135
        layoutY: 69
        width: 162
        disable: bind acModel.muting
        min: bind acModel.minDecibels
        max: bind acModel.maxDecibels
        value: bind acModel.selectedDecibels with inverse
      },
      Line {
        startX: 9
        startY: 97
        endX: 309
        endY: 97
        stroke: Color.color(0.66, 0.67, 0.69)
      },
      Text {
        layoutX: 18
        layoutY: 113
        textOrigin: TextOrigin.TOP
        fill: Color.web("0x131021")
        content: "Muting"
        font: Font.font("SansSerif", FontWeight.BOLD, 18)
      },
      CheckBox {
        layoutX: 280
        layoutY: 113
        selected: bind acModel.muting with inverse
      },
      Line {
        startX: 9
        startY: 141
        endX: 309
        endY: 141
        stroke: Color.web("0xA8AAAF")
      },
      Text {
        layoutX: 18
        layoutY: 157
        textOrigin: TextOrigin.TOP
        fill: Color.web("0x131021")
        content: "Genre"
        font: Font.font("SansSerif", FontWeight.BOLD, 18)
      },
      SwingComboBox {
        layoutX: 204
        layoutY: 148
        width: 93
        items: bind for (genre in acModel.genres) {
          SwingComboBoxItem {
            text: genre
          }
        }
        selectedIndex: bind acModel.selectedGenreIndex with inverse
      }
    ]
  }
}

Now that you’ve had a look at the main script in this application, let’s walk through the new concepts.

Creating an Instance of the Model, and the Magic of Binding

One of the very powerful aspects of JavaFX is binding, which enables the application’s UI to easily stay in sync with the state, or model, of the application.   The model for a JavaFX application is typically held in one or more classes, in this case the AudioConfigModel class.  To make an instance of this class we use the same object literal syntax that we’ve used to create instances of UI classes.  Look at the snippet below, taken from Listing 1-3:

  def acModel = AudioConfigModel {

    selectedDecibels: 35

  }

This instantiates the AudioConfigModel class, initializing its selectedDecibels instance variable to a value of 35.  In addition, a reference to that instance is held by a variable named acModel.

Note: The def keyword in the snippet above is similar to var, except that its value must be assigned and initialized when it is declared.  Also, it cannot subsequently be assigned a value.  The def keyword enables the compiler to perform related optimizations.

There are several graphical node instances in the scene of this UI (recall that a scene consists of a sequence of nodes).  Skipping past several of them, we come to the graphical nodes shown in the snippet below that have an instance variable bound to the selectedDecibels variable in the model:

      Text {

        layoutX: 18

        layoutY: 69

        textOrigin: TextOrigin.TOP

        fill: Color.web("0x131021")

        content: bind "{%1.0f acModel.selectedDecibels} dB"

        font: Font.font("SansSerif", FontWeight.BOLD, 18)

      },

      Slider {

        layoutX: 135

        layoutY: 69

        width: 162

        disable: bind acModel.muting

        min: bind acModel.minDecibels

        max: bind acModel.maxDecibels

        value: bind acModel.selectedDecibels with inverse

      },

As shown in the snippet above, the content variable of the Text object is bound to a String.  The curly braces in this String contain an expression (that includes the selectedDecibels variable) which is evaluated and becomes part of the String.  Look at Figure 1-16 (or check the running application) to see the content value of the Text node displayed to the left of the slider.

Note: The %1.0f string formatting specification causes the decimal portion of selectedDecibels to be suppressed.  See Chapter 4 for details on string formatting and its use for internationalization.

Notice also in the snippet above that value instance variable of the Slider node is bound to the selectedDecibels variable in the model as well, but that it has the keywords with inverse at the end of the expression.  This causes the bind to be bi-directional, so in this case when the slider is moved, the selectedDecibels value in the model changes.  Conversely, when the selectedDecibels value changes (as a result of changing the genre), the slider moves.

Go ahead and move the slider to demonstrate the effects of the bind expressions in the snippet above.  The number of decibels displayed at the left of the slider should change as the slider is adjusted.

There are other bound instance variables in Listing 1-3 that we’ll point out when we walk through the model class.  Before leaving the UI, we’d like to point out some color-related concepts in this example.

Colors and Gradients

The snippet below from Listing 1-3 contains an example of defining a color gradient pattern, as well as defining colors:

      Rectangle {

        // No need to assign 0 to x and y, because 0 is the default

        width: 320

        height: 45

        fill: LinearGradient {

          // No need to assign 0 to startX and startY, because 0 is default

          endX: 0.0

          endY: 1.0

          stops: [

            Stop {

              color: Color.web("0xAEBBCC")

              offset: 0.0

            },

            Stop {

              color: Color.web("0x6D84A3")

              offset: 1.0 

            }

          ]

        }

      },

If the JavaFX API docs are handy, first take a look at the javafx.scene.shape.Rectangle class and notice that it inherits an instance variable named fill that is of type javafx.scene.paint.Paint.  Looking at the JavaFX API docs for the Paint class, you’ll see that the Color, LinearGradient, and RadialGradient classes are subclasses of Paint.  This means that the fill of any shape can be assigned a color or a gradient.

To create a LinearGradient, as shown in the snippet, you need to define at least two stops, which define the location and color at that location.  In this example the offset value of the first stop is 0.0, and the offset value of the second stop is 1.0.  These are the values at both extremes of the unit square, the result being that the gradient will span the entire node (in this case a Rectangle).  The direction of the LinearGradient is controlled by its startX, startY, endX and endY values.  In this case, the direction is only vertical because the startY value is 0.0 and the endY value is 1.0, while the startX and endX values are both 0.0.   

Note that in the Hello Earthrise example in Listing 1-1, the constant named Color.WHITE was used to represent the color white.  In the snippet above, the web function of the Color class is used to define a color from a hexadecimal value.

The Model Class for the Audio Configuration Example

Take a look at the source code for the AudioConfigModel class in Listing 1-4 below:

Listing 1-4. The Source Code for AudioConfigModel.fx

package projavafx.audioconfig.model;

/**
* The model class that the AudioConfigMain.fx script uses
*/
public class AudioConfigModel {
  /**
   * The minimum audio volume in decibels
   */
  public def minDecibels:Number = 0;

  /**
   * The maximum audio volume in decibels
   */
  public def maxDecibels:Number = 160;

  /**
   * The selected audio volume in decibels
   */
  public var selectedDecibels:Number;

  /**
   * Indicates whether audio is muted
   */
  public var muting:Boolean;  // false is default for Boolean

  /**
   * List of some musical genres
   */
  public def genres = [
    "Chamber",
    "Country",
    "Cowbell",
    "Metal",
    "Polka",
    "Rock"
  ];

  /**
   * Index of the selected genre
   */
  public var selectedGenreIndex:Integer on replace {
    if (genres[selectedGenreIndex] == "Chamber") {
      selectedDecibels = 80;
    }
    else if (genres[selectedGenreIndex] == "Country") {
      selectedDecibels = 100;
    }
    else if (genres[selectedGenreIndex] == "Cowbell") {
      selectedDecibels = 150;
    }
    else if (genres[selectedGenreIndex] == "Metal") {
      selectedDecibels = 140;
    }
    else if (genres[selectedGenreIndex] == "Polka") {
      selectedDecibels = 120;
    }
    else if (genres[selectedGenreIndex] == "Rock") {
      selectedDecibels = 130;
    }
  };
}

Structure of a Minimal JavaFX class

JavaFX is fully object-oriented, and even supports mixin inheritance and closures (both of which will be discussed in Chapter 4).  The minimum code that you need to create a class in JavaFX is the class declaration.  The declaration of a class always includes the class keyword and, as shown in the preceding code snippet, has opening and closing curly braces. There are other JavaFX keywords, such as public and extends, that can modify the class keyword. We’ll discuss these in detail in Chapter 4.

Another basic construct of a class declaration is the instance variable.  The class in Listing 1-4 defines several instance variables.  When an instance of this class is created, space is carved out in memory for each instance variable.

Defining Triggers in the Model Class

Triggers are a construct in JavaFX that helps enable declarative programming.  For example, the on replace trigger shown in the snippet below executes whenever the value of the selectedGenreIndex variable changes:

  public var selectedGenreIndex:Integer on replace {

    if (genres[selectedGenreIndex] == "Chamber") {

      selectedDecibels = 80;

    }

    else if (genres[selectedGenreIndex] == "Country") {

      selectedDecibels = 100;

    }

    else if (genres[selectedGenreIndex] == "Cowbell") {

      selectedDecibels = 150;

    }

    else if (genres[selectedGenreIndex] == "Metal") {

      selectedDecibels = 140;

    }

    else if (genres[selectedGenreIndex] == "Polka") {

      selectedDecibels = 120;

    }

    else if (genres[selectedGenreIndex] == "Rock") {

      selectedDecibels = 130;

    }

  };

What causes selectedGenreIndex to change though?  To see the answer to this, we have to revisit the declarative UI script in Listing 1-3.  Here’s the relevant snippet:

      SwingComboBox {

        layoutX: 204

        layoutY: 148

        width: 93

        items: bind for (genre in acModel.genres) {

          SwingComboBoxItem {

            text: genre

          }

        }

        selectedIndex: bind acModel.selectedGenreIndex with inverse

      }

Notice that the selectedIndex variable of the SwingComboBox is bi-directionally bound (recall our with inverse discussion) to the selectedGenreIndex variable in the model.  Because of this, whenever the user selects a different genre in the combo box, the on replace trigger is executed.  Looking again at the code in the on replace trigger, you’ll see that the value of the selectedDecibels variable changes, which as you may recall, is bi-directionally bound to the slider.  This is why the slider moves when you select a genre in the combo box.  Go ahead and test this out by running the Audio Config program.

We’ll point out one more example of binding in this program, and then we’ll let you study the code independently to find the rest.  In the most recent code snippet, binding is used to populate the SwingComboBox with SwingComboBoxItem instances that each contains a genre.  The snippet below from the model code in Listing 1-4 contains the sequence to which the SwingComboBoxItem instances are bound. 

  /**

   * List of some musical genres

   */

  public var genres = [

    "Chamber",

    "Country",

    "Cowbell",

    "Metal",

    "Polka",

    "Rock"

  ];

The means by which the genres sequence is bound to the SwingComboBox items variable (using the for keyword in the explicit sequence expression) will be covered in Chapter 2.

Surveying JavaFX Features

We’d like to close this chapter by surveying many of the features of JavaFX, some of which will be a review for you.  We’ll do this by describing several of the more commonly used packages and classes in the JavaFX SDK API:

The javafx.stage package contains:

    *    The Stage class, which is the top level of the UI containment hierarchy for any JavaFX application, regardless of where it is deployed (e.g. desktop, browser, or mobile phone).

    *    The Alert class, which has functions that may be called to make alert dialogs (such as a confirmation dialog) appear.

    *    The Screen class  represents the displays on the machine in which a JavaFX program is running.  This enables you to get information about the screens, such as size and resolution.

The javafx.scene package contains some classes that you'll use often:

    *    The Scene class is the second level of the UI containment hierarchy for JavaFX applications.  It contains all of the UI elements contained in the application.  These elements are called graphical nodes, or simply nodes.

    *    The Node class is the base class of all of the graphical nodes in JavaFX.  As you'll see, UI elements such as text, images, media, shapes, and controls (such as text boxes and buttons) are all subclasses of Node.  Take a moment to look at the variables and functions in the Node class to appreciate the capabilities provided to all of its subclasses, including bounds calculation and mouse and keyboard event handling.

    *    The CustomNode class enables you to create your own UI elements.

    *    The Group class is a subclass of the Node class whose purpose includes grouping nodes together into a single coordinate space, and allowing transforms (such as rotate) to be applied to the whole group.  Also, attributes of the group that are changed (such as opacity) apply to all of the nodes contained within the group.

There are several packages that begin with javafx.scene that contain subclasses of Node of various types.  For example:

    *    The javafx.scene.image package contains the Image and ImageView classes, which enables images to be displayed in the Scene.  The ImageView class is a subclass of Node.

    *    The javafx.scene.shape package contains several classes for drawing shapes such as Circle, Rectangle, Line, Polygon and Arc.  The base class of the shapes, named Shape, contains an attribute named fill that enables you to specify a color or gradient with which to fill the shape.

    *    The javafx.scene.text package contains the Text class for drawing text in the scene.  The Font class enables you to specify the font name and size of the text.

    *    The javafx.scene.media package has classes that enable you to play media.  The MediaView class is a subclass of Node that displays the media.

    *    The javafx.scene.chart package has classes that help you easily create area, bar, bubble, line, pie, and scatter charts.  The corresponding UI classes in this package are AreaChart, etc.

Although it doesn't begin with javafx.scene, the javafx.ext.swing package contains UI controls (such as SwingCombobox) that subclass Node.  Many of the Swing "components" are available in this package, and because these components are actually nodes, any of the transforms and other capabilities of Node are available with these classes.  Also, any Swing components that aren't in this package may be used in JavaFX by wrapping them with the wrap function of the SwingComponent class.

The javafx.scene.control package contains several UI controls,  each one having the ability to be skinned, and styled via CSS.  The Control, Skin, and Behavior classes in this package give you the ability to create your own skinned and CSS-styled controls.

The javafx.scene.transform package enables you to transform nodes (scale, rotate, translate, shear, and affine).

The javafx.scene.input package contains classes such as MouseEvent and KeyEvent that provide information about these events from within an event handler function such as the Node class' onMouseClicked event.

The javafx.scene.layout package contains several layout containers, including HBox, VBox, ClipView, Flow, Stack, and Tile .  The Container class in that package enables writing custom layout classes.

The javafx.scene.effect and javafx.scene.effect.light packages contain easy to use effects such as Reflection, Glow, Shadow, BoxBlur and Lighting.

The javafx.animation and javafx.animation.transition packages contain time-based interpolations typically used for animation, and convenience classes for common transitions, respectively.

The javafx.io.http, javafx.data.pull, and javafx.data.xml packages provide a way to communicate with servers via HTTP, JSON, and XML from any JavaFX enabled device (e.g. desktop and mobile phones).

The javafx.data.feed.atom, and javafx.data.feed.rss packages contain classes that facilitate reading Atom and RSS feeds, respectively.

The javafx.async package provide support for asynchronous processing.  Classes in this package are extended by classes such as HttpRequest to provide asynchronous capability.

The javafx.io package has classes that utilize local storage facilities of a machine without requiring that a JavaFX program be signed.

The javafx.util package contains several utility classes such as Math, Sequences, and Properties.

Take a look at the JavaFX API docs again in the light of the information above to get a deeper sense for how you can use its capabilities.

Congratulations to all in Sun and the JavaFX community that contributed to this JavaFX 1.2 release!  Also, be sure and read Inyoung Cho's JavaFX 1.2 Features and Enhancements article and Stephen Chin's JavaFX 1.2: Top 10 Excellent New Features and Migration Guide post.  Party on, Wayne!  Party on, Garth!

Jim Weaver


July 07, 2008

SequenceExample: Book Example Updated for JavaFX Script SDK

As I mentioned earlier in the Book Example Updated for JavaFX Script SDK: HelloJFX post, several of the upcoming blog posts are going to contain the examples from my JavaFX Script book, rewritten to work with the JavaFX SDK Technology Preview Release.  For your convenience, I'm placing these posts in the JavaFX Script Book Examples category. Today's post contains the SequenceExample program, which was developed to demonstrate creating and manipulating sequences.  Here is the console output when running the program:

The third planet is:Earth
Mercury is a planet in our solar system
Venus is a planet in our solar system
Earth is a planet in our solar system
Mars is a planet in our solar system
Saturn is a planet in our solar system
Neptune is a planet in our solar system

Inserting Uranus before Neptune
Inserting Jupiter after Mars
Inserting Pluto as the last planet
Inserting the Sun into the beginning
Sun is a planet in our solar system
Mercury is a planet in our solar system
Venus is a planet in our solar system
Earth is a planet in our solar system
Mars is a planet in our solar system
Jupiter is a planet in our solar system
Saturn is a planet in our solar system
Uranus is a planet in our solar system
Neptune is a planet in our solar system
Pluto is a planet in our solar system

Deleting the Sun in position 0
Querying for the indexof Pluto
Pluto is in position 8
Deleting Pluto
[ Neptune, Uranus, Saturn, Jupiter, Mars, Earth, Venus, Mercury ]

The 5 planets with more than 5 characters are:
    MercuryJupiterSaturnUranusNeptune

The 4 planets in the second half of the alphabet are:
    Venus,Saturn,Uranus,Neptune,

By the way, the eBook version of the JavaFX Script book is available for download from this Apress site.

The Updated Code for SequenceExample

Here is the code, updated by a colleague and JavaFX developer named Matt Shirey:

/*
*  SequenceExample.fx - An example creating a sequence literal and using
*                       some sequence related features of JavaFX to work
*                       with it.
*
*  Developed 2007 by James L. Weaver (jim.weaver at lat-inc dot com)
*
*  Updated July 2008 by Matt Shirey (matt.shirey at lat-inc dot com)
*  for JavaFX SDK Technology Preview 1
*/
package jfx_book;

import java.lang.System;

// Literally define the planets sequence, leaving out Jupiter and Uranus
var planets = ["Mercury", "Venus", "Earth", "Mars",
                       "Saturn", "Neptune"];

// Print out the third element in the array, which is element 2
// since arrays are zero-based.
System.out.println("The third planet is:{planets[2]}");

// Print out all planets by iterating over the planets sequence
for (planet in planets) {
  System.out.println("{planet} is a planet in our solar system");
}
System.out.println("");

// Insert Uranus before Neptune (which is currently in position 5)
System.out.println("Inserting Uranus before Neptune");
insert "Uranus" before planets[5];

// Insert Jupiter after Mars (which is currently in position 3)
System.out.println("Inserting Jupiter after Mars");
insert "Jupiter" after planets[3];

// Add Pluto to the end of the sequence.
System.out.println("Inserting Pluto as the last planet");
insert "Pluto" into planets;

// Add Sun to the beginning of the sequence
System.out.println("Inserting the Sun into the beginning");
insert "Sun" before planets [0];

// Print out all planets by iterating over a sequence that is the same
// size as the planets sequence, and reference the corresponding element
// in the planets array.
for (i in [0.. sizeof planets - 1]) {
  System.out.println("{planets[i]} is a planet in our solar system");
}
System.out.println("");

// Delete the Sun (which is currently in position 0)
System.out.println("Deleting the Sun in position 0");
delete planets[0];

// Query for the indexof Pluto and delete it
System.out.println("Querying for the indexof Pluto");
var indices = for (planet in planets
                       where planet == "Pluto") indexof planet;
System.out.println("Pluto is in position {indices}");
if (sizeof indices >= 0) {
  System.out.println("Deleting Pluto");
  delete "Pluto" from planets;
}

// Query for and print all of the planets run together in reverse order
var allPlanetsRunTogether = reverse planets;
System.out.println(allPlanetsRunTogether);
System.out.println("");

// Use for to query for all of the planets with more than 5 characters
var somePlanets:String[];
somePlanets = for (planet in planets where planet.length() > 5) planet;
System.out.println("The {sizeof somePlanets} planets with more than 5 characters are:
    {somePlanets}");
System.out.println("");

// Use for to query for all of the planets that begin with
// the letter "N" or later
somePlanets = for (planet in planets where planet.compareTo("N") >= 0) "{planet},";
System.out.println("The {sizeof somePlanets} planets in the second half of the alphabet are:
    {somePlanets}");

Running this Example

The JavaFX SDK Technology Preview branch of the compiler build may be downloaded here.  This branch is what will become the JavaFX SDK Preview Release.  After adding the openjfx-compiler-tp1/dist/bin directory to your PATH environment variable, and verifying that you have the Java Runtime Environment (JRE) 6 installed, use the following command at your operating system prompt to compile the program:

javafxc -d . SequenceExample.fx

To run the program, use the following command:

javafx jfx_book.SequenceExample

Have fun, and please post a comment if you have any questions!
Jim Weaver
JavaFX Script: Dynamic Java Scripting for Rich Internet/Client-side Applications

Immediate eBook (PDF) download available at the book's Apress site

July 06, 2008

HelloJFXBind2: Book Example Updated for JavaFX Script SDK

As I mentioned earlier in the Book Example Updated for JavaFX Script SDK: HelloJFX post, several of the upcoming blog posts are going to contain the examples from my JavaFX Script book, rewritten to work with the JavaFX SDK Technology Preview Release.  For your convenience, I'm placing these posts in the JavaFX Script Book Examples category. Today's post contains the HelloJFXBind2 program, which builds upon the HelloJFXBind program to demonstrate putting a model in its own file.  Here is a screenshot of the UI:

Hellojfxbind2

By the way, the eBook version of the JavaFX Script book is available for download from this Apress site.

The Updated Code for HelloJFXBind2

This example program is comprised of two files.   Here is the code, updated by a colleague and JavaFX developer named Matt Shirey:

HelloJFXBind2.fx

/*
*  HelloJFXBind2.fx - A JavaFX Script "Hello World" style example
*                     binding to a model that is located in its own file.
*
*  Developed 2007 by James L. Weaver (jim.weaver at lat-inc dot com)
*
*  Updated July 2008 by Matt Shirey (matt.shirey@lat-inc.com)
*  for JavaFX SDK Technology Preview 1
*/
package jfx_book;

import javafx.ext.swing.*;
import javafx.scene.*;
import javafx.scene.paint.*;
import javafx.scene.text.*;

/**
* This is a JavaFX Script that binds to data from the model.
*/
Frame {
  var hellojfxModel =
    HelloJFXModel {
      greeting: "Howdy JavaFX Script Developer!"
    }
  title: "JavaFX Script example that binds to a model"
  height: 100
  width: 400
  content:
    Canvas {
      content:
        Text {
          font:
            Font {
              name: "Sans Serif"
              style: FontStyle.BOLD_ITALIC
              size: 24
            }
          textOrigin: TextOrigin.TOP 
          // Put some color into the app
          stroke: Color.RED
          fill: Color.RED
          x: 10
          y: 10
          content: bind  hellojfxModel.greeting
        }
    }
  visible: true
}


HelloJFXModel.fx

/*
*  HelloJFXModel.fx - The model behind a JavaFX Script "Hello World" style
*                     example of binding.
*
*  Developed 2007 by James L. Weaver (jim.weaver at lat-inc.com)
*
*  Updated July 2008 by Matt Shirey (matt.shirey at lat-inc.com)
*  for JavaFX SDK Technology Preview 1
*/
package jfx_book;

/**
* This class serves as the model behind the user interface
*/
class HelloJFXModel {
  attribute greeting:String;
}

Running this Example

The JavaFX SDK Technology Preview branch of the compiler build may be downloaded here.  This branch is what will become the JavaFX SDK Preview Release.  After adding the openjfx-compiler-tp1/dist/bin directory to your PATH environment variable, and verifying that you have the Java Runtime Environment (JRE) 6 installed, use the following command at your operating system prompt to compile the program:

javafxc -d . *.fx

To run the program, use the following command:

javafx jfx_book.HelloJFXBind2

Have fun, and please post a comment if you have any questions!
Jim Weaver
JavaFX Script: Dynamic Java Scripting for Rich Internet/Client-side Applications

Immediate eBook (PDF) download available at the book's Apress site

July 05, 2008

HelloJFXBind: Book Example Updated for JavaFX Script SDK

As I mentioned earlier in the Book Example Updated for JavaFX Script SDK: HelloJFX post, several of the upcoming blog posts are going to contain the examples from my JavaFX Script book, rewritten to work with the JavaFX SDK Technology Preview Release.  For your convenience, I'm placing these posts in the JavaFX Script Book Examples category. Today's post contains the HelloJFXBind program, which builds upon the HelloJFX program to demonstrate binding the UI to a model.  Here is a screenshot of the UI:

Hellojfxbind

By the way, the eBook version of the JavaFX Script book is available for download from this Apress site.

The Updated Code for HelloJFXBind

Here is the code, updated by a colleague and JavaFX developer named Matt Shirey:

/*
*  HelloJFXBind.fx - A JavaFX Script "Hello World" style example
*                    binding to a model
*
*  Developed 2007 by James L. Weaver (jim.weaver at lat-inc.com)
*
*  Updated July 2008 by Matt Shirey (matt.shirey at lat-inc.com)
*  for JavaFX SDK Technology Preview 1
*/
package jfx_book;

import javafx.ext.swing.*;
import javafx.scene.*;
import javafx.scene.paint.*;
import javafx.scene.text.*;

/**
* This class serves as the model behind the user interface
*/
class HelloJFXModel {
  attribute greeting:String;
}

/**
* This is a JavaFX Script that binds to data from the model.
*/
var hellojfxModel =
  HelloJFXModel {
    greeting: "Hello JavaFX Script Developer!"
  };

Frame {
  title: "JavaFX Script example that binds to a model"
  height: 100
  width: 400
  content:
    Canvas {
      content:
        Text {
          font:
            Font {
              name: "Sans Serif"
              // Example of an attribute with a collection of values
              style: FontStyle.BOLD_ITALIC
              size: 24
            }
          textOrigin: TextOrigin.TOP 
          // Put some color into the app
          stroke: Color.RED
          fill: Color.RED
          x: 10
          y: 10
          content: bind  hellojfxModel.greeting
        }
    }
  visible: true
}

Running this Example

The JavaFX SDK Technology Preview branch of the compiler build may be downloaded here.  This branch is what will become the JavaFX SDK Preview Release.  After adding the openjfx-compiler-tp1/dist/bin directory to your PATH environment variable, and verifying that you have the Java Runtime Environment (JRE) 6 installed, use the following command at your operating system prompt to compile the program:

javafxc -d . HelloJFXBind.fx

To run the program, use the following command:

javafx jfx_book.HelloJFXBind

Have fun, and please post a comment if you have any questions!
Jim Weaver
JavaFX Script: Dynamic Java Scripting for Rich Internet/Client-side Applications

Immediate eBook (PDF) download available at the book's Apress site

July 03, 2008

Book Example Updated for JavaFX Script SDK: HelloJFX

In response to the The JavaFX SDK Packages are Taking Shape post, a reader named John writes: "I started with the examples in your nice book. However, I see that many things have changed in JFX since then. E.g. javafx.ui.* classes have been replaced by javafx.ext.swing.* classes? And of course many examples do not run. Will you create an updated source of the examples of the book that run with the latest JFX update?"

I responded in agreement, so the next several blog posts are going to contain the examples from my JavaFX Script book, rewritten to work with the JavaFX SDK Technology Preview Release.  The first one is the HelloJFX program, for which this is the UI:

Hellojfx

By the way, the eBook version of the JavaFX Script book is available for download from this Apress site.

The Updated Code for HelloJFX

Here is the code, updated by a colleague and JavaFX developer named Matt Shirey:

/*
*  HelloJFX.fx - A JavaFX Script "Hello World" style example
*
*  Developed 2007 by James L. Weaver (jim.weaver at jmentor dot com)
*
*  Updated July 2008 by Matt Shirey (matt.shirey@lat-inc.com)
*  for JavaFX SDK Technology Preview 1
*/
package jfx_book;

import javafx.ext.swing.*;
import javafx.scene.*;
import javafx.scene.text.*;

Frame {
  title: "Hello World-style example for JavaFX Script"
  height: 100
  width: 400
  content:
    Canvas {
      content:
        Text {
          font:
            Font {
              name: "Sans Serif"
              style: FontStyle.BOLD
              size: 24
            }
          x: 10
          y: 10
          textOrigin: TextOrigin.TOP
          content: "Hello JavaFX Script Developer!"
        }
    }
  // Show the Frame on the screen
  visible: true
}

Running this Example

The JavaFX SDK Technology Preview branch of the compiler build may be downloaded here.  This branch is what will become the JavaFX SDK Preview Release.  After adding the openjfx-compiler-tp1/dist/bin directory to your PATH environment variable, and verifying that you have the Java Runtime Environment (JRE) 6 installed, use the following command at your operating system prompt to compile the program:

javafxc -d . HelloJFX.fx

To run the program, use the following command:

javafx jfx_book.HelloJFX

Have fun, and please post a comment if you have any questions!
Jim Weaver
JavaFX Script: Dynamic Java Scripting for Rich Internet/Client-side Applications

Immediate eBook (PDF) download available at the book's Apress site

My Photo

Upcoming Speaking Engagements:


  • Stephen Chin and Jim Weaver speaking about JavaFX Platform

  • Speaking on JavaFX and Java at Øredev in Malmö, Sweden on 2-6 November, 2009

Upcoming JavaFX Training:


  • Developing Secure, Rich Internet Applications Hosted on a Variety of Clients Using JavaFX Technology

Enter your email address:

Delivered by FeedBurner

Available now as early access eBook


  • Click book image above to obtain eBook

Twitter Updates

    follow me on Twitter

    Affiliations:

    DZone Links:


    July 2009

    Sun Mon Tue Wed Thu Fri Sat
          1 2 3 4
    5 6 7 8 9 10 11
    12 13 14 15 16 17 18
    19 20 21 22 23 24 25
    26 27 28 29 30 31  

    Disclaimer:

    • By reading this site, you are agreeing that under no circumstances will Veriana Networks, Inc. or its affiliates be responsible for (1) any information contained on or omitted from the site, (2) any person's reliance on any such information, whether or not the information is correct, current or complete, (3) the consequences of any action you or any other person takes or fails to take, whether or not based on information provided by or as a result of the use of the sites.