The development is progressing nicely. Because I do not like to reinvent the wheel, I decided to try as many of the available libraries as possible. The thing that struck me most was that a lot of the libraries aren’t using retrolambda, even though they can without any problems (because streams are not used that often), and that many are really suited for running on tablets and smartphones. And I blame myself as well, because MigPane (the port of MigLayout for JavaFX I started) was not using it either. But that I could easily fix: as of the 5.1-SNAPSHOT MigPane runs on Android, and quite well I may add. (I know people have been asking for this.)
One of the first libraries I tested was FlatterFX by GuiGarage.com. A styling intended for touch devices, but not compiled with retrolambda. Is that strange? But also easily fixed, and the local snapshot build quickly integrated into the application.
It is a bit hard to see on an image, but in default mode the buttons are rather large. Too large. Of course this is fixable by overriding the CSS, but I’m a bit confused why the whole styling is so large. Maybe it was developed on a UHD screen. I decided to not use FlatterFX, for now at least.
I also tried JFoenix (which already uses retrolambda), but it uses special controls instead of reskinning the standard ones. Because I initially want to stick as close to the standard JavaFX as possible, that got placed on the backburner. The same faith befell Gluon’s GListen; the example showed that the application needed to extend MobileApplication and used a ViewFactory… Too deviating from the standard JavaFX for my first attempt on a hybrid JavaFX application.
Another library I tested was ResponsiveFX, also by GuiGarage. ResponsiveFX is inspired by Twitter Bootstrap and in essence assigns CSS (pseudo)classes to all the nodes on the stage based on the current size of the window. As CSS classes you have extra small, small, medium, large. A smartphone for example could then be ‘small’, and a desktop ‘large’. Using these classes, CSS can be easily customized for each device.
On the desktop ResponsiveFX works amazingly well (for testing I used it to change the sizes of the buttons of FlatterFX). ResponsiveFX needed to be retrolambdaed, and then it turned out to be not such a success on Android. It is not crashing, and maybe if I wait long enough the screen will show something, but after 30 minutes the screen in Android still is black. ResponsiveFX is a very invasive algorithm, assigning and removing classes on all nodes in the graph, and that on every change of the stage width. I assume this is simply too much for my 2012 Nexus 7.
But ResponsiveFX’s approach is sound, so I decided to write my own version, with a few tweaks:
- A 500 ms delay between the window size change and actions that follow.
- The orientation is also taken into account, so you have a phone in landscape or portrait. (Note to self: do not reuse javafx.print.PageOrientation, it is not present on Android. 🙂
- Based on the window size, a CSS file is switched, not the classes on the nodes.
I hope that swapping a single CSS file will turn out to be less intrusive than assigning all those classes to all those nodes. I have not progressed enough to test the CSS intensively, but the basic layout-per-device mode works perfectly. Below is the current desktop layout (yes, that logo is way to big, I know, but it gives some scale to the FlatterFX window; the logo’s are the same size).
And this is exactly the same application on Android.
If you resize the window on the desktop, it will automatically switch to the Android layout if the width gets small enough. On Android this is the starting layout of course. Oh, I decided to use a Tabpane instead of a scrollpane; the scrollpane on the Nexus was very sluggish (but the drag scroll did work).
The icons you seeing are from FontAwesomeFX. That library also was not retrolambdaed, but Jens quickly merged my pull request, so as of 8.10-SNAPSHOT it runs on Android.
So… How did I fare as a whole? Well, at times it was frustrating. I usually was making good progress on the desktop version (change-run-test cycle) and after a few iterations of changes you also test on Android (because the install cycle is so much longer), and it fails. Finding out where in the cycles you introduced the error can be challenging. But once you got the boundaries figured out of what works and what does not, it actually is quite a smooth ride.
I’ve got most of the functional part of the UI running, and this version should work against my production environment. I will test that soon.
So what’s next on my to do list:
- The response time of my development server seems low, I want to check if it is the server or the client.
- Figure out if I can locally remember the server and username from the last login.
- Attempt “Material Design” in the the layout (CSS here I come)… That probably will be a lot of work. Maybe JFoenix or Gluon will reappear.
- Test on iOS.
- Create installers for the platforms.
By popular demand I’ve made the current state of the sources available here http://www.tbee.org/wordpress_support/dh2fx.zip. I cannot make the repo public, because of licenses that are present in the source code. Also I’m using my own Nexus repository, which proxies a number of other repos, so you may need to add some of those repos to the build.gradle.