After having established the communication with the backend, and the functional part of the UI on both PC and Android, the next step is to make it look a bit better by attempting to apply Google’s Material Design. Basically that would mean that I needed to start doing a lot of CSS and emulate the different UI aspects. FlatterFX could be a good starting point… Maybe use JFoenix controls… But after reexamining Gluon, it turned out that they already have done exactly what I was about to create from scratch; menubars, actionbars, views, layers, popup views, and all styled in Material Design… Well. Ahm. Ok. That settles it then.
Refactoring to Gluon’s view based approach was not that difficult; a View extends BorderPane, so you can add your own controls as the center node. The first result was quite pleasing.
Out of the box a nice and clean UI, in my opinion. The menu on top holds actions like refresh, quit, and switching from and to full screen mode. Full screen mode is a bit of a thing, because it removes all the window controls on desktop, but I have not found a way to maximize a JavaFX window on desktop. I did find a way to size the window to the screen size, but on Windows 10 that is not quite perfect. So the switch buttons basically replace the window controls. Not quite pleased there yet.
It also turned out that the datepicker is not suited for use in portrait mode, so the app needs to be forced in landscape. Unfortunately I have not found a way in JFXMobile to enforce that. Maybe I can use rotation on the center node of a view.
Because of the limited screen space on mobile, the app switches to a tabpane based layout. Since landscape is the required orientation, I decided to move the tablabels to the left. On the cards panel (showing a.o. day totals) there already was a tabpane to switch between the cards, there the tablabels are on the right side (as you can see below). The blue line marking the active tab is nice and subtle. Some more work is needed on selecting appropriate icons.
So what about the layout on the desktop? As I wrote in the previous blog, ResponsiveFX is not working on my two Android test systems. So I wrote my own which, instead of assigned classes to all nodes in the scene, replaces CSS files. This is working quite well so far. ResponsiveLayout (as I’ve called it for now) recognizes device types PHONE, PHABLET, TABLET and DESKTOP, plus orientation PORTRAIT and LANDSCAPE. In the application ResponsiveLayout exposes a property and based on its value the layout can be changed. Currently the application only has two layouts: desktop and mobile (non desktop). The desktop layout looks like this:
On the desktop, if you size that window smaller, it will automatically switch to mobile layout at a certain point. And that is what is shown on a mobile platform. The difference in the application are two methods; layoutForDesktop() using MigPane and layoutForMobile() using a TabPane, maybe 15 lines of code, that all it takes to make the same application run on PC and mobile.
Upon startup, ResponsiveLayout searches for a number of CSS files based on the states it recognizes, for example PHONE.css, PHONE_LANDSCAPE.css, PHONE_PORTAIT.css, etc, a total of 12 possible CSS files at the moment. At runtime it loads the CSS files that are applicable for the current stage size.
One of the things that changes in the CSS used in the application, is the color of the background (on desktop this is light grey to add some contrast) and the size of the arrows in the picker so they are more easily clickable, as can be seen below (compare this to the desktop layout above).
ResponsiveLayout does exactly what it should, and I probably will be moving it to JFXtras in the future, maybe in a separate “mobile” artifact.
The app is fully usable now, for convenience I have to store the last logged in server and user somehow, so the user only needs to type the password. The last hurdle before I’m going to use it in real life.
But there of course still is a lot to do, but these are all are minor tweaks and improvements compared to the fact that I have a single code base that runs on all platforms! The most notable issue is the performance of the calendar picker; it’s a tad sluggish, that should not be necessary. And I’m not quite please with the way the app looks on the desktop; it’s a bit bland in my opinion. And of course the points I mentioned above; forced landscape and maximize. Maybe ResponsiveLayout can automatically rotate the center node of the view… Hmmmm. Hacking continues.
ResponsiveLayout, as mentioned in this post, is being developed in JFXtras as ResponsivePane and is almost ‘functionally complete’. It will accept multiple layouts & stylesheets, and pick the best one given the current scene size.