I’ve spent a while learning JavaFX and developing an application which is now live. I’ve written about the application itself over on the Guardian’s Open Platform blog, because it makes use of the Open Platform’s Content API. But in this blog post I want to write less about the application and more about my experiences with the JavaFX technology.
In this article:
- What is JavaFX?
- The language (good)
- Development support (ugly)
- The user experience (bad)
- Conclusions and (inevitable) comparison with Flash
JavaFX is probably best viewed as Sun’s answer to Flash, just as Silverlight is Microsoft’s response. So it’s a way of developing rich internet applications, or embedding fancy graphical thingies into web pages.
In some sense Sun might not have had any need for JavaFX. For example, take a look at We Feel Fine. This is an astonishingly beautiful and imaginative application, and though it might look like it’s been written as Flash it’s actually a Java applet.
So why did Sun feel the need for adding to Java? According to JavaFX’s creator, Chris Oliver, “its purpose was to explore making GUI programming easier in general”. In other words, the Java language is not really optimised for GUI development. In addition, the language needs a number of libraries. But all of this compiles down to Java bytecode and runs on the JVM, so JavaFX is really just Java with special add-ons to make graphical-oriented applications easier.
The most obvious initial difference with JavaFX is the language that comes with it: JavaFX Script. As implausible as it sounds Sun has combined the best bits of Javascript and Java, and come up with something really rather wonderful. Consider the following code snippet from my application:
ring = Circle { centerX: bind bubble.x centerY: bind bubble.y radius: bubble.diameterInScene / 2 opacity: 0.0 fill: null stroke: BUBBLE_INDICATOR_COLOUR };
This creates a thin ring, which is actually just a circle with an outline and no fill. It starts off being invisible (opacity 0). The variable ring
was declared on a previous line and is initialised here. I think this simple piece of code demonstrates a number of really nice things about the language. First, the code Circle { ... };
. This is a constructor, which I really like. It feels lightweight, like Javascript, and it’s got Javascript’s named properties. But like Java, JavaFX Script is a statically typed language, so ring
is of type Circle
and if I forget this later on in my development then the compiler will signal an error — that error won’t make it into production. Second, the most exciting addition: the bind
keyword. This means that the formula that follows will change dynamically when any of its component parts changes. So the x co-ordinate of the ring’s centre is bound to bubble.x
— the x
property of the variable bubble
, which is the x co-ordinate of its centre. Similarly for the y co-ordinates. Now I know that the ring will always be centred on the bubble: whenever I update the bubble’s position the ring’s position will change, too. As one of our team’s developers explained when I started telling him about JavaFX binding (in fact he didn’t even let me finish my sentence) it’s just perfect for a GUI-oriented language where you want the view to track the model. Another great feature of the language is its native handling of timelines. For example, here’s a piece of code I use to fade something in or out over a period of half a second:
Timeline { repeatCount: 1 keyFrames: [ at (0.5s) { this.opacity => targetOpacity } ] }.play();
This constructs a Timeline
with a single keyframe (at the half second point), and JavaFX is told that by that point the opacity needs to be at the target opacity. On calling the play()
method it will interpolate the object’s opacity value so that it fades in or out accordingly. Needless to say, you can have several keyframes, and interpolate several values simultaneously or in sequence.
You can also ensure specific actions at certain points. Here is some code which fades a message out, changes it, and fades it back in again. This mixes native timeline syntax with more usual JavaFX syntax:
Timeline { repeatCount: 1 keyFrames: [ at (0.5s) { barText.opacity => 0.0 } KeyFrame { time: 0.5s action: function():Void { barText.content = message; } } at (1.0s) { barText.opacity => 1.0 } ] }.play();
You might also notice from this that functions are treated as a first class object: another very handy feature of the language.
As you might expect from a Java extension JavaFX integrates well with Java: you can use any Java class or object in your JavaFX code. In my case I wrote a small physics engine in Java and then accessed it via my JavaFX code; it was trivial to do.
On the other hand, JavaFX classes and methods can’t be accessed from Java without a lot of jumping through hoops (you have to create an interface in Java, implement it in JavaFX, and then you can reference that interface in your Java code). Also, Java generics aren’t available in JavaFX, which is a bit of loss.
The JavaFX platform itself is evolving. Version 1.0 was released in December 2008. Version 1.1 came out in February 2009 and changed not only the underlying libraries, but also the language, so even your source code needed be revised. Most recently version 1.2 came out in May 2009, with similar changes and similar consequences.
Overall, these changes are a very good thing. Each new version contains not only extra front-end features (charting capabilities appeared in 1.2) but also performance enhancements and changes which ensure greater API consistency and extensibility. It’s interesting to see Sun take a different approach from Java: there the remit has been to preserve backwards compatibility at all costs, because there are so many applications deployed in it, but JavaFX is still in its infancy and breaking backwards compability is a significantly lesser evil than consistency and extensibility. Nevertheless, the feeling is of a platform that’s yet to mature, and my productivity was knocked back by one or two platform bugs whose equivalents just wouldn’t be be dreamt of in, say, Java. Still, JavaFX is clearly actively evolving, and most certainly for the better.
More disappointing is the poor IDE support. Inevitably, support for Sun’s NetBeans is being actively pursued alongside the evolving platform. But my first experience with JavaFX in NetBeans earlier in 2009 found it to be an imperfect environment, and I opted to switch to Eclipse — I decided I could live with more quirks in return for a more familiar working environment. And after some considerable hassle I got it working.
But Eclipse support really is poor: there are a few annoyances documented over on pliq.com, and I found a few more. Overall it meant that even typing code was a bit of a minefield, and that’s without refactoring support.
There is also the inevitable problem with unit testing graphically-oriented applications. I admit I resorted to the old fashioned develop-debug cycle, which was a little disappointing and inevitably frustrating. But I can’t quite conceive of a unit test framework for a platform in which there is so much visually-oriented code. I suspect it would mean a slightly different approach to coding. My brain can’t quite work out what, though.
So developers have problems. Let’s pretend not to worry about them; their entire lives revolve around solving problems so they’ll find ways to solve those. Much more important is the experience of end users, and with Sun boasting that Java runs on “800 million desktops” (isn’t that more than the number of atoms in the universe…?) those people’s experience is paramount.
Well, if you’re running the right environment then the JavaFX experience isn’t at all bad. Unfortunately you’re very unlikely to be running in the right environment…
Sun have done an excellent job in making it simple and reliable to embed your applet into a web page: once you’ve configured your code you only need some very simple and clear JavaScript in your page. This JavaScript takes care of platform versioning, prompts the user for an update if necessary, shows a standard “Loading…” animation, and downloads and runs your code.
In the circumstances this clever; but the circumstances are far from ideal. For example, when did you last update your JVM? Probably not recently enough to have the latest JavaFX release, so your first use of a 1.2 application is going to prompt you for a very large download of the JavaFX 1.2 runtime. You’re also going to need to run a launcher applet from Sun, which then prompts you with a popup requesting you trust software from Sun. Anyone who wants a seamless user experience is going to take one look at JavaFX and run a mile.
Even if you’ve already got the 1.2 runtime and launcher applet the JavaScript embed code itself references a script on Sun’s website. That means your web page is always relying on Sun’s website being up, running and performant in order to load. For code on my own little blog that’s fine — Sun’s uptime will always be more reliable than mine. But if this is to be adopted by bigger players, such as my own employer, the Guardian, then the sysadmins responsible for page delivery time and reliability won’t be happy with another third party dependency.
And if you’re not impressed with that, then I hope you’re not an Apple user. Java support for Macs has long lagged behind that of Windows machines (I recall the Java 5 SDK came out over a year after the Windows release) and this shows again with JavaFX. In theory JavaFX runs on a Mac. In practice it’s a world of pain: it’s slow and rendering features such as antialiasing are dire. Experiments show that if you’re running a very high end Mac then it’s half-way approaching decent, but not actually decent.
As someone who spent a long time developing this on a Windows machine it was very disspiriting to see the fruits of my labour reduced to a syrupy judder when I wanted to demo it to someone with a Mac.
Conclusions and (inevitable) comparison with Flash
If Flash didn’t exist then my view of JavaFX would be different. But Flash does exist, it’s the dominant RIA platform — certainly within web pages — and so any view of JavaFX has to be assessed in that context.
I find it very amusing that Adobe and Sun have eyed up each others’ territory and each wanted a piece of the other’s action. Adobe has wanted to move out of the web page and onto the desktop, so they’ve introduced AIR, while ActionScript has gone all serious, ditching the JavaScript-like version 2 for the Java-like version 3, and encouraging a cavalcade of grown-up design patterns. Meanwhile Sun has left behind that heavyweight baggage of the Java programming language and gone all JavaScripty, with easy constructor syntax, type inference and treating functions as first-class objects. They’ve each adopted the other’s clothes, but changing clothes is only part of what’s needed.
For my money JavaFX Script is the superior language. It’s designed for graphics creation and management, while ActionScript looks like Java before generics. The code I’ve found online to draw shapes in ActionScript brings back nightmares from the early days of writing Java applets: get a graphics object, set some properties, start the filling, do the drawing, stop the filling… it’s unintuitive, uphill work. (What the hell is a “graphics object”, anyway?) With JavaFX you use a constructor like the one shown above.
Mind you, there’s a reason for this difference. Flash development is predicated on the use of some really well-developed proprietary, commercial tools to do the job: Flash Professional for designers and Flex Builder for application developers. Looking for an ActionScript Hello World program produces some entertaining results. Here’s one conversation in which the request for a Hello World app is met with incomprehension: can’t you just drop the text on the stage? asks one responder, who misses the point of a programming tutorial; I suppose you could use the trace function to print the text out, suggests someone else. Here’s an ActionScript Hello World tutorial which includes the instruction “Select the Text Tool…”. There is a purely programmatic tutorial which Andrew Payne created because “The other examples I could find all used Adobe’s paid tools, Flash Designer, etc.” — but that was written only in January 2009.
So Flash is deeply embedded into design houses, which have come to rely on some very mature tools in which programming is secondary, particularly when it comes to asset creation. And while this might make more traditional developers smile it does demonstrate the cultural chasm that seperates Flash from JavaFX. Designers demand a first rate user experience, or else their work won’t sell itself. That means Flash execution doesn’t suffer the popup bombardment of JavaFX. And it means Flash runs just as well on a Mac as on a PC. And it means Flash developers have become obsessed with performance in a way that JavaFX developers can’t even imagine, so there’s an entire mindset which has yet to be addressed. And it means component support in JavaFX is lacking where in Flash it’s commonplace. One example of this is the lack of a JavaFX preloader: with Flash it’s standard to have a progress bar as the application loads; with JavaFX the standard preloader is an animated image that continues to animate even if there’s a background error, and I can’t find any code which shows a progress bar. Another is the ease in which one Flash swf can load another; again, not readily possible in JavaFX.
Designers would also bring a huge benefit to JavaFX beyond setting high bars for user experience: they are the people who will make JavaFX applications look beautiful, and so attract others’ interest, and so start a rolling snowball of adoption. I think my own application is quite pretty, but it was quite different in the early stages. It was only when I studied and tried to emulate the work of the Guardian’s professional designers that it started to come alive: circles were a friendlier shape than rounded rectangles, the palette of guardian.co.uk was infinitely prettier than my original palette of browns, and so on.
Sun is not unaware that this cultural gap needs to be bridged. That will be one reason why they’ve created JavaFX Production Suite. But years of cultural awareness and workflow embedded into design studios’ daily operations will be very, very hard to reverse.
So my own thoughts about JavaFX reflect my own experience with it. My development experience was very positive: it’s a great language and a mediocre development environment with many teething troubles which will no doubt be ironed out over time. I had terrific fun with it, and getting fast results was very rewarding. But beyond the development experience the future seems more difficult. The user experience is very poor, with JavaFX throwing up barriers in front of the non-technical end user where Flash is invisible. And the leap from niche developer interest to general acceptance by design studios is just enormous.
Making JavaFX a real success is huge job for Sun. They’ve got off to an excellent start, with a language and runtime environment that allow for very quick development. But that, alas, is the easy bit compared to what lies ahead. I do wish them the very best of luck.
Wow, great write up. I found this site while googling for JavaFX. Added to RSS
10^80 atoms in the universe :)
Hopefully Java 7 helps solve some of the problems you have listed.
Hmm, I tried it on a Mac, and it wasn’t so bad. I did have to click two OK buttons to install JavaFX (which took under ten seconds) — but if I didn’t have Flash installed, I’d get the equivalent prompts.