JFXtras: lessons learned developing in JavaFX

JFXtras is my pet open source project. I like visual things, and HTML and CSS are way to frustrating, so I’m running with JavaFX. Since 2012 I’ve been submitting controls to it, simple ones at first; the ListSpinner, then the CalendarPicker (date picker), and eventually Agenda (Google Calendar) and gauges. Doing this has resulted in many satisfying moments when a control worked, but the road to that point was littered with many chunks of frustration and sometimes even scrapping whole controls and restarting on them (Agenda has three iterations).

Writing these controls in JavaFX 2 and later has teached a lot of lessons; things that work, things that didn’t work, or worked better than others, and in the end resulted in a few best practices. It’s not like I have all the wisdom on JavaFX or anything, but being on this for so long, well, at least some commonalities were found. So during Christmas holiday 2014 some of this knowledge was wrapped up in a small 1 – 1.5 hour presentation / talk, touching on some of JavaFX’s strong points, slip ups and other topics like code structure and testing JavaFX applications. It’s titled: “Lessons learned developing in JavaFX”, or “Let us make your mistakes for you”.

I gave the presentation three times and after incorporating the feedback, decided to submit it to a number of conferences. To my amazement the talk was not selected by any of them, based on that JavaFX is not interesting enough for the intended audience.

Ok. That was unexpected.

So following the three-strike-out rule, I’ve decided to not submit it to conferences anymore, and put my energy elsewhere (probably back in developing more JFXtras controls or testing JavaFX on mobile). But letting that presentation collect dust is not sitting right. So, if anyone feels like it would be of interest, if it fits in my schedule and I don’t have to lose money over it… I’m glad to run it again!

Below are the first two slides.

jfxtrasSlide1 jfxtrasSlide2

The whole presentation in PDF can be found here
JFXtras presentation

Posted in Java, javafx, jfxtras, UI | 5 Comments

JFXMobile – first attempt follow up

The previous post contains a detailed log of my adventure in getting a JavaFX application running on Android. It highlights the initial hurdles, the amazement how easy it was once those hurdles were taken, and comes with the conclusion that I need a new hardware.


Turns out I do not need a new hardware.


Besides the date picker my application will also need an editable table. So continuing the HelloWorld test, I added one. Tables are never simple, but after you have done JTable, TableView is a breeze. After compilation it started on the Nexus without a hick and was very responsive!

Ok, but a TableView is not a simple component! If Jonathan is able to get that thing working responsive, why isn’t JFXtras’ CalendarPicker responsive? I mean, I admire and respect the magic mr. Kiwi does with the controls in JavaFX, and do not pretend to know half as much about that as he does… But a two second sluggish response?! Boundaries have to be drawn, limits need to be set! ;-)


So I revisited the source code of the skin of calendar picker, and did some analysis. It was the second component I wrote for JavaFX and has undergone MANY refactorings. Turns out it could use a bit more. Some events were listened to, but did not contribute anything. Some code could be a bit less, ah, British (as they call it).

And after a good 30 minutes of tuning, things still ran on the desktop as they should, but on the Nexus it was a major difference! Instant responses to a click! Wow!

A desktop is very forgiving if code is not optimal, and on Android it does not have to be perfect, but a bit of tuning really pays off!

I do not need a new hardware after all…

Posted in Java, javafx, jfxtras, UI | 2 Comments

JFXMobile – first attempt

Who would not like to be able to write a single code base for desktop and mobile? I know I want to, and the applet I’m using for time registration is getting into a pinch with all the browsers dropping support for applets, so why not give JavaFX a try? And see if things go as smoothly as Gluon’s tweets make it sound?

So, first things first and setup a nice virtual machine for this project with Java and Eclipse, hookup the old 1st gen Nexus 7, then download the HelloWorld demo project from Gluon. Finally a “gradlew androidInstall” should do the trick…

But no such luck!

Execution failed for task ':dex'.
> org.gradle.api.GradleException (no error message)

Dex fails and without an error message. Great! But luckily --debug shines a light on the problem: dex is started with a default of Xmx=2g, and I’m still in the habit of installing 32 bit Java, even if I run a 64 bit operating system. And 2g for a single process is a problem then.

But what is the best solution? Either 64 bit Java needs to be installed, and I often run into issues with that, or dex needs to be convinced to run with a lower Xmx. Some researching into Gluon’s JFXMobile plugin reveals that the android block has a subblock called dexOptions, where the javaMaxHeapSize can be defined; and 1024m works just fine.


And look at that: one HelloWorld JavaFX application running on my Nexus 7 Android tablet! Startup time ain’t bad at all either.

Next step: including JFXtras. The application I intend to write needs a date picker and being the guy behind JFXtras, well, I of course want to use my own library. The dependency is added quickly to the build.gradle file, the HelloWorld application quickly changed to add a CalendarPicker next to the Label, and redeploy!

com.android.dx.cf.iface.ParseException: InvokeDynamic not supported

Que??? Oh… Right… Android uses Java 7, and JFXtras 8.0 uses Java 8, including Lambda’s.
I forgot.

It would be an option to use JFXtras 2.x, which is Java 7 based, but it is so old, I really want to use the 8.0 branch.

Luckily there is a tool called RetroLambda, which apparently allows backporting of lambda’s to Java 7. It’s an easy include in the build.gradle script, so let’s give it a try. 

Compile is still ok, good, good, and…

com.android.dx.cf.iface.ParseException: InvokeDynamic not supported

Eh??? Ah… RetroLambda’s only processes the active project, being the HelloWorld application, not dependencies like JFXtras. So JFXtras needs to be RetroLambda-ed as well. Hm. Thread carefully there, I’m not the only one using it. So let’s just install that 8.0-R5-SNAPSHOT in the local Maven repository only.

JFXtras compiling is ok… Let’s see if JFXtras samples runs under Windows…

default method found in version 50.0 classfile

Ah. Yeah. It would have been too good to be true. RetroLambda is actually generating Java 6 classfiles, but those can’t handle default methods in interfaces used a.o. by JFXtras’ Agenda.

But again RetroLambda might offer a solution: it has a rudimentary implementation for default methods, activated by:

retrolambda {

Compile is ok… Running samples… Hey! That actually seems to work! Samples are coming up. Interesting! 

Alright! Let’s try and build the HelloWorld on Android again.


I’ll be damned! It works! Those month and year ListSpinners need to have their arrows moved to opposing sides (with the -fxx-arrow-position CSS property), but for the rest it looks quite ok.

Let’s click a bit… Oh… That is sluggish. The time between the touching of the screen and the calendar picker actually responding is almost 2 seconds. I know my aging Nexus 7 isn’t the fastest, but… No… Actually that seems accurate for other apps as well. I need a new hardware.

That was not too hard at all. I probably stumbled into everything that reasonably can go wrong, but I do that all the time, being a bug magnet and all. The performance is a bit of a concern, let’s see what a newer tablet does.

What really worries me is the RetroLamda. Don’t get me wrong, it’s a great tool, but having to postprocess Java 8 files is not very promising for the future… What will happen when Java 9 with JigSaw comes out in 2016? Oracle and Google really need to get their heads out of each other’s b*tts and stop blocking progress.

For Oracle having the penetration on mobile hardware that Android has, is just free ‘presence’, so stop wining about it. Android and Java were was already in place before you became the boss of Java. Use the situation to your advantage, instead of frustrating the ecosystem.

OTOH Google seems a bit short sighted that it won’t let Oracle be part of that ecosystem by compromising. Open source is not for everyone, and having to switch to some other programming platform besides the JVM (class files need not be written in Java after all) is in many ways a step back. I, for one, would not mind something like a 1% fee on my Android hardware, in order to get regular updates of official Java on Android. Or a pay-per-update (of the JVM) model. It should be possible to have separate updates of the JVM available for apps. Some companies simply have different earning models, there must be a common ground somewhere.

Anyhow. To be continued…

Posted in Android, Java, javafx, jfxtras, Lambda | 2 Comments

Enzo’s simple gauge in JFXtras

Gerrit Grunwald is an enspiring internet of things (IoT) evangelist and his JavaFX library ‘Enzo’ contains many visually attractive controls, well suited for IoT but also many other JavaFX applications. Gerrit used to be an active contributor to JFXtras, but he decided to move his work to his Enzo library. Why? Because the scope of JFXtras did not fit his needs.

As an IoT evangelist he develops many JavaFX controls for his demos, and he wants to get results fast; there is always that next conference in a few days.  JFXtras on the other hand tries to uphold a certain quality by a.o. requiring tests to prevent regression. This is not something a roaming evangelist wants to invest his time in. So we end up with an interesting situation; great but risky controls! Examples of this are all the gauges that are part of JFXtras-labs 2.x: they were never ported to 8.x and thus all their users have a problem there. This of course is the risk of using anything from JFXtras-labs, it is after all JFXtras’ playground, with no guarantee what-so-ever.

So what now? Great controls but too risky to touch? For Enzo that may be the case, as Gerrit states on his blog; “Please keep in mind that all controls in that library are made for my personal demos and are not production ready”. However, Gerrit and I have an agreement that I’m allowed to become ‘inspired’ by (aka blatantly copy) his demos. This already happened with CornerMenu, which was inspired by one of Gerrit demo’s and spawned CircularPane and CirclePopupMenu. The next inspiration Gerrit gave me was his SimpleGauge.


The control you see above is from  JFXtras and is known as SimpleMetroArcGauge and it (at the time of writing this) is part of JFXtras-labs. Currently it is in the process of fleshing out the API, which will be much more minimalistic than SimpleGauge, relying more on stylesheets. And also the concept of a single LinearGauge superclass is tried. After all, there is more to a good gauge than just a beautiful face.

When the gauge is finished, tests are written, and a sample is added to the samples, the gauge will move from labs to a new “gauge” module of JFXtras.

So there you have the explanation why suddenly Enzo controls start appearing in JFXtras.

Posted in Uncategorized | 7 Comments

circle popup menu

And once you are able to layout things in a circle…

Besides the CornerMenu described in the previous post, another incarnation of CircularPane is the CirclePopupMenu. It, as the name suggests, pops up a circle shaped menu on a mouse press.


And since it is based again on CircularPane, several animation options are available and others can be created manually. A few examples are:

circlePopupMenu-appear circlePopupMenu-fromOrigin circlePopupMenu-overTheArc

CirclePopupMenu is available in JFXtras-8.0-SNAPSHOT-r2. And like CornerMenu; let me know how it works in real world applications.

Posted in Java, javafx, jfxtras, UI | Leave a comment

corner menu

A few months back I had the pleasure of attending the multidevice presentation by Gerrit Grunwald (@hansolo_). In this presentation he demonstrated how easy it was to port a single JavaFX code base to several devices, including Android, iOS, RasberryPi, and a few more. One of the UI elements he showed on each device was a corner menu; circular icons appearing from the corner of a window. This was visually a great UI component, and Gerrit told me it was part of his Enzo library. The Enzo library is full of such visually appealing JavaFX controls and components, and freely available to everyone who wants to use them, but it is also the case that Enzo mainly exists to support Gerrit in his presentations and demonstrations. And there is a difference between a control intended for public use and one that is a result of a demonstration. So when I asked Gerrit if I could take his control and move it over to JFXtras, he agreed immediately.

The first order of business was to layout stuff in a 90 degree arc. And I could have just copied Gerrit’s code, but as things go in a hobby project I decided that this should be something reusable, so CircularPane was born.


It took some time to get it working correctly; creating a general purpose pane for laying out stuff in a circle dynamically is not as trivial as it seems. But after a few weeks it got to the point where CircularPane was mature enough, a demo was available, and it was unit tested. After that, work could finally start on one of the primary things it was created for: CornerMenu. (Although the fact that a round shaped Android watch will come out soon, may turn out to be a nice coincidence.)

So CornerMenu is exactly what it says: a menu that is located in any of the four corners of a window. The menu can be static, but usually it will show the items when the mouse comes close to the corner, like so:


Because CornerMenu is leaning heavy on CircularPane, it also supports configurable animations. Build-in are “from origin” (which can be seen above) and “over the arc” (below), both are based on the animations defined in CircularPane, but in CornerMenu some transparency and rotation is added.


CornerMenu uses the standard MenuItem class of JavaFX, so starting to use it should be very straight forward. The main difference is that in CornerMenu the graphic of a MenuItem is mandatory, while in regular menu’s only the text is.

	// position a corner menu in the top left corner, that initially is not visible
	CornerMenu cornerMenu = new CornerMenu(CornerMenu.Location.TOP_LEFT, stackPane, false)

	// add the menu items
	cornerMenu.getItems().addAll(facebookMenuItem, googleMenuItem, skypeMenuItem, twitterMenuItem, windowsMenuItem);

CornerMenu is available in JFXtras-8.0-SNAPSHOT-r2. I’m very curious how it will work out in real world applications, so if anyone uses it, drop a line in the comments below!

Posted in Java, javafx, jfxtras, UI | 2 Comments

Java 8 method references

Java 8 is finally out officially and it brings probably the biggest change to the Java platform ever; lambda’s. Lambda’s are a very powerful technology which will have major influence on the way API’s in Java will be written, but the first critical sounds also are heard already.

Lambda’s in Java have two main aspects; one is the powerful stream API, where all kinds of processing is chained and in that way multicore processing is easily made possible. The other aspect is the replacement of the anonymous inner classes scaffolding, and that is probably the thing people are exited about first, when discovering lambda’s in Java 8. Let’s take a peek using my latest hobby project as an example.

In the previous blog I’ve written about CircularPane; a way to layout nodes in JavaFX in a circle. Below is an example of how some tests in CircularPane look (the green circles are debugging hints):


One of the latest additions is that nodes can be animated into their positions. The example below shows that the left two CircularPanes animate their nodes into place “over the arc”, the right two “from origin”.

Now, this animation is a calculation of a progress (0.0 to 1.0) over time. For example the “from origin” slowly adds the difference between the origin and the end location; at 0.0 all nodes are at the origin, at 1.0 all nodes have the full difference added and are at their end location. For this a Transition is used to handle the calculation of the progress value, CircularPane has precalculated all sorts of layout values, so the actual calculation it is pretty straight forward.

   	new Transition() {
		protected void interpolate(double progress) {
			for (AnimationLayoutInfo animationLayoutInfo: animationLayoutInfos) {
				double lX = animationLayoutInfo.originX + (progress * -animationLayoutInfo.originX) + (animationLayoutInfo.nodeLayoutInfo.x * progress); 
				double lY = animationLayoutInfo.originY + (progress * -animationLayoutInfo.originY) + (animationLayoutInfo.nodeLayoutInfo.y * progress);
				animationLayoutInfo.node.relocate(lX, lY);    	

In the code above the “from origin” animation is hardcoded in the Transition, but I would like to make this dynamic, so multiple animations can be supported. In order to facilitate this, an interface is introduced that will hold the actual interpolation calculation, and that is called instead:

	// the interface
	public interface AnimationInterpolation {
		public void interpolate(double progress, AnimationLayoutInfo animationLayoutInfo);    	

	// a property for setting an implementation of the interface
	final private ObjectProperty<AnimationInterpolation> animationInterpolationObjectProperty = new SimpleObjectProperty<AnimationInterpolation>(this, "animationInterpolation", null);

	new Transition() {
		protected void interpolate(double progress) {
			for (AnimationLayoutInfo animationLayoutInfo: animationLayoutInfos) {
				animationInterpolationObjectProperty.get().interpolate(progress, lAnimationLayoutInfo);

Things are in place to have the animation implemented externally. Prior to Java 8 this would involve creating an anonymous inner class like so:

	lCircularPane.setAnimationInterpolation(new CircularPane.AnimationInterpolation() {
		public void interpolate(double progress, AnimationLayoutInfo animationLayoutInfo) {
			double lX = animationLayoutInfo.originX + (progress * -animationLayoutInfo.originX) + (animationLayoutInfo.nodeLayoutInfo.x * progress); 
			double lY = animationLayoutInfo.originY + (progress * -animationLayoutInfo.originY) + (animationLayoutInfo.nodeLayoutInfo.y * progress);
			animationLayoutInfo.node.relocate(lX, lY);    	

Even though this is a lot of scaffolding, it is very clear what is going on: you are implementing an interface defined in CircularPane, and you see exactly which method it defines. Now, if the interface changes for any reason, it is obvious that this code will get compiler errors. But also an IDE can easily find all implementations of an interface, because it is explicit. No magic.

But that is a lot of code just to be explicit. So the equivalent lambda notation does make it a lot more readable. Basically the compiler generates the anonymous inner class. It is a trade off between brevity and completeness, but one probably worth trading. And in the end, knowing how lambda’s work, there is still the notion of that anonymous inner class underneath. The scaffolding is just generated for you.

	lCircularPane.setAnimationInterpolation( (progress, animationLayoutInfo) -> {
		double lX = animationLayoutInfo.originX + (progress * -animationLayoutInfo.originX) + (animationLayoutInfo.nodeLayoutInfo.x * progress); 
		double lY = animationLayoutInfo.originY + (progress * -animationLayoutInfo.originY) + (animationLayoutInfo.nodeLayoutInfo.y * progress);
		animationLayoutInfo.node.relocate(lX, lY);    	

But now we move the calculation into a static method inside CircularPane. This allows us to configure what animation to use by simply setting a method reference:


	static public void animateFromTheOrigin(double progress, AnimationLayoutInfo animationLayoutInfo) {
		double lX = animationLayoutInfo.originX + (progress * -animationLayoutInfo.originX) + (animationLayoutInfo.nodeLayoutInfo.x * progress); 
		double lY = animationLayoutInfo.originY + (progress * -animationLayoutInfo.originY) + (animationLayoutInfo.nodeLayoutInfo.y * progress);
		animationLayoutInfo.node.relocate(lX, lY);    	

This is where lambda’s become vague, and IMHO let go of the ideas behind Java. Normally if you move the implementation of an interface from an anonymous class into a formal class, than there is a reference to the implemented interface. This is not the case here; the animateFromTheOrigin method actually implements AnimationInterpolation, but that information is not visible in anyway. It appears as just a method with two parameters, only compiler / EDI errors will show otherwise, and that only after making breaking changes to either the interface or the method. And only if the method is used somewhere! If the method is never used as the interface it implements, no compiler or IDE will be able to figure out that it needs to change when refactoring the interface. I do not like that.

Maybe the static method should explicitly state that it is implementing an interface:

    static public void animateFromTheOrigin(double progress, AnimationLayoutInfo animationLayoutInfo) 
    implements AnimationInterpolation {

Or there should be an annotation similar to @Override

    static public void animateFromTheOrigin(double progress, AnimationLayoutInfo animationLayoutInfo) {

Of course this implementing keyword or annotation can only be used for single method interfaces, but now you know that this method is not just any static two parameter method…

For JFXtras I have written test classes that use both methods, thus allowing the IDE to correctly refactor.

Posted in Java, javafx, jfxtras, Lambda | Leave a comment