Review: JavaFX and FXML

So I’ve been experimenting with UI development in JavaFX.  I initially was coding UIs by hand, to avoid introducing a dependency on any tool.  But I decided I rather like Oracle’s Scene Builder tool and FXML.  I’m not enamored of the idea of editing FXML by hand, although it’s nice that you can tweak it when necessary, and it makes a nice standardized serialization format for UI tools like Scene Builder.  Since Oracle is supporting it going forward, FXML is a stable format, and it’s nice that I can use it without being locked into a particular UI builder.  If someone makes a tool that beats the socks off of Scene Builder on day, and it supports FXML, I’ll be able to switch seamlessly.

After playing around with various approaches, I’m settling into a pattern for my current Scala application.  Part of the challenge is that there are so many ways to build a UI application in JavaFX that it’s not obvious which one to choose.  Here’s what is working for my desktop application:

I’m not using “pure” Model-View-Controller (MVC) with observers and binding to models all over the place.  Frankly, I think that’s overkill for many applications, though I see the value of it for large ones.  Magical bindings that update values back and forth are slick in simple cases (when you don’t need them anyway) but a haven for bugs in complex cases… I think they should be avoided unless the benefit is strongly needed (and it sometimes is).  So I’m using a “Flow Synchronization” approach, which fits well with the type of application I’m writing.

On the other hand, I am trying to make the two key separations that Martin Fowler describes as fundamental to MVC: between model and view/controller, and (secondarily) between the view and controller.  In Scala style, my model objects are either immutable or minimally-mutable.  The views are created in Scene Builder and stored in FXML, then loaded in a way that keeps this detail abstracted from the UI code.  The controller code, handling events and input, is then cleanly separated from layout code.  JavaFX has the nice touch of being able to style UIs with CSS, whether they are built through FXML or not.

Overall, I’ve been quite happy using JavaFX from Scala, even without the fun bindings in ScalaFX.  (I like their work, but I wasn’t ready to commit to a dependency for this application.)  I like being able to design UIs with a builder tool and load them cleanly and transparently from code, then use the concise and typesafe syntax of Scala to write the controlling code.

Evil JVM feature optimizes away error information

The other day I ran across a tricky bug in the Flying Saucer PDF generation library.  It’s been pretty useful so far, but it does not seem to be under active development, so it has the occasional stale bug. In this case, our designer tried to use “display: table”, which crashes Flying Saucer R8.  Workaround is to use a different “display” property, like “display: block”.

The really annoying part was researching the bug.  The JVM includes an “optimization” that causes it to lose stack trace information for repeated exceptions in some cases.  So the server log showed “Caused by ClassCastException” but without any trace.  You can disable this “optimization” with the JVM argument XX:-OmitStackTraceInFastThrow .  I keep using apologetic quotes because I think there is something terribly wrong with optimizing exception control flow at the expense of debugging information.  If your application is throwing exceptions all over the place, you probably want to do something about that, and having the stack trace can make a world of difference.  In the case above, it cost me hours of debugging time (since I had never heard of this “feature” previously, I assumed it was a problem in our codebase), when once I had the stack trace it only took a few minutes to figure out.

Personally I would rather never see this “optimization” used, but at the very least I think it should not be enabled by default.