
How many lines of Java do you need to create the following JavaFX application?
(Answer: About 30, as seen in Hello World, JavaFX Style)
And how many lines of (http://fxjs.java.net/) would you need?
(Answer: See below)
{T: fxStage, title: 'Hello World!',
scene: {T: fxScene, width: 300, height: 250,
root: {T: fxStackPane,
children: [
{T: fxButton, text: "Say 'Hello World'",
onAction: function (e) {println('Hello World!');}}
]
}
}
}
Yet another new format? No, look again ... plain old JavaScript, written with attention to just a few details. If you are even slightly familiar with FXML, the details must be clear already, but if you'd like to see a tutorial, look up the Language Guide.
A lines-of-code comparison with the raw Java in Hello World, JavaFX Style is not really fair, so lets move on to a comparison with some full-blooded FXML. But first a quick guided tour to help you understand the example ...
But wait, there's more!
The script shown above has a JavaScript function labelled onAction to handle button events. But how can you have code executed at startup?
{T: fxStage, title: 'Hello World!',
scene: {T: fxScene, fxid: 'theScene', width: 300, height: 250,
root: {T: fxStackPane,
children: [
{T: fxButton, text: "Say 'Hello World'",
onAction: function (e) {println('Hello World!');}}
]
}
},
main: function (args) {
if (args.length > 0) {
importPackage(Packages.javafx.scene.paint);
this.theScene.setFill(Paint.valueOf(args[0]));
}
}
}
The main(args)
function is executed at startup. It expects one command-line argument, the name of a color (that Paint.valueOf() can recognize), and sets the background of the Scene to that color. We added "fxid: 'theScene'
" to the Scene
object to give it a name that main()
can access. The following table shows the effect of running the script with skyblue and khaki respectively as a command-line argument.
java -cp ... fxjs.Main sample.js skyblue | java -cp ... fxjs.Main sample.js khaki |
![]() | ![]() |
Incidentally, if you are a JavaScript guru frowning at the "importPackage(...);
", you should take a lesson about a part of the JVM that is as threatened by neglect as its critically endangered namesake is by man's superstition and greed.
You can also add other application-specific functions and/or data alongside main()
(or in place of it). Code in functions and event-handlers can access these functions and data using the "this.name
" notation.
When you use the entire application lives in one file, no separate XML for the GUI, no Java launchers, stubs or glue files, and no build files to assemble everything. Just one warm and fuzzy ball of JavaScript. But if you need to, it's always possible to call out to Java as described in Application Architectures. You can find a bunch of
examples in More UI Examples.
Before moving on to the FXML comparison let's quickly find out how a script is run.
Running a
Script
Instructions for running a script can be found in the Quick Start Guide.
An FXML Comparison
Here is the translation of the application in Using FXML to Create a User Interface.
{T: fxStage, title: "JavaFX Welcome",
scene: {T: fxScene, width: 300, height: 275,
root: {T: fxGridPane, vgap: 10, hgap: 10, alignment: fxCENTER,
padding: {T: fxInsets, top: 25, right: 25, bottom: 25, left: 25},
stylesheets: "file:Login.css",
children: [
{T: fxText, id: "welcome-text", text: "Welcome",
font: {T: fxFont, name: "Tahoma", size: 20},
rowIndex: 0, columnIndex: 0, columnSpan: 2, rowSpan: 1},
{T: fxLabel, text: "User Name:", rowIndex: 1, columnIndex: 0},
{T: fxTextField, rowIndex: 1, columnIndex: 1},
{T: fxLabel, text: "Password:", rowIndex: 2, columnIndex: 0},
{T: fxPasswordField, rowIndex: 2, columnIndex: 1},
{T: fxHBox, spacing: 10, rowIndex: 4, columnIndex: 1,
alignment: fxBOTTOM_RIGHT,
children: [{T: fxButton, text: "Sign in", onAction: function (e) {
this.actiontarget.setFill(fxFIREBRICK);
this.actiontarget.setText("Sign in button pressed");}}]},
{T: fxText, fxid: "actiontarget", rowIndex: 6, columnIndex: 1},
]
}
}
}
Before trying to run this example, copy Login.css and background.jpg into the directory containing the script.
The FXML approach uses three separate files, and a number of naming and coding conventions that must be used to express the linkages between them. Which do you prefer?
The
Project
An open-source project for has been started at "http://fxjs.java.net/". The interpreter, source-code, documentation, and sample applications are available at the project site. The volume of documentation and examples is still growing, but there's already enough to help you get started. Take a look!
Curious about the name?
Like many other parents (that live on my side of the planet), I consulted the recommended lists, books, astrological sites, and sundry quacks, and narrowed things down to guise and disguise. Both contained "gui", and were strangely mysterious enough to satisfy the eastern penchant for unusual names. But guise was too similar to guice. And, though the gui in disguise was a neat hint, it didn't really show that the newborn was destined to follow in the footsteps of systems that use JavaScript in unexpected ways. Long live !