Articles
Java Platform, Standard Edition
|
|
| By James L. Weaver, April 2008 |
|
The previous article of this series, Creating Rich Internet Applications With Compiled JavaFX Script Technology, covered how to develop, compile, and run a simple JavaFX Script technology-based program. The article examined the program in detail and discussed several JavaFX Script concepts.
This article builds on that information and contains an example program that will help you understand more JavaFX Script concepts. This example program focuses on teaching you to use the following user interface (UI) components available in JavaFX Script technology:
BoxColorChooserDialogMenuMenuBarMenuItemSimpleLabelTextFieldAlong the way, you'll learn how to do the following:
Compile and run the SomeBasicWidgets.fx program using the instructions in the previous article. Figure 1 shows the window that should appear.
|
Figure 1: The Application's Main Window
|
Note that the O in Options is underlined. This indicates a mnemonic key, which enables the user to select this menu by simultaneously pressing the Alt key and the underlined character on the keyboard. Select the Options menu either by clicking on the word Options or by pressing Alt-O on the keyboard. You should now see the Options menu drop down as shown in Figure 2.
|
Figure 2: The Options Menu
|
As with the Options menu, each of the menu items has a mnemonic key. Additionally, two of the menu items have accelerator keys, in this case Ctrl-T and Ctrl-S, which give the user a quick way to select these menu items. Selecting the Text menu item causes the dialog box shown in Figure 3 to appear.
|
Figure 3: The Enter Text Dialog Box
|
Use this dialog box to edit the text that is to appear in the application's main window, then approve the change by either clicking OK or pressing Enter. As you'll soon see, the OK button is the default button, which is why Enter activates it. If you want the program to disregard your changes, either click the Cancel button or press Esc.
Now type A horse of a different color into the text field, and click OK or press Enter. The dialog box closes, and the main window of the application should look like Figure 4.
|
Figure 4: The Application's Main Window With Different Text
|
From the Options menu, choose Select Color. The color chooser dialog box in Figure 5 appears. Now you can choose a different color for the message.
|
Figure 5: The Color Chooser
|
Choose a color that is different from the current color of blue, perhaps red, and click OK or press Enter. The message in the window now appears in the color that you chose.
Following is the source-code listing for the SomeBasicWidgets.fx program:
/*
* SomeBasicWidgets.fx - A compiled JavaFX Script program that
* demonstrates some basic UI components
* available in compiled JavaFX Script
* technology
*
* Developed 2008 by James L. Weaver (jim.weaver at lat-inc.com)
* to serve as a compiled JavaFX Script technology example.
*/
package mypackage;
import javafx.ui.*;
import javafx.ui.canvas.*;
import java.lang.System;
class Model {
attribute messageText:String;
attribute messageColor:Color;
}
Frame {
var model =
Model {
messageText: "JavaFX Script has lots of cool UI components"
messageColor: Color.BLUE
}
var msgTF:TextField =
TextField {
value: model.messageText
columns: 30
background: Color.WHITE
}
var dlg:Dialog
title: "Some Basic UI Components"
width: 600
height: 200
background: Color.WHITE
visible: true
menubar:
MenuBar {
menus: [
Menu {
text: "Options"
mnemonic: KeyStroke.O
items: [
MenuItem {
text: "Text..."
mnemonic: KeyStroke.T
accelerator:
Accelerator {
modifier: KeyModifier.CTRL
keyStroke: KeyStroke.T
}
action:
function():Void {
dlg =
Dialog {
modal: true
title: "Enter Text"
visible: true
content:
Box {
orientation: Orientation.VERTICAL
content: [
SimpleLabel {
text: "Text:"
},
msgTF
]
}
buttons: [
Button {
text: "OK"
defaultButton: true
action:
function():Void {
model.messageText = msgTF.value;
dlg.hide();
}
},
Button {
text: "Cancel"
defaultCancelButton: true
action:
function():Void {
dlg.hide();
}
}
]
};
}
},
MenuItem {
text: "Select Color..."
mnemonic: KeyStroke.S
accelerator:
Accelerator {
modifier: KeyModifier.CTRL
keyStroke: KeyStroke.S
}
action:
function():Void {
ColorChooser {
title: "Choose Text Color"
initialColor: bind model.messageColor
showDialog: true
action:
function(color:Color):Void {
model.messageColor = color;
}
}
}
},
MenuItem {
text: "Exit"
mnemonic: KeyStroke.X
action:
function():Void {
System.exit(0);
}
},
]
}
]
}
content:
Canvas {
content:
Text {
font:
Font {
face: FontFace.MICROSOFT_SANS_SERIF
style: FontStyle.BOLD;
size: 24
}
x: 20
y: 40
stroke: bind model.messageColor
fill: bind model.messageColor
content: bind model.messageText
}
}
onClose:
function():Void {
System.exit(0);
}
}
|
Now let's examine the source code, focusing on the concepts introduced in this article.
JavaFX Script is a declarative scripting language that is also fully object-oriented. You can define your own classes as shown in the following excerpt from the example program:
class Model {
attribute messageText:String;
attribute messageColor:Color;
}
|
This very simple class is named Model and contains two attributes that hold
The type of each attribute is defined following the colon ( :) after the attribute name.
Classes may also contain functions, which future articles in this series will discuss. Additionally, class, attribute, and function declarations can have access modifiers, such as public, private, and protected.
The following code excerpt from the declarative expression that defines the UI creates an instance of the Model class. It assigns a reference to that instance to a variable named model.
var model =
Model {
messageText: "JavaFX Script has lots of cool UI components"
messageColor: Color.BLUE
}
|
The model reference variable will enable the program's UI to stay in sync with the attributes in the Model class.
TextField Component The following code excerpt from the program creates a TextField component and assigns its reference to a variable named msgTF.
var msgTF:TextField =
TextField {
value: model.messageText
columns: 30
background: Color.WHITE
}
|
This variable will be used later in the program to ascertain what the user entered in the text field. Table 1 contains some useful attributes in the TextField class.
|
Public Attribute
|
Type
|
Description
|
|---|---|---|
action |
Event handler
function() |
Called when the user presses Enter.
|
columns |
Number |
The width, in columns, of the text field.
|
editable |
Boolean |
Controls whether the text is editable.
|
enableDND |
Boolean |
Controls whether drag and drop is enabled.
|
horizontalAlignment |
HorizontalAlignment |
The horizontal alignment of the text in the field: leading, center, or trailing.
|
margin |
Insets |
Sets the margin around the text field.
Insets has four attributes expressed in pixels: top, bottom, left, and right. |
onChange |
Event handler
function(String) |
Called when the user changes the contents of the text field. The changed text is passed into the function.
|
selectOnFocus |
Boolean |
Controls whether the text is selected when the field receives focus.
|
text |
String |
The content in the text field that the user is typing.
|
value |
String |
The value in the text field after it has lost focus or after the user has pressed Enter.
|
The TextField class is a subclass of the Widget class. Consequently, the TextField class inherits the Widget attributes listed in Table 2. Note that several other components are derived from the Widget class, so this article will refer back to Table 2.
|
Public Attribute
|
Type
|
Description
|
|---|---|---|
background |
AbstractColor |
The background color of this component
|
focusTraversalKeysEnabled |
Boolean |
Controls whether the user can land on this component by way of a focus traversal key, such as Tab
|
font |
Font |
The font in which the text in this component is rendered
|
foreground |
AbstractColor |
The foreground color of this component
|
name |
String |
The name that you assign to this component
|
toolTipText |
String |
The tooltip text that is displayed when the mouse hovers over this component
|
visible |
Boolean |
Controls whether the component is visible
|
To give you an overall view of the classes and attributes covered in this article, Figure 6 contains a portion of the compiled JavaFX Script class hierarchy.
|
Figure 6: A Portion of the Class Hierarchy With Some Useful Attributes
|
Here is an excerpt from the program that creates its menu structure:
menubar:
MenuBar {
menus: [
Menu {
text: "Options"
mnemonic: KeyStroke.O
items: [
MenuItem {
text: "Text..."
mnemonic: KeyStroke.T
accelerator:
Accelerator {
modifier: KeyModifier.CTRL
keyStroke: KeyStroke.T
}
action:
function():Void {
...some code omitted...
}
},
MenuItem {
text: "Select Color..."
mnemonic: KeyStroke.S
accelerator:
Accelerator {
modifier: KeyModifier.CTRL
keyStroke: KeyStroke.S
}
action:
function():Void {
...some code omitted...
}
},
MenuItem {
text: "Exit"
mnemonic: KeyStroke.X
action:
function():Void {
System.exit(0);
}
},
]
}
]
}
|
Let's take a look at each of the menu-related classes used in this program.
As the preceding code excerpt shows, to create menus in a Frame, you must first create an instance of the MenuBar class and assign it to the menubar attribute of the Frame. The MenuBar class extends the Widget class, so the attributes in Table 2 apply to the MenuBar as well. Table 3 contains the most frequently used attribute in the MenuBar class.
|
Public Attribute
|
Type
|
Description
|
|---|---|---|
menus |
Menu[] |
The top-level menus on this
MenuBar |
To create menus on the MenuBar, assign them to the menus attribute of the MenuBar. To assign multiple objects to an attribute, use array literal notation, which consists of comma-separated values enclosed in square brackets. Note that arrays are called sequences in JavaFX Script technology.
As you can see in the preceding code excerpt, Menu components have several available public attributes, including the ones listed in Table 4.
|
Public Attribute
|
Type
|
Description
|
|---|---|---|
items |
AbstractMenuItem[] |
Holds menu items, as described in the next section. This attribute can also hold
Menu components so that multilevel menu structures can be defined. |
mnemonic |
KeyStroke |
Specifies a key that you can use in conjunction with the Alt key to invoke that menu, in this case the letter O, which is represented by the constant value
KeyStroke.O. |
text |
String |
The label is on the
Menu, in this case on the word Options. |
The Menu is a descendant of the Widget class, so the attributes in Table 2 apply to the Menu class as well.
As seen in the Text menu item in the preceding code excerpt, to create menu items on a Menu, you assign them to the items attribute of the Menu component by using array literal notation. MenuItem components have several available attributes, including the ones listed in Table 5.
|
Public Attribute
|
Type
|
Description
|
|---|---|---|
accelerator |
Accelerator |
Defines a shortcut key for invoking the menu item, which is defined with the help of the
modifier and keystroke attributes of the Accelerator class. In this case, the shortcut key combination is Ctrl-T. |
action |
Event handler
function() |
Defines the function to be invoked when the action event occurs -- that is, when the user selects this menu item. To accomplish this, you must assign an anonymous function to the
action attribute. Note that because the function associated with the action attribute does not return anything, it is defined with a return type of Void. |
icon |
Icon |
An icon to be displayed on the menu item.
|
mnemonic |
KeyStroke |
Specifies a key that you can use in conjunction with the Alt key to invoke that menu item, in this case, the letter T, which is represented by the constant value
KeyStroke.T. |
text |
String |
The label on the
MenuItem, in this case, the string Text... |
The MenuItem is a descendant of the Widget class, so the attributes in Table 2 apply to the MenuItem class as well. Also note that a MenuItem is a leaf or end node in a menu structure. It cannot contain other menu item widgets.
One of the strengths of JavaFX Script technology is its ability to leverage the power of Java technology. You can see a small example of this in the following function, which is invoked when the user chooses the Exit menu item.
function():Void {
System.exit(0);
}
|
The exit() method of the java.lang.System class is invoked, which causes the program to exit. To identify the System class to this program, you must use an import statement:
import java.lang.System; |
The following excerpt from the program shows another example of invoking the exit() method of the System class as a result of an event happening:
onClose:
function():Void {
System.exit(0);
}
|
The function assigned to the onClose attribute of the Frame is invoked when the frame closes. This ensures that the program exits when the user clicks the Close button of the frame.
JavaFX Script technology has full interoperability with Java technology, so it can instantiate Java classes, invoke methods, and access static and instance variables.
Table 6 contains a list of useful attributes in the Frame class.
|
Public Attribute
|
Type
|
Description
|
|---|---|---|
background |
AbstractColor |
Sets the background color of the frame.
|
centerOnScreen |
Boolean |
Causes the frame to be centered on the screen.
|
content |
Widget |
The UI component that the frame contains. The component is stretched to fill the entire frame.
|
height |
Number |
The height, in pixels, of this frame.
|
menubar |
MenuBar |
An optional menu bar on the frame.
|
onClose |
Event handler
function() |
Defines the function to be invoked when the dialog
onClose event occurs, that is, when the dialog box is closing. To accomplish this, you must assign an anonymous function to the onClose attribute. Note that because the function associated with the action attribute does not return anything, it is defined with a return type of Void. |
onOpen |
Event handler
function() |
Defines the function to be invoked when the dialog
onOpen event occurs, that is, when the dialog box is opening. To accomplish this, you must assign an anonymous function to the onOpen attribute. Note that because the function associated with the action attribute does not return anything, it is defined with a return type of Void. |
title |
String |
The string that will appear in the title area of the frame.
|
visible |
Boolean |
Controls whether the frame is visible.
|
width |
Number |
The width, in pixels, of this frame.
|
As demonstrated in the previous article, JavaFX Script technology has a simple dialog box named MessageDialog that presents a message to the user. But you can also define your own dialog boxes to enable the user to provide more complex input. To do so, use the Dialog class as shown in the following excerpt from the program:
dlg =
Dialog {
modal: true
title: "Enter Text"
visible: true
content:
Box {
orientation: Orientation.VERTICAL
content: [
SimpleLabel {
text: "Text:"
},
msgTF
]
}
buttons: [
Button {
text: "OK"
defaultButton: true
action:
function():Void {
model.messageText = msgTF.value;
dlg.hide();
}
},
Button {
text: "Cancel"
defaultCancelButton: true
action:
function():Void {
dlg.hide();
}
}
]
};
|
This declarative expression makes an instance of a Dialog, giving it the content and buttons shown in Figure 3. This expression is assigned to a variable so that the hide() function of the Dialog class can be invoked when the user clicks one of the buttons. The variable named dlg was declared earlier in the following statement:
var dlg:Dialog |
Notice that the attributes for the Dialog class are very similar to those of the Frame class. One additional attribute is used in this dialog box: modal. If its value is true, the dialog box must be dismissed before the user can interact with the underlying application.
As shown in the previous code excerpt, you use the Box layout component to make the SimpleLabel appear directly above the TextField. Recall that the TextField instance is assigned to the msgTF variable. The SimpleLabel component is just that: a simple label that can contain text and/or an icon.
Table 7 contains some useful attributes in the SimpleLabel class.
|
Public Attribute
|
Type
|
Description
|
|---|---|---|
icon |
Icon |
A
SimpleLabel can contain an icon, text, or both. This attribute causes an icon to be displayed. |
text |
String |
The text string displayed in this
SimpleLabel. |
The Box layout component enables you to stack components either vertically or horizontally. Table 8 contains some useful attributes in the Box class
|
Public Attribute
|
Type
|
Description
|
|---|---|---|
content |
Widget[] |
The UI components that the
Box contains. The components retain their preferred sizes. |
orientation |
Orientation |
The orientation of the content placed in the
Box, for example, horizontal and vertical. |
Now turn your attention to the buttons. If the defaultButton attribute is true, then pressing Enter causes the button to be activated. Similarly, if the defaultCancelButton attribute is true, then pressing Esc activates the button. In this program, when the user enters a text string into the text field and clicks OK or presses Enter, the value of the text field is assigned to the messageText attribute of the model object.
Table 9 contains a list of useful attributes in the Dialog class.
|
Public Attribute
|
Type
|
Description
|
|---|---|---|
buttons |
Button[] |
The buttons that will appear in the dialog box.
|
content |
Widget |
The UI component that the dialog box contains. The component is stretched to fill the entire dialog box, excluding the area reserved for buttons.
|
height |
Number |
The height, in pixels, of this dialog box.
|
modal |
Boolean |
Determines whether this dialog box must be dismissed before the user can interact with the application.
|
onClose |
Event handler
function() |
Defines the function to be invoked when the
dialog onClose event occurs, that is, when the dialog box is closing. To accomplish this, you must assign an anonymous function to the onClose attribute. Note that because the function associated with the action attribute does not return anything, it is defined with a return type of Void. |
owner |
UIElement |
Indicates the UI element to which the dialog box belongs. This is especially useful when
modal is true, because then the dialog is modal to its owner. |
title |
String |
The string that will appear in the title area of the dialog box.
|
visible |
Boolean |
Controls whether the dialog box is visible.
|
width |
Number |
The width, in pixels, of this dialog box.
|
Developers often say, "Once you use binding, you'll never go back." JavaFX Script technology was designed with the innate ability to implement the model-view-controller (MVC) pattern. You can easily keep the view (UI) and the model (data) of a program in sync through the use of the bind operator.
In this example program, as soon as the messageText attribute is changed, the content attribute of the Text graphical object changes as well, because it is bound to the messageText attribute as shown in this excerpt:
Text {
font:
Font {
face: FontFace.SANSSERIF
style: FontStyle.BOLD;
size: 24
}
x: 20
y: 40
stroke: bind model.messageColor
fill: bind model.messageColor
content: bind model.messageText
}
|
Similarly, the stroke and fill attributes of the Text graphical object are bound to the messageColor attribute of the model object. Next you'll see how to use the ColorChooser component to enable the user to change this messageColor attribute.
ColorChooser UI Component The ColorChooser component is a very easy-to-use but powerful UI component that enables the user to choose a color. Take a look at the following code excerpt from the program to see how to use it:
ColorChooser {
title: "Choose Text Color"
initialColor: bind model.messageColor
showDialog: true
action:
function(color:Color):Void {
model.messageColor = color;
}
}
|
The initialColor attribute of this class controls the default color selected when the color chooser appears. When the user clicks OK or presses Enter, the chosen color is passed to the anonymous function and then assigned to the messageColor attribute of the model instance. Because of binding, this causes the stroke and fill attributes of the Text graphical object to hold the newly chosen color. If you chose the color red, for example, then the main application window should look like Figure 6.
|
Figure 6: The Application's Main Window With the Text in the Chosen Color
|
Table 10 contains some useful attributes in the ColorChooser class.
|
Public Attribute
|
Type
|
Description
|
|---|---|---|
action |
Event handler
function(Color) |
Defines the function to be invoked when the action event occurs, that is, when the user clicks OK or presses Enter. To accomplish this, you must assign an anonymous function to the
action attribute. The color passed into this function is the one that the user selected in the ColorChooser. |
initialColor |
Color |
The color that will be selected by default when the color chooser appears.
|
selectedColor |
Color |
The color that the user has selected.
|
title |
String |
The string that will appear in the title area of the color chooser.
|
In this article, you have learned how to do the following:
TextField, Dialog, SimpleLabel, and ColorChooser UI components.MenuBar, Menu, and MenuItem instances, giving them mnemonic and accelerator keys as appropriate. You also learned to create an anonymous function that defines what will happen when the user chooses a MenuItem.Model.exit() method of the java.lang.System class.James L. (Jim) Weaver is the CTO at LAT, Inc. and a Java Champion. He writes books, speaks for groups and conferences, and conducts a JavaFXpert BootCamp. His latest book is JavaFX Script: Dynamic Java Scripting for Rich Internet/Client-Side Applications . He also posts daily to a blog whose purpose is to help the reader become a "JavaFXpert."