JavaFX Missing Features Survey: Performance & Quality

I take it as a good sign that the categories “Performance” and “Quality” have not seen a lot of submissions in the “Missing Features Survey”.

Performance

In the survey the performance of JavaFX was compared with the performance of Swing and people noticed that JavaFX is slower than Swing. I personally have yet to find a use-case where that is true but I do believe that they can be found, however it should be noted that JavaFX also provides a much better coding experience based on a modern API and architecture. JavaFX supports property bindings and CSS styling. These things of course do take their toll on CPU time. Swing was designed for computer hardware that existed 20 years ago. JavaFX is targeting today’s hardware.

Something that I can agree on is that the use of huge quantities of more or less complex controls within a single stage does lead to performance issues. In a test case that was discussed by several JavaFX experts in Germany, Switzerland, and Austria we looked at the performance of JavaFX when displaying several thousand textfields. This does sound silly but there are use-cases out there that need to create this amount of controls. When comparing the time it took JavaFX to display the textfields to the time it took HTML to do the same we could clearly see that HTML can do it almost instantly while JavaFX needed several seconds. The culprit seems to be the code that performs the CSS styling. Somebody should take a closer look at it. This doesn’t have to be an Oracle employee. The code is open source and available to anybody!

Quality

The following items were mentioned related to quality:

  • WebView needs to be kept up-to-date with the current versions of WebKit
  • Image resizing needs to be improved to ensure that lines do not vanish when decreasing image sizes.
  • Better font rendering (all fonts on all devices).
  • Canvas rendering quality needs to be on par with scene graph rendering.

This is it for the topic “performance and quality”. Next blog will be about CSS and FXML.

Happy coding everyone!

New CalendarFX View: MonthGridView!

Me and my team have recently begun work on a new view for CalendarFX with the initial goal to display a whole year in vertical columns. The name of the view is MonthGridView. As usual the goal has changed slightly while coding. The view is now capable of displaying any number of months with extra months added in front or in the back. Now, for example, the developer can choose to display six months (a semester) with one month “padding” in front and one month in the back.

The following screenshot shows an entire year with no padding.

Screen Shot 2016-04-06 at 09.57.19

In planning and scheduling applications it is often the case that the person using the software wants to quickly compare the same weekdays with each other (e.g. “see resource utilisation on Mondays”). To make this easier the new view also supports a layout option where the same weekdays are aligned. It looks like this:

Screen Shot 2016-04-06 at 10.02.44

As mentioned above, the view can display any number of months with any number of “padding” months. The screenshot below shows a six month period with one month padding on each side (the styling of the extra months still needs some work :-))

Screen Shot 2016-04-06 at 10.14.13.png

The screenshots do not show any calendar information, yet. This part is still work in progress.

If you have any suggestions for features that you would like to see in this view then please leave a comment.

 

Shadow Fields vs. Property Accessor Interface

Carl Dea recently followed up on a blog post of mine called Save Memory! Use Shadow Fields for Properties. In his blog he suggested the use of an interface called “Property Accessor” to eliminate the heavy use of boilerplate code that is needed in order to use  shadow fields. Carl also mentioned that he hasn’t tested his approach with a lot of data and that he or some reader might follow up with a performance comparison. So here it comes.

I wrote a small test application that implements the three strategies that Carl mentions in his post:

  1. standard properties that are instantiated at the same time when the class gets instantiated
  2. property accessor interface as proposed by Carl
  3. shadow fields as proposed in my recent blog post

The code can be found on GitHub. (when you run it please make sure to set the initial and the maximum heap size to 2048 MB -ms2048m -mx2048m, otherwise the memory allocations will mess up the results).

The application allows the user to execute these strategies either with or without asking for the properties. It measures the time spent and the memory used. It should be noted that the measurements are not scientific as I used System.currentTimeInMillis() and Runtime.gc(). When run several times I would still argue that the qualitative value of these tests are acceptable.

The first screenshot below shows the numbers you get when you create between 1,000 and 2,000,000 instances of the Employee class that Carl used for his blog. The tests do not ask for the properties that are available on Employee (name, powers, supervisor, minions):

A1

As you can see the “shadow field” strategy is the fastest and also uses the least amount of memory. This makes sense as the “standard properties” strategy always creates those fat property objects and the “property accessor interface” internally manages a hash map for each model object. Only the “shadow field” strategy works with a minimal amount of data structures. In the case of the selected test it saves a total of 230 MB. If you now imagine that typical applications have many model classes and many of those much more complex than the Employee test class then you can imagine how much memory you can save.

The next screenshot shows the measurements taken when also accessing all four properties and observables inside the Employee class.

A2.png

Now the “standard properties” strategy is the fastest and also the one that uses the least amount of memory. Once again, this makes sense, as this strategy now implements the perfect approach for the given use case. However, the “shadow field” strategy comes in at a very close 2nd place.

Conclusion

The “Property Accessor Interface” strategy is successful at reducing  the noise created by all the boilerplate code needed for shadow fields but it comes at a price that I believe is too high to pay for any application that creates more than just a few model objects.

 

 

P.S.: it should be noted that the comparison is even more in favour of the “shadow fields” strategy when the initial heap size of the JVM is left at its default setting. In this case the test app has to keep asking for more heap space which is quite an expensive operation.

JavaFX Tip 23: Save Memory! Shadow Fields for Properties.

Properties and property bindings introduced in Java 8 are extremely useful programming concepts. They are especially useful when you are developing user interfaces. In fact they are so useful that developers have fallen victim to the idea that everything should be a property instead of a primitive. Unfortunately they easily forget that properties such as SimpleLongProperty are much bigger objects than standard types such as Long. And of course they are much bigger than primitive data types such as long.

In one of my current projects pretty much every model object used by the client is composed of properties. For many of these model objects it is the right approach because they will be edited / modified via JavaFX controls. But there are also many model objects that are not edited. They exist to support the rendering of schedules in the FlexGanttFX control. These objects do not need to be observed, hence they do not need to provide properties … but they do and they waste a lot of memory because they do.

One way to fix this would be to refactor the model classes and to get rid of all properties, but then again we might want to use these objects in a future release in a different context and then we might need properties because we want to edit them directly. What to do?

Shadow Fields

The solution to this problem is something I recently saw Gerrit Grunwald do in the code of his Medusa project and a pattern that was described by Mr. Properties himself Michael Heinrichs.  The pattern makes use of a “shadow field” that is of the same type as the wrapped object inside the property. When using this pattern a property will only be created when it is really needed (“when somebody asks for it”).

Example

In this example we want to manage an attribute called “title”. We need a setter, a getter, and the property accessor.

private String _title = "Untitled"; // shadow field

private StringProperty title;

public final String getTitle() {
    return title == null ? _title : title.get();
}

public final void setTitle(String newTitle) {
    if (title == null) {
        _title = newTitle;
    } else {
        title.set(newTitle);
    }
}

public final StringProperty titleProperty() {
    if (title == null) {
        /// !!!! pass shadow field to constructor
        title = new SimpleStringProperty(this, "title", _title);  
    }

    return title;
}

By using this pattern I was able to bring down the memory footprint from 310 MB to 250 MB for a specific use case in my project. The saved memory is ten times the total memory my computer had when I was a student. Just think about that!

JavaFX Missing Features Survey: Table View

The TableView (and TreeTableView) of JavaFX has won the prize for being the control that was mentioned the most in my recent “JavaFX Missing Features” survey and also in many follow-up discussions (including and especially the guys in our Zurich JavaFX Meetup group). I guess one of the reasons is the simple fact that almost every application needs a table view.

The two most requested features / improvements for the TableView were freezing rows / columns and better editing support.

Freezing Rows / Columns

  • Freeze / lock rows – the ability to have one or more rows to stay at the top or bottom of the table view. Often this feature is needed when trying to display the sum of the values in the columns.
  • Freeze / lock columns – the ability to have one or more columns stay on the left or right-hand side of the table view. Again, to show the sum of the values in the row or to display some kind of header for the row. In the case of my FlexGanttFX framework I like to have a column on the left-hand side to show the row number (yes, like in Excel).

I believe that freezing columns / rows was a feature that was planned for the TableView but that did not make it into the final release because of time and resource constraints. If I remember correctly then there is actually some left-over code / comments in the TableView code base that was intended for this purpose.

Editing Support

  • Ability to edit cell values by simply starting to type the new value – currently the user has to double click a cell first.
  • Fluent keyboard navigation to navigate from one cell to another via TAB, SHIFT_TAB, ENTER, arrow keys.
  • Cell validation when editing a value. The user should not be able to leave the cell without either entering a valid value or cancelling the edit.

The current editing support is probably the one thing that annoys developers the most when using the TableView as they know that their users expect more. I have already worked on two projects myself where we had to hack the TableView so that it would let the user edit values directly.

Miscellaneous

Other features that were requested included:

  • Cell / row spanning – the ability to have a cell go across multiple rows and or columns.
  • Filter UI – table views often let the user select one or more filters per column. The collection of all filters then determines the visible rows. In JavaFX this can be easily done in the model (via SortedList and FilteredList) but developers wished there were built-in controls directly inside the TableView (inside the headers).
  • Automatic column sizing – a way to adjust the width of a column to its content, to ensure readability of all values. This feature is actually implemented inside the TableView codebase. It is used to resize the column when the user double clicks on the edges of the column headers. However, the code for this is not public. I have recently posted an article showing how to do it.

I think that all of the above features are valid things to expect from a good table control but I am pretty sure that we will not see any progress in this area from the JavaFX team itself. I believe that from Oracle’s point of view the current table implementation is considered “good enough”, so I assume that it will be up to a third-party to come up with a good alternative, either open-source or commercial. I have brainstormed a lot about how to implement my own table view control but have reached the conclusion that this is too big to be a simple side-project. This is bad, but it also means that there is a potential for somebody else to create a commercial product and to actually make some money with it. Because like I said in the beginning: almost all applications need a table view.

The next “Missing Features” blog will be about performance and quality.

Stay tuned!

P.S.: for some of the features above you might want to try out the SpreadsheetView in the ControlsFX project.

 

FlexGanttFX 1.4.0 Released!

I am very happy to announce that I have released version 1.4.0 of FlexGanttFX for JavaFX. This release contains bug fixes and small improvements. I am glad to say that FlexGanttFX has proven itself in the field and is operational in various large enterprise applications. Some of its more prominent users are:

  • Emirates Airlines
  • European Broadcasting Union
  • Airbus
  • PSI Poland

The following are a couple of screenshots from these applications.

ScreenShot005

PSI Poland

Bildschirmfoto 2015-12-19 um 12.28.15

European Broadcasting Union

Gantt-Split-4up

Emirates Airlines

mintpage

MINT Software Systems