In my previous post I mentioned the idea of using JavaFX for the Chunky GUI. Chunky currently uses the Swing toolkit for its GUI, and JavaFX is aiming to replace Swing eventually. I was interested in using JavaFX because it seems to have better cross-platform consistency. I have now done some exploratory development using JavaFX 8, and I want to share my thoughts so far.
What JavaFX does right
Consistency between platforms is the reason I wanted to try JavaFX. I made a clone of part of the Chunky GUI in JavaFX and tried running it on Windows 10, OSX, and Linux, and it looked the same on each OS. That’s awesome, it’s exactly what I wanted. Here is a screenshot of the GUI running on Windows 10:
Another great thing about JavaFX is that it’s possible to separate layout from behavior. In Swing the only way to build a GUI was to write code that constructs each element manually. There did exist layout editors for Swing, but they all behaved differently and they generated ugly code that got mixed with the application code. Using Swing layout editors was sometimes a useful first step when building a GUI, but I always ended up having to code everything by hand because after I had made changes to the generated code the layout editor no longer could edit the layout. I really hate working with Swing layouts by manual coding but that’s what I had to do mostly.
JavaFX solves the layout editing problem by using XML files to define the layout. The layout is edited with a program called Scene Builder. Separating the layout from the code in this way means that you can continue using the layout program even after you edit the code – because they are separate. It is still possible to edit GUI elements via code if you need to, but it no longer has to be the main way to construct a GUI. Graphical editing is so much better for building GUIs! Here is a screenshot of the Chunky GUI in Scene Builder:
Although it’s nice to remove the manual coding of GUI layouts, it is of course necessary to wire up the GUI components to code that can make them do useful things. Coding with JavaFX is easier than with Swing thanks to a much nicer API. For example:
- JavaFX uses functional interfaces for all callbacks which makes it easy to set up callbacks with lambdas in Java 8. In contrast Swing callbacks are grouped into listeners with multiple callbacks per listener.
- Listening for modifier keys is supported in JavaFX with proper focus handling. In Swing you have to handle modifier keys for the whole application.
- It is very easy to bind variables in the application to JavaFX GUI elements by wrapping the value in a JavaFX property.
A few other points about JavaFX that I like:
- Customizable tooltips that can be built individually and placed anywhere.
- Much improved color pickers.
- Simpler file chooser API.
Things JavaFX needs to improve
My overall impression of JavaFX so far is quite positive, but I do have some gripes about JavaFX which I hope get fixed in the future. Below are three things that I hope will be changed/improved.
API additions between major Java releases
Some new API methods have been added to JavaFX 8 after the Java 8 release. For example you can call
ChoiceBox.setOnAction() in Java 8 update 60, but it won’t compile or run on older Java 8 version. Adding things like this in Java updates means developers like me can end up unknowingly relying on a specific Java 8 release. I hate this and it’s a stupid idea. One of the cornerstones of Java is backward compatibility, and it should not be jeopardized for small API improvements. APIs must be stable so that you can rely on them. There is nothing more annoying than compiling a Java 8 program, and then trying to run it on another machine with Java 8 installed only to find out that it doesn’t work!
No image scaling without interpolation
JavaFX provides a
drawImage method that can scale images, but it does so by using a blurring interpolation mode and there is no way to change the interpolation mode. This causes undesirable blurring when the image is enlarged. In Swing this worked just the way I wanted, but in JavaFX I have to implement my own scaling code just to fix this annoying behavior.
Feedback is very important in a user interface. The feedback needs to be delivered as fast as possible. In JavaFX when I hover over a button it takes a short while before the highlight that indicates the button is hovered appears. This may seem like a nitpicky complaint, but it is important to me that GUIs are responsive and right now JavaFX on Windows does not feel responsive enough. On the other hand I have noticed a huge performance regression in Swing based GUIs on Windows 10 recently making them lag ridiculously much. At least JavaFX is a little better than Swing on Windows 10 right in that respect.