Note: This post has been superseded by the HelloJFXBind: Book Example Updated for JavaFX Script SDK post.
Also, if you've been directed here by a blog post citing this JavaFX demo as one that "just look[s] a bit nasty", please take a look at the Watch for Falling Blocks: Take TetrisJFX for a Spin post. The Tetris example is meant to look more appealing, as opposed to being a very basic example of binding in JavaFX Script. By the way, I very much appreciate the spirit in which Matt Stephens wrote that article, and agree with his sense of urgency. Thanks Matt!
Now that you’ve learned some JavaFX concepts by running and examining the HelloJFX.fx code in a previous post, I’d like to introduce you to some more concepts. You’ll get a taste of what it is like to create classes and objects in JavaFX, as well as how to create variables and use constants. You’ll also learn about a deceptively simple but powerful concept in JavaFX: binding a view to a model. Let’s walk through these concepts in the context of the HelloJFXBind application, which builds on the previous application.
Running and Examining the HelloJFXBind Application
Run the HelloJFXBind.fx program in your JavaFX tool of choice; the output should be a
window that looks something like the following screen shot:
Now let’s examine the source code for the HelloJFXBind.fx Program, making special note of the added
concepts:
package jfx_book;
import javafx.ui.*;
import javafx.ui.canvas.*;
/**
* 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 {
faceName: "Sans Serif"
// Example of an attribute with a collection of values
style: [
BOLD,
ITALIC
]
size: 24
}
// Put some color into the app
stroke: red
fill: red
x: 10
y: 10
content: bind hellojfxModel.greeting
}
}
visible: true
}
Structure of a Minimal JavaFX Class
One of the first differences you’ll notice from the previous example is that this program defines a class named HelloJFXModel in the following lines of code:
class HelloJFXModel {
attribute greeting:String;
}
This is a very minimal class, as it doesn’t have many of the possible characteristics (which you’ll learn about later), but it’s a good place to start.
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 modify the class keyword.
attribute Declarations
There is one attribute in the HelloJFXModel class, named greeting, and its data type is String. As mentioned previously, an attribute is a variable that is associated with an object. When instances of this class are created, each one will be able to hold a string named greeting.
Note: As shown in the example, there is a third type of comment used in JavaFX files, called Javadoc comments. These comments start with the /** characters and end with the */ characters. Their purpose is to support automatic generation of documentation for Java classes, and I anticipate that there will be tools created for JavaFX that use Javadoc-style comments to generate documentation for JavaFX classes.
Making an Instance of the Class
Now that the HelloJFXModel class has been defined, the program goes on to create an instance of that class using the same declarative syntax that was used earlier to create a UI:
var hellojfxModel =
HelloJFXModel {
greeting: "Hello JavaFX Script Developer!"
};
The greeting attribute of this new instance contains a string with the value of Hello JavaFX Script Developer!.
Declaring and Assigning Variables
As just shown, the program uses the var keyword to declare a variable named hellojfxModel. Using an assignment operator (=), this variable is assigned a reference to a newly created instance of the HelloJFXModel class. You’re going to need the hellojfxModel variable a little later to get a reference to this instance. It is worth noting that you should always assign a value to a variable declared with the var keyword before using it. There are rules and conventions for the names that you give to variables (identifiers that are declared with either the var or attribute keywords):
- The rules: Variables must begin with a letter, an underscore character (_), or a dollar
sign ($). Subsequent characters in the variable name can be numbers, letters,
underscore characters, or dollar signs. - The conventions: Variables start with a lowercase letter, don’t usually have
underscores, never contain dollar signs, and consist of one or more camel case words.
Numbers are used where appropriate. For example, the variable used in the
HelloJFXModel class is named greeting. A variable that holds the name of a planet
could be named planetName.
Variable names can be as long as practical, and should convey meaning. In addition, variables, like most everything in JavaFX, are case-sensitive.
Understanding Binding
Please jump down in the current example to the declaration of the Text object, shown here:
Text {
font:
Font {
faceName: "Sans Serif"
// Example of an attribute with a collection of values
style: [
BOLD,
ITALIC]
size: 24
}
// Put some color into the app
stroke: red
fill: red
x: 10
y: 10
content: bind hellojfxModel.greeting
}
There are some new concepts in this block of code (the code between any opening curly brace and its matching closing curly brace is called a block). The concept I’d like to point out now is binding the view (user interface) of an application to the model (data) of the application. In the last line of code, you’ll notice that the content attribute of the Text instance contains the bind operator. This results in binding (incrementally updating) the content of the Text instance with the greeting attribute of the HelloJFXModel instance. If the greeting attribute changes, JavaFX will automatically cause the content of the Text instance to change, resulting in the immediate update of the message displayed in the application. The following graphic represents this binding behavior, with the containment hierarchy of the UI components on the left side, and a class diagram of the HelloJFXModel class on the right side.
Assigning Color Constants to the Text Object
JavaFX has many predefined constants for your use, as well as support for creating your own constants. Here, I’d like to point out how to assign constants in your code. In the following code snippet from the current example, notice that the stroke and fill attributes of the Text object are both assigned the color red:
Text {
font:
Font {
...some code omitted...
}
// Put some color into the app
stroke: red
fill: red
x: 10
y: 10
content: bind hellojfxModel.greeting
}
The stroke attribute for any graphical element, including this Text object, defines the color that the outline will have. The fill attribute for any graphical element defines the color with which the area inside the outline will be filled.
The Paint class in JavaFX currently has about 140 predefined constants that represent colors. Here are some of these constants:
- red
- green
- blue
- yellow
- orange
- black
- white
- lightblue
- lemonchiffon
- lightgoldenrodyellow
Assigning an Array of Values to an Attribute
Arrays (also known as sequences) are the main data structures in JavaFX. At this point, I’d like to just broach the subject by showing you how to create and assign an array to an attribute in declarative code. In the following code snippet from the current example, the style attribute of the Font object is being assigned two values, which you probably have guessed correctly are constants:
Font {
faceName: "Sans Serif"
// Example of an attribute with a collection of values
style: [
BOLD,
ITALIC]
size: 24
}
The style attribute of the Font class accepts one or more values, and to represent those
values, an array is literally being defined here. As shown in the preceding code snippet, an
array literal consists of an opening square bracket, followed by comma-separated elements,
followed by a closing square bracket. The available constants for the style attribute of the
Font class are as follows:
- BOLD
- PLAIN
- ITALIC
Summary
In this post you've learned how to create a simple JavaFX class, and have experienced the power and elegance of binding attributes to a model. This post, by the way, is an excerpt from my recently published book entitled "JavaFX Script: Dynamic Java Scripting for Rich Internet/Client-Side Applications", which is available from Apress.
Regards,
James L. (Jim) Weaver
Joseph,
Excellent point! I'll make sure that we cover event handling in future posts.
Thanks,
Jim Weaver
Posted by: James Weaver | November 02, 2007 at 10:51 AM
I'm sure people will want to get into event handeling, so here is a little code extension on what happens if the click on the text.
Text {
font:
Font {
...some code omitted...
}
// Put some color into the app
stroke: red
fill: red
x: 10
y: 10
content: bind hellojfxModel.greeting
onMouseClicked: operation (CanvasMouseEvent) {
//-- do something like print click
//-- make sure you have import System.out.*; before hand
println("Clicked");
}
}
Posted by: Joseph Montanez | November 02, 2007 at 05:00 AM