FX Experience Has Gone Read-Only

I've been maintaining FX Experience for a really long time now, and I love hearing from people who enjoy my weekly links roundup. One thing I've noticed recently is that maintaining two sites (FX Experience and JonathanGiles.net) takes more time than ideal, and splits the audience up. Therefore, FX Experience will become read-only for new blog posts, but weekly posts will continue to be published on JonathanGiles.net. If you follow @FXExperience on Twitter, I suggest you also follow @JonathanGiles. This is not the end - just a consolidation of my online presence to make my life a little easier!

tl;dr: Follow me on Twitter and check for the latest news on JonathanGiles.net.

I was doing a bit of work today reviewing the Popup class we’re working on for the next release of JavaFX. I showed Jasper some code snippets and he pointed out that I should write a quick blog on it because it shows a nice progression of how to do looping in JavaFX.

The code in question is relatively easy to understand. The Popup class had a private sequence of “child” popups var childrenPopups:Popup[]. The function is called “hideAll” and will hide each child popup. The original function used a java-like looping mechanism:

[jfx]
public function hideAll():Void {
   for ( i in [0..sizeof this.childrenPopups] ) {
       if (this.childrenPopups[i].visible) {
           this.childrenPopups[i].hideAll();
       }
   }
   hide();
}
[/jfx]

The function is relatively straightforward. We iterate from 0 to sizeof childrenPopups. Except, oops, sequences are inclusive so this actually iterates one time too often! So either we’d need to throw a -1 on there ([0..sizeof this.childrenPopups - 1]), or use the less-than operator ([0..<sizeof this.childrenPopups]).

In any case, we iterate over all the child popups and hide them, accessing them by index. This is fine, and a very java-centric way to do it. However, we can clean up some of the visual noise here by using JavaFX’s built in sequence looping instead:

[jfx]
public function hideAll():Void {
   for (p in childrenPopups) {
       if (p.visible) p.hideAll();
   }
   hide();
}
[/jfx]

This is a fair amount cleaner from a visual-clutter perspective. Performance (and indeed, the generated code) is exactly the same as before. One positive gain here is that we avoided the nasty hidden bug in the previous code of iterating one to many times.

I would consider this a completely fx-like implementation of the function. But we can actually take it one step further. In JavaFX looping supports a “where” clause. The performance (and indeed, the generated code!) is exactly the same as with both previous examples. Its mostly just a style thing:

[jfx]
public function hideAll():Void {
   for (p in childrenPopups where p.visible) {
       p.hideAll();
   }
   hide();
}
[/jfx]

As mentioned, all three of these implementations essentially generate the exact same code. They all turn into very efficient for loops (unlike the java for-each code which creates iterators in many cases). They all have the same if clause inside the loop and do the same work. It’s just matter of taste and visual clutter.