Hi folks – another quiet week on account of the looming JavaOne conference. In my (way too many) years doing this weekly series, things always go quiet around this time as people start to work on their projects for JavaOne. For me that means I need to get head down on ControlsFX and Scenic View. If you’re working on a project for JavaOne (or just in general), good luck! 🙂
That’s all for this week – catch you again next week (August already?!!!).
A relatively quiet week this week, with most people probably heads-down on JavaOne preparations by now. In any case, what we have below are some very interesting links, so enjoy! 🙂
- The JavaFX dialogs discussion continues. This week I posted an updated summary of where the discussions are now, and of course there has been plenty more discussion since then in the Jira issue (RT-12643). The final API for dialogs is due in early August, so time is running out – if you want to offer your opinion on what JavaFX needs, and especially if you can relate it back to the proposed APIs in RT-12643, now is the time!
- Dirk Lemmermann continues to post JavaFX-related tips, including ‘Beauty is Skin Deep‘, ‘Do Not Mix Swing / JavaFX‘, ‘Custom Composite Controls‘, and ‘Updating Read-Only Properties‘.
- One area that I’ve seen a few people working on recently is support for detaching tabs from a TabPane in JavaFX. This is something I would love to see one day in JavaFX itself. This week Jens Deters offers up his implementation, which looks very nice and polished.
- Geertjan Wielenga has posted about Monet, a project which offers tight JavaFX Scene Builder integration in NetBeans IDE, developed by Sven Reimers.
- Josh Juneau has an article in the latest Java Magazine about JavaFX with alternative languages.
- Alexander Casall has a post about decoupling the view and its behavior in JavaFX to create a testable UI.
Catch you all again next week!
Since the initial JavaFX dialogs post here on FXExperience, the JavaFX dialogs discussion has been going gangbusters, most of it at the Jira issue over at RT-12643. Now that things have settled down a little, I wanted to take a step back and summarise where things are, and what has been discussed in the Jira issue and in comments to the previous blog post. I also want to discuss the evolution of the API (and implementation) that Eugene Ryzhikov and I have been working on (derived from ControlsFX). I apologise in advance for not covering all the points people have raised in the Jira issue – partly it is because I want to focus on what I perceive to be the most important points, but also it is because I’ve just returned from vacation, so things take a while to page back into memory.
RT-12643 has been really useful at discussing both peoples use cases and API details. There have been multiple implementations developed and discussed, and I think in general the members of the community involved in the discussion are in violent agreement over what is necessary at the core, with some differing opinions on exactly how to approach aspects of the API. My impression is that most people are happy with the direction of the discussion, but I’m always happy to be proven wrong! 🙂 There have been a few alternative implementations provided (which are all attached in RT-12643), and I’ll do my best to summarise their differences (or important ideas) briefly below:
- Mikael Grev proposed a fluent API that uses a ButtonType enumeration to individual buttons available, and then has API to pass in a varargs argument consisting of the buttons to show in the dialog (although custom buttons are also supported). The ButtonType is also used as the return type for dialogs that don’t require user input (dialogs that require user input return the user input as the result). I like the use of Optional (it is something ControlsFX uses too) and the fluent API (which is something I’ve already removed from my API due to feedback that it doesn’t fit the JavaFX API style). Things get a little complex if the same ButtonType is used multiple times, but other than that it seems to be a fine API.
- Scott Palmer proposed a more low-level API – it relies on a DialogType enumeration to specify which buttons to show (e.g. OK, OK_CANCEL, YES_NO_CANCEL, etc). The result back from the Dialog is a String representing the button, which you can compare against a constant (e.g. if (result == Dialog.OK_BUTTON_ID)). If users want a button that is not part of the DialogType enumeration, they can do so by creating a Dialog instance and overriding a createButtonBar() method, at which point it becomes their responsibility to create and layout all buttons. If users want to customise a Button, they can do so by getting the dialog pane from the dialog, and calling lookup with the button ID. This returns the Button instance that they can customise to their needs.
- Graham Matthews proposed yet another approach which relied on dialogs being more easily broken down and recomposed. To achieve this his implementation introduce a DialogModel to represent properties like title, blocking, modality and the result of the dialog. It then has a DialogPane class that accepts the model, as well as the display content, and is able to show the dialog when requested. There are subclasses of DialogPane for common use cases like OkCancelDialog, which handles the creation and placement of the OK and Cancel buttons. The DialogPane can be completely customised by the user overriding the buildContent() method with their own code.
As feedback and alternate implementations have been received, Eugene and I have been revising our dialog API and implementation (as noted, a fork from ControlsFX). It is hoped that as we revise our API we will slowly take into account the feedback and ideas people have been proposing. I’ve been posting javadocs of each revision on my website, so for those of you interested in seeing the evolution and giving your thoughts, here are the links of the already posted APIs:
The changes between revisions is relatively minor:
- Version 1 is the ControlsFX API. It has a fluent Dialogs API for the ‘high-level dialogs’, and a Dialog API for ‘low-level dialogs’.
- Version 2 is the first API based on community discussion. This version removes the fluent Dialogs API, instead making the Dialog class support high- and low-level dialogs by adding additional setters and show*() methods. We also improved the Action API to have id / style / styleClass properties so that controls generated from the Action can be more easily styled via CSS. Even though it doesn’t appear in the API docs, version 2 did include the concept of a ButtonBar / ButtonType, as shown in the version 3 API docs.
- Version 3 refined the Action API slightly – it removed the id property added in version 2, and added a lot more complexity around the graphic property to account for the fact that a single graphic Node in an Action could not be used in multiple controls (the scenegraph does not support a node being in multiple places).
My gut feeling remains the same as it did at the beginning: a JavaFX dialogs API should provide a simple way for users to create and show a modal and blocking dialog to a user. In my mind, this is the 90% use case. The extent of customisation in this API is enough to change title, header (our new name for masthead), graphic, content and buttons. Of course, by being able to change content, the entire visuals of the Dialog can also be changed. What has become more obvious to me in the discussions is the other use cases people have, and their objections to the API I was proposing, including:
- Dialogs should ideally support non-blocking and non-modal modes.
- Dialogs should ideally support further customisation by being able to access the root pane of the dialog.
- Some people feel that the requirement to use Action is overkill, and would rather create their buttons in an alternative manner.
Version 3 was given a slightly more comprehensive internal API review, and I posted the feedback from this in Jira. This API review, along with the miles of community feedback, has helped to inform V4, which is now available for review. I need to stress immediately that V4 does not imply that this version is better than V3, it is just a variation on API based on feedback. It may very well be that we decide that V4 is taking things too far, and that the added complexity is not worth the cost. I am very keen to hear your thoughts on this – please post them over at RT-12643.
What are the changes in V4? Here’s a high-level summary:
- We’ve made the root node of the dialog more accessible – you can now call dialog.getDialogPane() to get a DialogPaneBase instance. This allows for you to completely modify the dialog (it’s a GridPane, so go wild). It also has helper API to access the common sections of the default dialog.
- We’ve created a DialogBase class that has two generic parameters – one for specifying the actions type (note that this is small ‘a’ action – there is no Action API dependency in DialogBase), and one for specifying the result type). We have also added a Dialog subclass of DialogBase, which uses the Action class for both the actions type and the result type.
- Action has been simplified – we now don’t have graphicFactory to deal with the limitations of the scenegraph. Now the graphic property is just an Image, which can be reused multiple times in the scenegraph (as each time it will be placed in its own ImageView node).
We also made a bunch of small tweaks:
- Masthead has been renamed header
- There is API to specify modality
- There is API to get the dialog owner object
- Some methods have been renamed to be more Scene Builder friendly
- Events have been added for onShowing, onShown, onHiding, and onHidden.
The result of the V4 API is that we have more classes, and more complexity (although most of it is hidden to users who just want to show a dialog). The way 95% of people interact with the API remains the same – they create a Dialog instance, set the title/header/content/actions and then call one of the show methods. The rest of the API is for people who want more power to customise their dialog. The big question I have for the community is, how do you feel about this? Is the additional functionality worth the extra complexity? What use cases do you have to have alternative action and return types, and is the API suitable for you? Is there more that needs to be done to enable your use case?
So, that’s where things are today. How can you help? Get into RT-12643 and offer your thoughts and use cases. It would be especially great if you could relate your use cases back to the APIs that are highlighted in the V3 and V4 links above. I’m really keen to hear from people who have taken a good long look at the V4 JavaDoc and are concerned about some aspect not meeting their requirements.
Sorry about not posting links last week – I was on vacation, and the internet in my hotel was terrible. Because I didn’t get a post out last week, this week I have a heap of links to share. Enjoy! 🙂
- Geertjan Wielenga has posted about his modular JavaFX Application Framework project, which looks promising.
- Danno Ferrin has put out updated versions of the Gradle and Maven plugins for JavaFX 8u20.
- Tomas Mikula has created a simplified VirtualFlow implementation for use in his RichTextFX project. VirtualFlow is used to efficiently handle ListView, TableView, etc. Tomas’ implementation is a more performant implementation, at the cost of reduced functionality. As the owner of the JavaFX VirtualFlow implementation, I would love to see the official code getting faster, but it is very, very hard to achieve without functional regressions. It is always one of those tasks I try to undertake once per release, but I think most of the low-hanging fruit has well and truly been picked. Quick update: I just spent an hour trying to improve the performance of the JavaFX VirtualFlow based on Tomas’ benchmark, and managed to take the results from 25/25/5/75 to 1/0/5/0 (refer to the flowless wiki document to understand what these numbers mean). You can see more detail in my last two comments over at RT-35395.
- Dirk Lemmermann continues to post JavaFX-related tips, including ‘Have the Final Word‘, ‘Be Observable‘, ‘Use Transparent Colors‘, and ‘Use CSS Color Constants / Derive Colors‘.
- Jens Deters has three posts. Firstly, he has a post talking about how to get rid of focus highlighting in JavaFX. David Grieves’ comment gives good insight into how borders are handled in JavaFX. Secondly, Jens has announced that MQTT.fx 0.0.4 has been released. Finally, Jens has a post about UI logic with JavaFX Bindings.
- Andres Almiray has two posts on ‘getting started with Griffon and JavaFX’. The first post talks about “the new capabilities of the framework, specifically targeting JavaFX as the main UI toolkit and Java as the main programming language.” The second post talks about the same application as in part one, but using Groovy instead of Java.
- Pedro Duque Vieira has blogged about the addition of a ToggleSwitch control to JFXtras, which also includes a JMetro style.
- John Sirach has posted a review of the recently released JavaFX 8: Introduction by Example book.
- Alexander Casall has a post about how to get the controller of an included FXML when using FXML composition.
- Manuel Mauky has been working on an ‘Advanced Bindings‘ project for JavaFX, which, not surprisingly, is “a collection of useful helpers and custom binding implementations to simplify the development of applications that are heavily based on JavaFX’s Properties and Bindings. “
- David Gilbert let me know that JFreeChart 1.0.18 has been released. He went on to say that “it features JavaFX support with a new ChartViewer control that renders charts to a Canvas node and handles tooltips, a context menu, zooming via mouse drag and wheel events, panning and mouse event notifications (more or less equivalent to the existing ChartPanel class used in Swing). This will ease the path for our users that are migrating Swing applications to JavaFX, as their charting code will require very minimal changes.”
- Mark Stephens from IDR solutions (makers of the PDF viewing software for Swing and JavaFX) let me know that they “offer an Open source version (with less bells and whistles) under an LGPL license at http://www.idrsolutions.com/open-fx/“. He went on to say that “we wanted a generic free version which lots of people could use (including us in our NetBeans plugin) and we think there are lots of uses for this in embedded. Then a high end supported version with support and lots of extras (like a slick pageflow which could work really nicely on a Pi with touchscreen) which funds the development.”
- Johannes Rupprecht has a post about custom transitions in JavaFX.
That’s a lot of links! Keep up the hard work folks, it’s fascinating reading what you’re all doing, and it makes me jealous that there aren’t more hours in the day to hack on all the stuff you’re doing.