JavaFX Days Zurich – Sessions

The holidays are over, time to get serious, time to fill the session catalogue for the JavaFX Days Zurich (Website). We managed to convince some of the best JavaFX experts to come to Switzerland and to show us the things they work on or work with. So without further ado here is a list of the currently scheduled sessions:

 

JavaFX State of the Union

Wolfgang Weigend, Oracle Corp.

The current state of JavaFX UI development will be explained from the perspective of Oracle, with an inventory of existing development resources and the continuation of JavaFX in a free ecosystem. With the release of the OpenJFX and the decoupling of the Oracle JDK, the Java module system has created new possibilities for the integration of JavaFX modules into OpenJDK. The companies involved in the JavaFX ecosystem are creating additional functionalities and shaping the transition from active Oracle engineering to the year 2022, thereby securing the long-term technological viability of JavaFX. The organizational developer participation takes place via the OpenJDK and from there the open source software could be redistributed. Depending on the expertise of the respective development projects, the involved development companies offer independent support and thus close the gap to new innovative JavaFX features and customer requirements that go beyond the current state of development. JavaFX support is available with the commercial Java SE subscription for JDK 8 (LTS) until March 2025 and could be extended as desired.

Building Mobile Apps with Gluon

Johan Vos, Gluon

Building cross-platform mobile applications for iOS and Android with Java is fairly simple with the Gluon open source and commercial tools. Development teams can quickly build beautiful apps leveraging their Java skills, without extra budget or external teams. This session revisits the state of the latest developments (JDK, Gluon VM, JavaFX). It also demonstrates how you can build applications with one cross-platform Java API and deploy to mobile platforms with compelling UI, native services integration, and seamless connection with the cloud and enterprise back end. You will profit from improved security and common mobile features such as push notifications, authentication, and data synchronization or persistency, among others.

 

The JavaFX Ecosystem

Andres Almiray, Trivadis AG

For the past 7 years we have seen open source libraries and JavaFX projects popping up slowly, however the pace at which new projects appear has increased. We’ll cover a wide range of libraries that will ensure your next JavaFX project becomes a success. Make the most of layouts with MigPane. Spice up your control repertoire with JideFX, Medusa and ControlsFX. Change the looks of your application with the flick of a CSS switch, thanks to JFoenix and BootstrapFX. Decorate your screens with a wide variety of icons from Ikonli. And these are but a few of the libraries we’ll cover.

Developing Business Applications on top of e(fx)clipse

Tom Schindl, BestSolution

In this talk we’ll introduce you to e(fx)clipse which is a JavaFX application framework built on top of OSGi and the UI-agnostic parts of Eclipse 4. We’ll show you applications we built with customers around the world, ranging from 3d modeling tools to sophisticated form applications and PDF-Viewers.

The TilesFX and Medusa Frameworks

Gerrit Grunwald, Karakun, Blog: Harmonic Code

Gerrit presents his two open source frameworks TilesFX and Medusa. TilesFX is used for creating professional and sophisticated dashboards. Medusa delivers a huge set of custom controls that implement gauges, ideal for monitoring applications. Gerrit will share many tricks on how to accomplish eye candy effects.

Extreme GUI Makeover

Dirk Lemmermann, Hendrik Ebbers, Karakun, Blog: GuiGarage

Come and see Dirk and Hendrik take you step by step through the process of turning a dull movie database application into a sexy app filled with eye candy.

JPro in Production

Hans-Henry Sandbaek, Florian Kirmaier, Sandec, JPro One

This session will show how to develop and deploy with JPro, which enables Java programs to run in standard web browsers without a plugin.  By taking a deeper look into some real-world applications, the audience will learn how Java can be used for cross platform development, to write applications for not only desktops, but also for mobile devices and web browsers.  The audience will learn how a typical web page can be created with pure Java.  And the code for the web page runs not only in browsers, but also as native apps (desktops, iOS or Android).  A new portal, a web-based JavaFX ensemble, will be announced and presented, which already consolidates a number of prominent JavaFX libraries, such as ControlsFXand JFoenixand can hopefully serve as a common API Portal for many more libraries in time to come.  Attendees will also learn how to let Java code interoperate with currently popular web technologies such as Angular and React.

JavaFX Real-World Apps: Monastery Disentis

[fusion_builder_container hundred_percent=”yes” overflow=”visible”][fusion_builder_row][fusion_builder_column type=”1_1″ background_position=”left top” background_color=”” border_size=”” border_color=”” border_style=”solid” spacing=”yes” background_image=”” background_repeat=”no-repeat” padding=”” margin_top=”0px” margin_bottom=”0px” class=”” id=”” animation_type=”” animation_speed=”0.3″ animation_direction=”left” hide_on_mobile=”no” center_content=”no” min_height=”none”][fusion_text]

Finally the first “JavaFX Real World Apps” post that actually covers an “app” and not an “application”, meaning the first JavaFX application in this series that was designed for mobile devices and not the desktop. The application is simply called “Monastery Disentis”. It was developed by cnlab in Switzerland. It can be used by visitors of the monastery as a guide. Below you can see a couple of screenshots that were taken on an Android device.

Video: a screencast of the application.[/fusion_text][fusion_text]What is cool about this application is that everybody can try it out be following the links to the app stores, either the Apple App Store for iPhone users or Google Play for Android.

As usual I asked the development team a couple of questions and Daniel Zimmermann was nice enough to answer them below:

General Questions

What is the name of your product / project?

Monastery Disentis

Who are your users / customers?

Monastery of Disentis, Mustér, Switzerland.

What is the purpose of your software? What are its benefits?

Mobile app to guide the user through the monastery church.

Is the application operational? If yes, since when. If not when do you plan to go live?

Yes. It can be installed via the iTunes app store or Google play.

iTunes: https://itunes.apple.com/ch/app/hora-benedicti/id930800749?l=en&mt=8

Google Play: https://play.google.com/store/apps/details?id=ch.cnlab.horabenedicti

Development

How did you get the necessary JavaFX Know-How into your team? (Consultants, Internal / External training courses)?

Internal training.

With which version of JavaFX did you start? 1, 2, 8?

We started with version 8.

When did you start developing the application and how long did it take?

September, 2016, 6 Month with some pauses in between.

How many developers worked on it? In total and on the UI.

2 Developers in total. 1 exclusively on the UI.

How big is the application? Lines of code, Number of classes.

Lines of Code: 11000, No. of Classes: 113.

How big is the JavaFX client? Lines of code, Number of classes.

Lines of Code: 7500, No. of Classes: 51

Why did you choose JavaFX as frontend technology? And very importantly: why did you not choose HTML / Web?

The developer already knew Cordova, but wanted something else. The app‘s scope
seemed small enough to be used for it.

Was it difficult to convince decision makers to agree on JavaFX?

No. Since so we did not need to create two native apps with two developers.

What were the biggest challenges / problems / issues / bugs you faced in the JavaFX part and how did you solve them?

Rendering performance of Text nodes – heavily relied on asynchronous content loading and
lazy content display (in other words: lazily put it onto the Scene Graph).

Which 3rd-party products / frameworks / tools (open source and commercial) did you use and why did you choose them?

JavaFXPorts, Gluon Charm Down, ControlsFX, FontawesomeFX, jackson, commons-codec, Afterburner.fx, ScenicView.

Did you mix JavaFX and Swing code?

No.

Outlook

Would you use JavaFX again for your next project? Please elaborate why or why not.

Yes, but I will think twice for mobile, because the performance is not yet where it needs to
be on all platforms / phone variants.

Which recommendations do you have related to JavaFX for other companies / projects?

Not much, except for: Just give it a try. If you need platform independent Desktop
applications and/or don‘t want to rely on long-term browser support, this is a good and
good-looking alternative.

Which features would you like to see being added to JavaFX?

CSS closer to Web, faster CSS, improved layouting/API, faster text rendering performance.

[/fusion_text][/fusion_builder_column][/fusion_builder_row][/fusion_builder_container]

JavaFX Animation Tool

[fusion_builder_container hundred_percent=”yes” overflow=”visible”][fusion_builder_row][fusion_builder_column type=”1_1″ background_position=”left top” background_color=”” border_size=”” border_color=”” border_style=”solid” spacing=”yes” background_image=”” background_repeat=”no-repeat” padding=”” margin_top=”0px” margin_bottom=”0px” class=”” id=”” animation_type=”” animation_speed=”0.3″ animation_direction=”left” hide_on_mobile=”no” center_content=”no” min_height=”none”][fusion_text]Ok, I guess it is time to let you in on a little secret. The last three months or so I worked on a private project with the goal to create a tool that would allow me to easily create animations for Java desktop applications. JavaFX contains fantastic support on the API level for doing animations but for beginners or even intermediate level programmers it is not trivial to leverage it. However, when I use Apple’s Keynote for creating presentation slides, or when I see the animation / slider plugins for WordPress I realize how easy it can be to do animations, so why not bring the ease of these tools to JavaFX. What you can see in the screenshot below is the result of my work so far.

This is still at an early stage and things are subject to change but the basic idea is this: the output of the tool will be a presentation consisting of several slides. Each slide contains one or more elements. Element types are: region, node (code or fxml), images, and videos (more most likely to come). Each element can have any number of transitions associated with it. The background of the slides can be an image or a video or both. The image below shows a presentation with a background video, and three videos on top of it. Video playback starts when the user presses the green “play” button. However, the start of each video can be delayed by moving the “play” transitions further to the right / to the future, hence adding an initial delay.

It took me 60 seconds to create this second example, just to give you an idea on how much time you can save by using a tool.

Ok, that’s all for now. I hope I will find time to continue work on this tool and maybe present it at JavaOne this year. That is if Trump has resigned before then 🙂

Happy coding everyone!

 

P.S.: below you will find two YouTube videos showing the tool in action

[/fusion_text][fusion_text]Video 1, Video 2[/fusion_text][/fusion_builder_column][/fusion_builder_row][/fusion_builder_container]

JavaFX Tip 24: Custom Layouts for Performance and Flexibility

I just finished a two month sprint on advancing CalendarFX and getting it ready for release 8.4.0. One focus of this sprint was on performance. There are many things that can influence performance but when it comes to JavaFX the number of nodes in your scenegraph and CSS styling are top candidates for optimisation. After reviewing the custom controls that ship with CalendarFX I realized that many of them used a lot of nested panes (BorderPane, VBox, HBox, GridPane) in order to achieve a specific layout. Nested panes result in a high node count and complex CSS styling instructions.

One simple example are the views that CalendarFX creates to visualize calendar entries in the DayView control. This control shows the 24 hours of a day vertically and places DayEntryView instances on them. These entry views look like this:

day-entry-view

In the previous releases of CalendarFX the skin of the entry view used a VBox instance to lay out the two labels that show the title of the entry and its start time. That was the only purpose of the VBox. Doesn’t sound like a big issue but when your application starts to show hundreds of those entries then you end up creating hundreds of VBox instances, too.

The way to avoid this is to mange the positioning of these labels yourself and to implement / override the layoutChildren() method of the skin. Not only do we save one node but it also gives us more flexibility. We can now decide to hide or show the labels based on the available space. In the case of the DayEntryView we can decide to hide the start time label if the available height of the view is not big enough to show both labels. This kind of, may I dare to say it, “responsiveness” is not possible when using the out-of-the-box layout panes that are shipping with JavaFX.

The code of the layoutChildren() method of DayEntryViewSkin can be seen below.

[fusion_builder_container hundred_percent=”yes” overflow=”visible”][fusion_builder_row][fusion_builder_column type=”1_1″ background_position=”left top” background_color=”” border_size=”” border_color=”” border_style=”solid” spacing=”yes” background_image=”” background_repeat=”no-repeat” padding=”” margin_top=”0px” margin_bottom=”0px” class=”” id=”” animation_type=”” animation_speed=”0.3″ animation_direction=”left” hide_on_mobile=”no” center_content=”no” min_height=”none”]

    @Override
    protected void layoutChildren(
                               double contentX, 
                               double contentY, 
                               double contentWidth, 
                               double contentHeight) {

        // Title label.
        double titleHeight = titleLabel.prefHeight(contentWidth);

        // It is guaranteed that we have enough height to display 
        // the title (because "computeMinHeight" returns the min
        // height of the title label).

        titleLabel.resizeRelocate(
                snapPosition(contentX), 
                snapPosition(contentY), 
                snapSize(contentWidth), 
                snapSize(titleHeight));

        // Start time label (only show it when there is enough space).

        double timeLabelHeight = 
                           startTimeLabel.prefHeight(contentWidth);

        if (contentHeight - titleHeight > timeLabelHeight) {

            // make sure to set visibility to true again
            startTimeLabel.setVisible(true);

            startTimeLabel.resizeRelocate(
                    snapPosition(contentX), 
                    snapPosition(contentY + titleHeight), 
                    snapSize(contentWidth), 
                    snapSize(timeLabelHeight));

        } else {
            // Not enough space, hide the start time label.
            startTimeLabel.setVisible(false);
        }
    }

The nice thing about the layoutChildren() method is that it tells you exactly which space it is that your children nodes can use. The space is given by the four parameters contentX, contentY, contentWidth, and contentHeight. So there is no need to first lookup things like insets or padding. The “content” rectangle is the space that is available to you.

The second nice thing when writing your own layoutChildren() method is that you can utilize the snapXYZ() methods provided by the SkinBase superclass. These methods ensure that the child nodes will be sized and placed in such a way that they will appear crisp and not blurry. Why is this needed? Because JavaFX uses double precision coordinates to place nodes and unfortunately “int” coordinates are actually located between pixels on your display. So the snapPosition() method might take your x / y coordinate of 100 / 100 and change it to 100.5 / 100.5.

As mentioned before, the DayEntryView is a simple example. Obviously you can also create very complex layouts by overriding the layoutChildren() method. Did I always do this in the current release of CalendarFX? No, I did not. Very often I exchanged all those nested panes with instances of type GridPane, which does give you a lot of layout options but unfortunately no support for responsiveness.

Hope this has been helpful for some of you.

Happy coding![/fusion_builder_column][/fusion_builder_row][/fusion_builder_container]

JavaFX Real-World Apps: SkedPal

skedpal logo v152

A new entry in the “Real World Applications” series. This time it is SkedPal, an application for managing a busy person’s life intelligently. I have been consulting the SkedPal team in matters related to JavaFX and also when they made the decision to start using the CalendarFX framework for their calendar requirements. Below you can see a couple of screenshots of this attractive application. If you want to try it out yourself then you can simply register on the SkedPal website and download the desktop client (they also have mobile clients).

Screen Shot 2016-04-01 at 10.17.33

Screen Shot 2016-04-01 at 11.24.25

Screen Shot 2016-04-01 at 11.24.10

I have asked Saied ArBabian, the found of SkedPal to answer a couple of questions related to their product, their development, and (of course) their use of and thoughts about JavaFX.

General Questions

What is the name of your product / project?

SkedPal

Who are your users / customers?

SkedPal is a publicly downloadable application made for busy professionals who need to schedule their work in order to better manage their time.

What is the purpose of your software? What are its benefits?

SkedPal’s key objective is to assist busy professionals to deliver their projects on time by scheduling all their work intelligently. It’s a SOA cloud-based application that includes a Narrow Artificial Intelligence scheduling engine in the cloud with a JavaFX client for the desktop and an iOS companion app.

Is the application operational? If yes, since when. If not when do you plan to go live?

We’re in public Beta since 2014. We’re into our 3rd pivot and getting closer to the sweet spot for our users.

Development

How did you get the necessary JavaFX Know-How into your team? (Consultants, Internal / External training courses)?

The team was familiar with Swing and it didn’t take too long to get on board with JavaFX in order to deliver the first version. The training process was internal.

With which version of JavaFX did you start? 1, 2, 8?

Started with version 2.

When did you start developing the application and how long did it take?

We have released two versions so far, and we’re in the middle of our third version. We started in late 2013, and had our first version released in Oct 2014. The second version was released in Jun 2015.

How many developers worked on it? In total and on the UI.

5 Developers in total. 2 exclusively on the UI.

How big is the application? Lines of code, Number of classes.

Lines of Code: 132,000, No. of Classes: 860

How big is the JavaFX client? Lines of code, Number of classes.

Lines of Code: 76,000, No. of Classes: 548

Why did you choose JavaFX as frontend technology? And very importantly: why did you not choose HTML / Web?

Our team’s experience was primarily in Java so in order to immediately get started to deliver a front-end application, it was a natural decision to go for JavaFX. In hindsight, a stronger developer community as it exists for HTML/Web could have been a huge help.

Was it difficult to convince decision makers to agree on JavaFX?

No, decisions in startups are made faster and easier than in enterprise environments.

What were the biggest challenges / problems / issues / bugs you faced in the JavaFX part and how did you solve them?

The high memory consumption of JavaFX was particularly a trouble area for us. The only way to resolve it was to consider the performance constraints in our next iteration design and limit our design to what works.

Which 3rd-party products / frameworks / tools (open source and commercial) did you use and why did you choose them?

Initially we used the MiG Java Calendar which was based on Swing code, and then we switched to CalendarFX for its better UI design and use of JavaFX instead of Swing. We developed our own MVVM framework to support our Service Oriented Architecture. It turned out to be a huge project of its own, and we might open source it at some point to contribute to the JavaFX developer community.

Did you mix JavaFX and Swing code?

Initially yes when we used MiG Java Calendar.

Outlook

Would you use JavaFX again for your next project? Please elaborate why or why not.
Which recommendations do you have related to JavaFX for other companies / projects?

We have made a significant investment in JavaFX technology both in terms of team’s experience over the years, as well as development of a complex MVVM framework. This is a strong reason to stay with JavaFX. On the other hand, we really envy the strong developer community that exists for the web apps and we can see how fast development can become once you have access to such communities with large portfolio of open source codes.

In addition, we’re facing severe issues when our users do not opt to update their client to the latest version. Distribution of JavaFX applications for Internet users is a lot more challenging than web based applications.

Which features would you like to see being added to JavaFX?

We’d like to see better performance (speed and memory.)

Do you plan to provide a mobile version of your application or a mobile addition?

We already have a native (Objective C) iOS app integrated into our SOA architecture. The mobile app and the JavaFX desktop apps work in tandem very well in our MVVM framework.

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!

Never too old to learn!

Yesterday (March 16th) I celebrated my 47th birthday. I am now packing a solid 20 years of work experience and a masters degree in computer science. Still I managed to screw up bad.

A potential customer of mine, who is currently evaluating FlexGanttFX for their application, contacted me and argued that the initial model creation takes too long. 22 seconds to be precise. I asked them to send me a standalone demo and when I ran it I could confirm that it takes a long time to create the model. After further investigation I realized that they were creating over 5 million objects (activities that will be placed on the timeline). All of these objects are then inserted into a balanced binary interval tree. When I saw that I basically told them to stop evaluating FlexGanttFX because it will not be able to handle these many objects and that object creation and the tree modifications do take their time. So the basic message I sent was “Go somewhere else. Fu.. off!”.

However, they also included a snapshot of the profiler they used and I could see that most of the time was spent inside the constructor of the base model class “ActivityBase” and not inside the tree modifications (which I found surprising). After some more research I realized that it was primarily the creation of the activity ID, which is of type String and uses UUID.randomUUID(). So I replaced this logic with a simple counter of type Long. After this change the total time went from 22 seconds to 8. Nice! But it got even better.

To be on the safe side I made sure that the start and end times of my activities are initialized with Instant.now(). However, there was no need for that as those times are usually passed to the activity in the constructor or after creation by calling setStart/EndTime(). After this change the total loading time went down to 7 seconds.

Since the problem at hand was to create a lot of objects very fast I decided to change the initial heap size allocated to the program to 2 Gigabytes. This brought down the loading time to 2 seconds.

From 22 seconds to 2 after 10 minutes of work, not bad! However, quite embarrassing considering the initial “Fu.. off!” 🙂

 

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.