Přeskočit na hlavní obsah

My JavaFX experience

Since version 2.0 of JavaFX, I was very keen about this technology and was looking forward to use it in some project. Hello world is fine, but you need some real application, used by real people. 
First opportunity came with AgroSense project, where we developed Gantt chart component for planning (similar to Google Calendar or Outlook).
As far as I know, this component was never used and now there are plenty of alternative solutions, but it gave me some insight to the library (is it library, or platform?) and its features.

Few months ago another opportunity came in my company, where we decided to rewrite legacy self-service cafeteria terminal.
The application is quite simple - user signs with his/hers contactless smart card and adds grocery to the shopping cart using barcode scanner or touch screen.
This application is only for internal use in our company, so we decided to experiment a little and use JavaFX to the frontend of the application.

We use quite ordinary technology stack:
  • Oracle DB for data
  • Hibernate for persistence
  • Spring for IOC and security
  • JavaFX (not ordinary) for frontend

 Here are some thoughts about the development and user experience.

Learning curve

From my point of view, the learning curve is quite steep. If you are Swing programmer, most components are familiar to you. If not, you should have no problem to understand the basic ideas to be able to develop nice GUI.
If you use Swing, you should know the term “layout hell”. I think I understand layouts in Swing, but using JavaFX Pane class and its hierarchy (AnchorPane, BorderPane, GridPane, etc.) is much easier and straightforward. And with SceneBuilder you have feeling like going from Swing layout hell to JavaFX design heaven :-)

Code separation

Of course you can create your complete GUI by creating components and adding them to the containers to build complete component tree. But with Scene Builder and FXML it is much easier.
Again: you can create your FXML file by hand in notepad (it reminds me HTML or XAML in C#), but with Scene Builder you just drag and drop components, set correct borders and bounds and that’s it.

Using FXML file to describe GUI has one big advantage – you can focus on writing business logic and the GUI definition code doesn’t hinder in your code. Just create controller implementing Initializable interface and set it to the form in the FXML file.
When the FXML file is loaded and inflated, form with all its components is created, registered controller is also created and initialized and components from the form are injected to the annotated fields in the controller class.

What about Spring

You want to use Spring features like autowiring, but controller classes are not managed by Spring, because they are created by JavaFX Loader. What can we do about this?

We did the trick by annotating controller classes as @Configurable and Spring does the rest. Another solution, if you don’t like @Configurable annotation, would be to create your own Loader and do the injection. We didn’t try this approach and it is possible, that there exists some similar solution now (but we didn’t find any at the time of the development).

Styling

Styling is completely different compared to Swing. Forget setBorder, setBackground or setForeground methods you know from Swing.  JavaFX is styled by CSS. You can set ID or class (or list of classes) to any component. Just register style sheet during application startup and you are done.
You can imagine that with CSS styling you can create really nice GUI.

Touch screen

JavaFX is well prepared for touch screen systems, nothing more needed to say here :)

Binding

I love binding features of JavaFX and there is also DataFX open source project, which I would like to try.

Drawbacks

Not everything can be perfect, we experienced one major drawback and it was performance.
With many components in the scene graph, especially when scrolling, especially using pannable function of Scrollpane for simulating swipe gesture, it reminded me my old Celeron PC and playing games on it :)
After some profiling we found, that the major reason of this slowness was walking through the component tree in the scene, parsing CSS file and applying styles to the components.

Converting CSS file to binary form should help, but it was not the core of the problem.

We reduced CSS styles (to almost none) and not only the application is painting faster now, but also looks better (remember Metro design in windows 8? Same reason and same result :-) ).
Also better graphic card helped, because JavaFX can use hardware acceleration. It was fun to call to IT department and saying “Hey, we would need some really fast graphic card for our Java based terminal”.

Some of these problems should be fixed with JavaFX version 8, released with Java 8, which was not released yet at the time of the application development.

Another problem was leaking memory (I try to summarize it in the next article), but as far as I know, this is also solved in already released version 8.

Conclusion


I agree with people saying that it is time to move from Swing when developing desktop application, and I think JavaFX is good choice as its substitute. 

Populární příspěvky z tohoto blogu

CPU killer in Java with JavaFX GUI client

Motivation Few weeks ago I was searching for a source of a bug in one of our applications. The QA team suspected that slow computer could be a reason for this. You know that - developers have Core i7 CPU with 8 GB RAM (at least some of us :-) ) and never realize, that users can have slow machine, which reacts differently . And for that tiny moment you would need slow computer, just to see how it works and whether you can break it. But how to achieve this? The QA team does that by creating a virtual machine and setting it very low resources, so it acts very slow. Another option is to use some kind of CPU killer – those are great pieces of software, doing exactly what it sounds – killing your CPU. There are tons of complete solutions out there, but I didn’t want to deal with the licensing and our IT stuff yelling at me, what is that software that I installed by myself again. So I decided to break the rule “ Don’t reinvent the wheel ” again. Requirements At first, here is a list ...

Using JavaFX with Maven

JavaFX is exciting new framework from Oracle, which should replace Swing one day. But unfortunatelly it is not added to Java classpath, so we need to add it manually. And because I use Maven for all my projects (right now experimenting Gradle) we want to add it as a Maven dependency.  But javaFX jar is not in any public maven repository, thus we have to install it manually to local repository. This command does the installation: mvn install:install-file -Dfile=jfxrt.jar -DgroupId=com.oracle -DartifactId=javafx -Dversion=2.2.3 -Dpackaging=jar The command was executed in the directory, where the file  jfxrt.jar  is located (on Windows the path would be something like  c:\Program Files\Java\jdk1.7.0_09\jre\lib ) otherwise the full path has to be supplied. Latest version of JavaFX runtime is 2.2.3 (included in JDK 7u9) Once the installation is done, we can use regular maven dependency attribute: <dependency> <groupId>com.oracle</g...

Checking internet connection and connection to a particular server in Java

In AgroSense we need to know, if the computer is connected to the internet or not. And we don’t want to bother the user by throwing UnknownHostException or IOException also. So we need two things: Check the connection Notify everybody interested, that the connectivity changed When the first point is successfully implemented, the second one is easy – it is just a listener, so we will look only at the connectivity check problem. Solution For checking internet connectivity you need some host address. You will probably use the address, which you actually call, in our case it is www.openstreetmap.org. In first step, we check, if there is some internet connection, this is done in a method isOnlineFastCheck: private boolean isOnlineFastCheck() {         boolean check = false;         try {             InetAddress.getByName(hostName);             check = true;     ...