OK, JavaFX Script is pretty cool (the platform is still boring though)
Despite my last post, I’m not actually a raving anti JavaFX maniac - the script language itself is really pretty cool. I’ve been following what would become JavaFX script since when it was called F3, and have been impressed by what it can do. Both in terms of the language syntax, and the power it gives you in certain areas.
It is very Swing friendly, and the technically, the current version provides a lot of functionality to make life easier building Swing apps. Which kinda reinforces to me that that the JavaFX as an RIA *platform* reeks of “me too!” from Sun’s marketing department in response to Flex and Silverlight.
JavaFX’s homepage will tell you that “JavaFX Script is a highly productive scripting language for content developers to create rich media and interactive content” - which I don’t quite follow. Cause it’s Swing. And while Swing is really good at regular GUIs (once you get your head around the massive API and the traps for new players), it’s got pretty weak support for “rich media and interactive content” (whatever that means) unless you are someone like Romain Guy and have time and talent to come up with a bunch of cool hacks and work around more than a few limitations with the technology.
While I’m dubious of the potential of the platform, I think the scripting language itself is one of the most interesting things to happen around Swing in a long time. It comes about as close as anything to the dream framework I talked about in JRuby Can Save Swing. It’s a pity that Sun didn’t push it in the desktop app direction, but I guess straight desktop apps just aren’t that sexy at the moment…
Anyway, here’s a quick round up of some the “kick ass” bits in JavaFX Script that caught my attention. The JavaFX Script Programming Language contains details on most of the core concepts. It’s not 100% complete, as there are a few other tidbits in the demos and the tutorial examples that show other features.
Calling Java Objects
OK, this one is kinda a no brainer. If it didn’t do this there would be trouble. I’m mentioning it just because it means you’ve got a lot of existing Java libraries you can hook in without much hassle. Scripting in the JVM is the other big buzz concept these days (and with good cause).
Cardinality Operators On Variables
When declaring a variable, you can add the following operators:
- ? - optional. may be null (not sure if things that don’t have ? are non-nullable or not?)
- + - one or more
- * - zero or more
By themselves these are just another way of declaring arrays, but they tie in nicely with…
Inverse Attributes
Sure, JavaFX Script has your standard OO structure with classes and attributes that everyone knows and loves. The cool part is that you can define bi-directional inverse relationships. The effect is that when the instance on one end of the link is updated, the other end is updated in turn - kind of like cascading foreign keys. This example is the example given on the reference page:
class Person {
attribute name: String;
attribute parent: Person inverse Person.children;
attribute children: Person* inverse Person.parent;
function getFamilyIncome(): Number;
function getNumberOfChildren(): Number;
operation marry(spouse: Person);
}
The idea is that when a child is added to a parent, the parent value is automagically set. When a child’s parent is changed (in some strange circumstance…), the child is automagically added to the list of children on the parent object.
Array Manipulation
There is some nice syntax for working with arrays of objects as well. It all feels very SQLish. You can insert like SQL with insert myFoo first into barArray to insert in the first position, or insert myFoo after barArray[.=='foo'] to insert myFoo after whatever item in the array has the value of ‘foo’.
Or you can delete like SQL with delete barArray[.=='foo'] to remove the item with the value of ‘foo’ from the array. (The inverse attribute magic hooks in with these apparently)
You can even select like SQL (or like functional list comprehensions) with select name from album in albums where artist == "Nine Inch Nails" (there is a similar construct with foreach as well).
Pure Functions
Not really something you couldn’t do in plain old Java if you wanted to (except without the side effect guarantee), but it’s interesting that pure functions are supported as well. A pure function just has variable declarations and a return statement - which makes sure that pure functions don’t have any nasty side effects, and can be used in a functional programming style. Don’t worry, there are still regular procedures in there as well, which are called “operations” instead.
Incremental and Lazy Evaluation
This is a really nice touch, and will be one of the things that makes Swing a pleasure to work with. The bind operator will cause one variable to be “bound” to the other. When the value of the original is changed, the bound variable is automatically updated with the new value. This makes binding GUI views and models together super easy. Here’s some more code from the tutorials page which shows it off:
class HelloWorldModel {
attribute saying: String;
}
var model = HelloWorldModel {
saying: "Hello World"
};
var win = Frame {
title: "Hello World JavaFX"
width: 200
content: Label {
text: bind model.saying
}
visible: true
};
What this means is that whenever the value of saying in the model instance changes, the GUI Label is automagically updated - no need for messy listener glue code.
Now it gets even cooler. You can even bind strings that contain embedded expressions - similiar to using the "Hello, I'm #{name}" syntax in Ruby. When the value of a variable in a bound string changes, the variable it is bound to changes as well:
class HelloWorldModel {
attribute saying: String;
}
var model = HelloWorldModel {
saying: "Hello World"
};
var win = Frame {
title: bind "{model.saying} JavaFX"
width: 200
content: TextField {
value: bind model.saying
}
visible: true
};
And whenever the value of model.saying changes, the title is automagically updated!
Triggers
Related to bind (at least for Swing), is the use of triggers. When a value is changed on a JavaFX script GUI widget, a trigger is fired to set the text etc on the underlying Swing component. There are no custom setters or getters in JavaFX Script, but you can define custom behaviour using triggers. These are pretty similar to a database trigger. It’s really just some code that gets executed whenever a variable on a class instance is changed
Swing Event Dispatch Thread Support
As every Swing developer gets beaten into them DO NOT MESS WITH THE EVENT DISPATCH THREAD. For the non Swing readers, the Event Dispatch Thread (or EDT for short) handles all user input and rendering in a separate thread to the main app thread. In particular, it’s considered bad form to execute long running tasks on it (users have to wait a long time for response to their action and the GUI appears locked). And it’s also bad to update the GUI directly from a thread other than the EDT (Swing components aren’t thread safe).
This is a pain in regular Swing. There are a few frameworks for handling background operations (SwingWorker etc), and you can use the helper methods in SwingUtilities to safely interact with the EDT from other threads. But it means constructing awkward Runnable instances, usually as verbose anonymous inner classes, and passing them around.
JavaFX Script has some nice syntax sugar to take care of this. The do block allows you to execute a block of code asynchronously in another thread to the EDT (avoiding GUI lock up).
import java.lang.StringBuffer;
// in the AWT EDT
var input = getInput();
var calcResult = new StringBuffer();
do {
// now in a background thread
calcResult.append(doHeavyCalculationWithInput(input));
}
// now back in the EDT
System.out.println("result = {calcResult}");
This will cause the heavy calcuation to be done in a separate thread, while the EDT can carry on rendering and accepting user input (actually that’s not quite true as there is a hack with the EventQueue involved - but close enough). There are some gotchas with it though, so it would pay to read up on how it works first.
The other piece of this puzzle is the do later block which is executed in a piece of code running in a separate thread to update the GUI in a threadsafe manner. The idea is that your background thread goes off and does work, then when it is ready to display the results, it executes some code in a do later block to safely populate it to the GUI.
Conclusion
All up, there is some interesting stuff in JavaFX Script. I’ll have to have a play with it some more as it develops. Although I still don’t get the marketing blitz, the ease it should add to Swing development will be a welcome addition.
There is even a webstart sandbox app that lets you play around with the language and instantly see the results. Well worth checking out.
May 23rd, 2007 at 7:25 pm
You say the platform is boring, that might very well be, but you can still use all the power of Java 2D (maybe even 3D in the future?) to make interesting interfaces (as seen in some of the F3 demos).
On the other hand I must say I’ve never seen any good interfaces made with Flash, they might be nice-looking, even gorgeous, but actually usable? Not really.
Mind you, I’ve not looked into these Flex and Silverlight things so I’m only talking from personal experience with the Flash junk I’ve encountered over the years on the web.
So in the end I think you either need a usable GUI and use something like Swing or you want something flashy and make your own Java2D generated GUI elements.
May 23rd, 2007 at 8:29 pm
Quintesse - I totally agree. From what I can see, everything in JavaFX(aka F3) is based around the features already in Swing. I guess my point is that there is a lot of song and dance about JavaFX as a platform, but at a technical level it really isn’t adding anything that isn’t there already.
Which is why it’s odd to me that it’s being pushed as something other than a nicer way to build Swing apps (which is a great selling point by itself).
I also agree that most Flash interfaces are pretty, but unusable - but it almost seems that JavaFX is being positioned as being part of that market. Which is odd as well, as it could provide so much more!
May 24th, 2007 at 1:25 am
Sure, it’s reusing Java2D and Swing, but Java2D is a pretty powerful API that not a lot of people seem to master.
I could have done this clock example in Java2D easily, but I’m getting lots of comments about how simple the code looks in JFX. So there’s something there.
Plus, don’t forget that J2D doesn’t have a 2D “scenegraph”. I wish that had been added a long time ago (should still make it into Java outside of jfx).