Dear All,
Some three months ago I wrote about my first migration project: from VisageFX to ScalaFX. It was a rather simple project with about ten classes summing up to one thousand lines of code. Yet it was significant to me because I then had no notion of Scala. Over three days I had my application running.
Since then I have been working intermittently on my other migration project: from JavaFX Script 1.3.1 to ScalaFX. There are more than one hundred classes, making use of some advanced features such as various skins in order to have different behaviours for the same component, depending on where it is used in the layout. Being now at about 60% of the migration, I reached an interesting milestone: the first ScalaFX independent module is functionally equivalent to its JavaFX Script 1.3.1 counterpart.
I'll try to list here some of the lessons learned down the way:
* Lesson 1: NPE is striking back! Again and again!
While the runtime used to protect me against these by skipping the irrelevant instructions and retrying later on the unsuccessful bindings and som any other nice compiler optimizations... I have to take care again about the correct sequence of variable initializations. This is of critical relevance since the init and postinit blocks do not exist anymore.
* Lesson 2: there is no binding on functions
Not that I was using this feature a lot but, where it was used, I had to find some way to listen for changes on the properties used in the functions in order to fire an explicit call in the change listener.
* Lesson 3: my ScalaFX components cannot be retrieved from the containers' content
What gets stored in there is the JavaFX delegate. This becomes especially critical when it comes to custom controls. These have to extend from the JavaFX class, thus losing some of the facilities about handling the properties and bindings. On the other hand, I can maintain a duplicate of the children collection keeping a grip on my ScalaFX objects in order to refer to them when in need to perform some "business" logic.
* Lesson 4: the syntax is similar... yet not that much
Aside from renaming all "def" to "val" and "function" to "def", there not much that could be automated in the translation process. Well... I also made an automatic replacement of "= bind" with "<==" but I still had to review much of these expressions. My main nightmare has been the change from "blocksMouse = true" to "mouseTransparent = false", which has many other subtle implications... Many of them, I think I did not get right yet!
* Lesson 5: the sizing of the components seems to follow a rather different strategy
This first was a great preoccupation since my layout didn't look like expected at all. But after inspecting my scenegraph through the Scenic View tool, I discovered that my components had their preferred size smaller than their computed minimal values. It might well be that my original code was not really strict about the three sizes: minimal, preferred and maximal. But from now on, I would not code without these three concerns in mind. It is quite comfortable to know I have such a precise control over the sizing of my components.
* Conclusion
When I first read, some eighteen months ago, that JavaFX2.0 was an easy goal to migrate legacy JavaFX 1.3.1 applications since "JavaFX Script code is almost Java code", I joined Stephen Chin in the Visage team in the hope for maintaining a less verbose syntax for my code. However when I read later on some of the demo code for ScalaFX, I could not help noticing the syntax similarities. When considering my main difficulty in wrapping the VisageFX components was the lack of tooling to support our task... I could not resist the call of an IDE to use along with Scala.
Thanks to the work by the 19 contributors, I found until now all the components I needed to turn my codebase from deprecated to up-to-date.
Best regards,
Alain