FX Experience Has Gone Read-Only

I've been maintaining FX Experience for a really long time now, and I love hearing from people who enjoy my weekly links roundup. One thing I've noticed recently is that maintaining two sites (FX Experience and JonathanGiles.net) takes more time than ideal, and splits the audience up. Therefore, FX Experience will become read-only for new blog posts, but weekly posts will continue to be published on JonathanGiles.net. If you follow @FXExperience on Twitter, I suggest you also follow @JonathanGiles. This is not the end - just a consolidation of my online presence to make my life a little easier!

tl;dr: Follow me on Twitter and check for the latest news on JonathanGiles.net.

ControlsFX 8.40.10 now available

At JavaOne the other week Eugene Ryzhikov and I announced the release of ControlsFX 8.40.10. Since I got back from JavaOne I have been meaning to announce the release, but never quite got around to it. Now that I have a few spare minutes, I am very pleased to bring this to the communities attention! 🙂

This release is primarily a bug fix release, but there are also a number of nice new features included. It is recommended that all users of previous releases upgrade to this release. This release is baselined on JDK 8u40, which means that we require at least that, but we have also ensured that this build works on more recent releases (notably 8u60 and above broke ControlsFX due to our use of internal API – we are no longer broken in 8.40.10).

As always, you can download ControlsFX directly from the main ControlsFX website, or else you can add it as a dependency in your preferred dependency management tool.

Finally, as I always stress when doing these releases – this release was a community effort and there are a lot of people to thank. At last count, there are over 90 contributors to ControlsFX these days, and this is incredibly pleasing.

ControlsFX and JavaFX 8u60

Update: Just use the 8.40.10 final release now!

With the recent release of JDK 8u60, a lot of people are reporting that ControlsFX no longer works. This is because private APIs that ControlsFX depends on changed in 8u60, and as such we have needed to update our library to deal with this. For those of you who are using JDK 8u60 and want to make use of ControlsFX, please use the latest 8.40.10-SNAPSHOT builds that are available on Sonatype.

ControlsFX 8.40.10 will be released in the next few months. There are a lot of pull requests to merge, and this release will probably be quite a feature-packed release, if the community contributions are anything to go by! Also, Eugene and I will be presenting about ControlsFX again at JavaOne this year, so if you are attending, be sure to come along and say hi!

Announcing ControlsFX 8.40.9 (and 8.20.9)

This release has been a long time in the making – I must apologise for the delays. However, today is the day that I am pleased to announce the availability of ControlsFX 8.40.9. This release is the first release to baseline on JavaFX 8u40, and brings with it hundreds of bug fixes and usability improvements. This release is not a major feature release, but don’t let that dissuade you from downloading and using in place of the previous releases. For those of you stuck on JavaFX 8u20, we’ve also released 8.20.9, but this will be the last ControlsFX release for JavaFX 8u20 – all future releases (for now) are baselined on 8u40.

The main champion of this release is Samir Hadzic. He has almost single-handidly brought this release to life, pushing hundreds of bug fixes, not just in his SpreadsheetView control, but across all of ControlsFX. So, from myself, Eugene, and the many thousands of developers and users of ControlsFX – a massive thank you to Samir! Other contributors to this release include (in no particular order): Dirk Lemmerman, Geoff Capper, Eugene Ryzhikov, Roger Terrell, Robert Lichtenberger, Anirvan Sarkar, Márcio Carneiro Rodrigues, Nicolai Parlog, Andreas Liebelt, Cole Markahm, Danno Ferrin, Jeff Plourde, Steffen Rachner, Jason Pollastrini, Lukasz Sliwinski, Ralf Schmitt, Thijs Walcarius, and James Denvir. On top of this is our excellent translation team, who translated this release into 23 languages. A huge thank you to everyone who contributed!

If you are unfamiliar with ControlsFX, you can get an overview of the main features. As always, you can download the latest release from controlsfx.org, as well as find the latest release and hourly snapshot builds on Maven Central.

Announcing ControlsFX 8.20.8

Announcing ControlsFX 8.20.8

Hot on the heels of the 8.20.7 release, I am pleased to announce the release of ControlsFX 8.20.8. This release is primarily a bug fix release (to smooth some of the rough edges from 8.20.7), but there are also a couple of new features in this release to keep things interesting. The main bug fixes include:

  • ControlsFX 8.20.7 only worked on JavaFX 8u20. This has been fixed so ControlsFX 8.20.8 works on JavaFX 8u20 and later (such as the just-released 8u25).
  • ControlsFX-Samples was not executable because we changed our build scripts in 8.20.7 and forgot to include the relevant manifest attributes. This has been fixed.
  • SpreadsheetView continues to receive bug fixes (and unit tests).
  • It was not possible to use the Notifications API in an OSGi environment – now it is.
  • And of course a bunch of other useful bug fixes!

The two main features in this release were both contributed by Dirk Lemmermann. They are:


TaskProgressView
The task progress view is used to visualize the progress of long running tasks. These tasks are created via the Task class. This view manages a list of such tasks and displays each one of them with their name, progress, and update messages.

An optional graphic factory can be set to place a graphic in each row. This allows the user to more easily distinguish between different types of tasks.

task-monitor


ListSelectionView
A control used to perform a multi-selection via the help of two list views. Items can be moved from one list (source) to the other (target). This can be done by either double clicking on the list items or by using one of the “move” buttons between the two lists. Each list can be decorated with a header and a footer node. The default header nodes are simply two labels (“Available”, “Selected”).

list-selection-view


If you are unfamiliar with ControlsFX, you can get an overview of the main features. As always, you can download the latest release from controlsfx.org, as well as find the latest release and hourly snapshot builds on Maven Central.

Announcing ControlsFX 8.20.7

Announcing ControlsFX 8.20.7

It’s time for another ControlsFX release, this time taking the version number on another jump up the scale and finally settling on version 8.20.7. What this version number represents is the fact that this release requires JavaFX 8u20 and will not work with earlier versions. If you want to use ControlsFX with JavaFX 8.0, you will need to use ControlsFX 8.0.6.

Why the delay?
This release has been brewing since 8.0.6 was released on May 29th – so basically four months. This is not typical for us (we normally have much quicker releases), but Eugene and I were both distracted on a major undertaking – elevating the ControlsFX dialogs API and implementation into the next release of JavaFX itself (it’ll be appearing in JavaFX 8u40, although the API is vastly different than what you see in ControlsFX 8.0.6). The end result is that we iterated through a bunch of API design work (see RT-12643) and none of that benefited ControlsFX, but it took up all our time.

Once JavaFX 8u40 dialogs were API complete (which was only mid-August), we developed a plan for how to proceed with ControlsFX dialogs. In essence we didn’t feel that it was wise to maintain a dialogs API in ControlsFX that was so divergent than what will ship in JavaFX 8u40. Therefore, the plan that we developed was to deprecate the old ControlsFX API, fork the JavaFX dialogs API into a new project called openjfx-dialogs, and to recreate the additional features that ControlsFX includes (but are lacking in JavaFX itself) using the new API (this includes dialogs like progress, font chooser, command link, login, etc). The end result is two-fold:

  1. ControlsFX 8.20.7 has an external dependency on openjfx-dialogs, but this will only be the case until we baseline on JavaFX 8u40, at which point it can be removed.
  2. ControlsFX 8.20.7 ships with two dialogs APIs! The saving grace is that the old one is still fully functional but deprecated – hopefully that will give you enough of a hint that the old API will go away in a future release.

The nice thing about openjfx-dialogs is that people wanting to use the new JavaFX dialogs API in 8u20 can do so – just download the jar (or set it as a dependency) and you can use the API (and implementation) exactly as it will be in 8u40. This is great for me – it gives me more testers of the JavaFX dialogs API and implementation – hopefully you can file bugs if you run into them.

What else is new in ControlsFX 8.20.7?
On top of the already mentioned dialog classes, the major new features in ControlsFX 8.20.7 are a new Wizard API (again, built using the new dialog API) and a StatusBar control:

Wizard
The wizard was implemented by Eugene and myself. I think it strikes a really nice balance between simplicity and flexibility, but I am sure that over time we will continue to tweak the API as we get more user feedback. The thing I like most about the API is its simplicity. In the common use cases, you can simply specify the pages you want to show, and that’s it. Once the dialog is closed by the user (or in fact, at any time), you can query a Map to retrieve the input that the user has put into all fields of the wizard. The Wizard knows how to extract values from most commonly used controls, and if it can’t, you can easily add support for custom value extractors. On top of this, the wizard supports linear and conditionally branching page flows. Here’s a screenshot from our simple test wizard:

wizard

StatusBar
The status bar control was contributed by Dirk Lemmermann. It is normally placed at the bottom of a window. It is used to display various types of application status information. This can be a text message, the progress of a task, or any other kind of status (e.g. red / green / yellow lights). By default the status bar contains a label for displaying plain text and a progress bar for long running tasks. Additional controls / nodes can be placed on the left and right sides.

The picture below shows the default appearance of the StatusBar control: statusbar

The following picture shows the status bar reporting progress of a task:

statusbar-progress

The last picture shows the status bar with a couple of extra items added to the left and right:

statusbar-items

Miscellaneous Improvements
Of course, on top of the major new features / changes, there is a bucket load of small improvements, including the following:

  • Improved glyph font support, including support for the latest FontAwesome release.
  • Improved build system – we now have just one gradle project that can work with ControlsFX, ControlsFX-samples, and FX Sampler.
  • Action and Dialogs API refinement, based on our work moving dialogs up to JavaFX 8u40.
  • New CSS tab in FX Sampler – now FX Sampler can not only syntax highlight the code of a sample, it can also syntax highlight the CSS of the control.
  • The validation API now supports regular expressions and predicates.
  • Improved internationalisation support – we are fully integrated with Transifex, and the community is always welcome to help translate.
  • Big performance improvements in SpreadsheetView.
  • Support for any span in SpreadsheetView fixed row/columns
  • RangeSlider is now a lot less finicky about setting min / max / high / low values.
  • Lots of bug fixes, particularly in Dialogs, Actions, SpreadsheetView, as well as the Check* controls (CheckListView / CheckTreeView / CheckComboBox).

That’s all for this release – we hope you appreciate all the hard work that the team is putting in to ControlsFX, and that you might consider offering bug fixes or bug reports. If you want to get involved, check out our documentation that describes everything that you need to know to get started.

Announcing ControlsFX 8.0.6

Announcing ControlsFX 8.0.6

Wow – this release of ControlsFX is a big one in all respects! It took just shy of three months, consists of nearly 500 changesets, has been translated into 17 languages, and includes a huge number of bug fixes and new features. This is going to be a long post, so strap yourselves in and please read to the very end – this release has some important changes!

This release also continues in the long tradition of being a real team effort. ControlsFX wouldn’t be where it is today without the hard work of the following contributors: Eugene Ryzhikov, Samir Hadzic, Gabriel Féron, Carolina Veiga, Anirvan Sarkar, IsNull, Artur Biesiadowski, Yair Oren, Davide Nabais, Tom Eugelink, Michał Skowroński, Uwe Sander, Laurent Gebus, Geoffrey Capper, Romain Moreau, Mario Voigt, Ruben Paz, Jonathan Millman, Chen Gaofeng, Ladislav Török, Tiziano Lattisi, Victor Alfonso Pineda Orozco, Daniel Rodrigues, Avramucz István, Sriram Raghuraman, Dirk Lemmermann, Florian Brunner, and Christian Michelsen. Apologies if I missed anyone! As always, if you see these people walking down the street, give them a high-five or a knowing wink, as in to say “You’re a cool person – I appreciate your hard work”.

With that out of the way, lets dive in.

Important Release Note Regarding JavaFX 8u20

Everyone should upgrade to ControlsFX 8.0.6, but especially so if you are running JavaFX 8u20 on your machine. This is because ControlsFX 8.0.6 is the first release to support 8u20. You may be asking yourself why this is necessary – the answer is that ControlsFX uses internal JavaFX API, and this changed between JavaFX 8 and JavaFX 8u20. This is entirely our doing, so is no reflection on JavaFX itself. To support 8u20, we therefore are forced to release two separate releases: ControlsFX 8.0.6 for JavaFX 8.0, and ControlsFX 8.0.6_20 for JavaFX 8u20. I apologise for the extra hassle, but hey, at least ControlsFX works on both, right? 🙂

New Features

I should start by saying that this release was largely about consolidating what we had, so most of our focus has been on improving the quality of the release, and slowing down the introduction of new features. This approach will continue in future releases, as I don’t want to let the quality of any release fall below a (very high) threshold. This release was largely focused on decoration and validation. We already have plans for future releases – if you want to know more, it is a good idea to join our google group.

Decoration framework
ControlsFX 8.0.6 introduces a brand new (and at this stage relatively simplistic) decoration framework, to allow for developers to apply decorations to nodes on screen. For example, you may want to show graphics in the corner of your nodes, or add a styleclass in certain circumstances. The decoration framework makes this kind of action trivial. However, to be fair, the decoration framework was primarily developed to be the visual feedback mechanism for a validation framework, and we have one of those in ControlsFX 8.0.6 too (read down a bit further to see screenshots of it in action!).

SnapshotView
The SnapshotView is a control that allows for users to draw a bounding box inside a scenegraph (or typically in an ImageView). This bounding box represents the dimensions of their selection, and from which an image can be created of the selected area. This is another of those controls that is easier to describe with an image, so, see below! 🙂

SnapshotView - the 'Controls' section of the image has been selected.

SnapshotView – the ‘Controls’ section of the image has been selected.

 

Translations
We did a big push in ControlsFX 8.0.6 to externalise all translatable strings, and to get the community to help translate these strings into their local languages. I am so pleased to say that the community did an excellent job, resulting in ControlsFX 8.0.6 being translated into 17 languages! Hopefully in future versions we can take that number even higher, but for now we really do have an excellent amount of language coverage.

Validation framework
As mentioned above, we introduced a decoration framework in 8.0.6, primarily to enable the validation framework. The validation framework helps developers to validate user input and assists with reporting errors and warnings. It is designed to be lightweight but extensible, and will grow over time as developers suggest desired functionality (we are definitely open to suggestions!).

Graphic decorations showing how validation failed.

Graphic decorations showing how validation failed.

CSS decorations showing how validation failed.

CSS decorations showing how validation failed.

Other miscellaneous improvements
We can’t list everything (that’s what the hg changelog is for!), but here are some other highlights:

  • The SpreadsheetView continues to be improved – performance is better, functionality is greater, and API is becoming more polished.
  • It is now possible to specify the effect to display when a lightweight dialog is shown (rather than the default gray background).
  • The FXSampler project (which is a standalone project that you can use to demonstrate your own JavaFX stuff!) now has support for custom welcome pages. Very cool!
  • The login dialog shakes (almost mockingly) when you type in the wrong username / password combination.
  • The PopOver control got some useful bug fixes and additional API for hiding PopOver.

Breaking Changes

There is always a tension when working on API between retaining a stable API and continuously improving the API. Believe me, I’ve heard all arguments in my work on JavaFX UI controls! Unlike JavaFX with ControlsFX we are a little more flexible with our backwards compatibility requirements. In other words, I am more than happy to break API to get a better API. This release is by far the biggest release for breaking API, so I want to spend a few moments outlining the major changes, and what you need to do to upgrade to ControlsFX 8.0.6.

Action extends EventHandler<ActionEvent>
Previously the Action interface had an execute(ActionEvent) method, but it seemed pointless to roll our own API when, by extending EventHandler<ActionEvent>, we could directly install an action into, say, the Button.setOnAction(EventHandler<ActionEvent>) method. Unfortunately, EventHandler has a handle(ActionEvent) method, so this means that in all cases where you had Action code, you simply need to rename your execute method to handle.

Dialogs now return Optional
With Java 8 introducing the Optional class, we have updated some of the Dialogs API to return Optional, rather than the object directly.  This means that previously where there was code that looked like the following:

String response = Dialogs.create()
    .title("Name Check")
    .masthead("Please type in your name")
    .message("What is your name?")
    .showTextInput();

if (response != null) {
    System.out.println(response);
}

You now instead need to do the following:

Optional<String> response = Dialogs.create()
    .title("Name Check")
    .masthead("Please type in your name")
    .message("What is your name?")
    .showTextInput();

response.ifPresent(name -> System.out.println(name));

In other words, code that previously checked for null will now no longer work, as the returned Optional will never be null! You need to instead operate on the Optional instead, as shown above.

Getting ControlsFX

As per usual, more details about getting and using ControlsFX can be found on the ControlsFX website. You can also read through a high-level summary of all the features in this release, and peruse the JavaDocs (where we put the bulk of our documentation) if you want the gritty details.

From all the ControlsFX contributors, we hope you enjoy this release, and we hope that you may consider supporting the project in the future!