Responsive Design with JavaFX
With CSS technologies it’s relatively easy to create a responsive design for your website. Depending on the sizeof the screen you can use a different CSS File and Layout. In JavaFX this might seem a bit harder at first sight, since CSS is only responsible for styling, but not for the layout. But using different FXML Files for the respective screen sizes and sharing a Controller is actually not that bad, and this way you can easily use SceneBuilder to preview the layouts on different screen sizes. In the code you either switch between the FXML-files depending on screen size, or you get rid of this by creating different deployments depending on the targeted device and copying the required files as part of your build.
But responsive design is not only be about size. For touch enabled devices it’s important to also use the right controls. At JayDay Jim Weaver gave an excellent presentation of how to create touch enabled UIs using JavaFX. You can download the presenation from the JayDay site: JayDay 2013. One of the things he proposes is to use the Pagination control, which is easier to use on a touch device than a TabPane.
Unfortunately that wouldn’t work well with our approach of reusing the controller, so we would have to create a Baseclass for the controller that has the common stuff and use
@FXML private Pagination pager
for the Touch device and
@FXML private TabPane pager
if the application runs on the desktop.
It would be much nicer if we could simply switch the Skin via CSS, as Paru Somashekar showed at JavaONE in her presentation with Jonathan Giles. In this presentation she shows an alternative Skin for a CheckBox, that can simply be set via CSS ( at around 27:15 ):
So you either create a deployment specifically for touch devices, that has the CSS, or you use something like this to find out if the device supports touch:
PlatformImpl.isSupported(ConditionalFeature.INPUT_TOUCH);
I decided to give it a try myself and convert the ChoiceWheel Control I created to a Skin for ChoiceBox:
For the FXML/CSS based approach I would not set the style via a styleclass on every CheckBox like Paru did, but enable the alternative Skin for all the Controls. In my case for all ChoiceBoxes:
.choice-box { -fx-skin: "de.eppleton.controls.choicewheel.ChoiceBoxSkin"; }
No changes are required to the Controller. I think that’s a nice way to create an application that looks great on desktop as well as on a tablet or phone and it shows the strength of both FXML and CSS. Having a CSS-FXML pair per device size enables you to:
- Organize the layout on a per device basis
- Easily preview the design as it appears on different devices in SceneBuilder
- Switch between different controls (touch / mouse) via CSS
- Reuse the same Controller
- Create deployments that only come with the required files for the targeted device
It would really be great to have more of these touch optimized Skins for common controls.
Do you give me the code of a task manager that is like Windows, code in Java.
I need it, please…