New Website!

I am happy to announce that I finally managed to consolidate all 5 JavaFX-related websites of mine into one. It can be found at http://www.dlsc.com. The websites in question are:

  • This blog “Pixel Perfect”
  • FlexGanttFX.com
  • CalendarFX.com
  • FlexGantt.com
  • DLSC.com

2015: The Year When JavaFX Takes Over

trend

 

I must say that I very much enjoy using Google trends to evaluate the importance of a technology and to see what its future will look like. So today I ran a comparison between “Java Swing” and “JavaFX”. The result shows two things: once we enter the next year JavaFX will be more relevant than Swing but JavaFX will not be that relevant either.

I think this is totally wrong.

Based on the feedback I am getting from the community and also on the projects that I had contact with I foresee a rapid increase in JavaFX usage (and Google searches) over the next 6 to 9 months.

The main reason is the fact that a lot of companies will finally upgrade to Java 8 next year, and JavaFX has really only reached its full potential with this latest Java release. The second reason is the increased availability of third party solutions: open source projects like ControlsFX and JFXtras, and some commercial products (like mine: FlexGanttFX and soon FlexCalendarFX). The third reason will be the availability of JavaFX 8 on mobile devices (Android and iOS). Once managers see that they can ask their developers to use a single UI toolkit for desktop and mobile  development there will be no holding back.

So that’s my prognosis, please make sure to check back in Q2 2015 to see if I was right or wrong.

FlexGanttFX: First JavaFX Component on ComponentSource

Yesterday FlexGanttFX has become the first JavaFX component in the product catalog of ComponentSource.com. You can find the entry here. ComponentSource is an international reseller of software components, basically the “App Store” of custom controls.  The fact that FlexGanttFX has been listed shows that the market is reacting and that JavaFX is gaining acceptance.

Screen Shot 2014-09-20 at 10.54.04

New Release: FlexGanttFX 1.0.0

Gantt Chart
I finally managed to put together a 1.0.0 production-ready release of FlexGanttFX. After two early access releases at the beginning of the year I put in a lot of hours to get the framework to a maturity level that I deem to be high enough for real-world application development. The release can be downloaded from the product website at http://www.flexganttfx.com. I would recommend to run the three standalone demos in this distribution to get an idea of FlexGanttFX’s capabilities.

FlexGanttFX is much bigger than a regular JavaFX control. The view consists of 83 and the model of 58 classes. It could have been even bigger but during development I decided to contribute some of the custom controls to the ControlsFX project (e.g. StatusBar, PopOver, PlusMinusSlider, HiddenSidesPane, MasterDetailPane).

emirates

There were two events in the past that delayed the release: the first one was a requirement from an early adopter to use the graphics area of the Gantt chart standalone, without the tree table view on the left-hand side. They wanted to use it as an editor for creating classroom schedules. Even though this requirement delayed the release it turned out to be very beneficial for the overall design of the framework. In the end I came up with four different ways the graphics can be presented: single row, using a VBox, using a SplitPane, or using a ListView.

The second event was the release of JDK 8u20. Changes were made to the way CSS was applied / processed which caused many warning messages to be shown in the console (“…unable to resolve -fx-background-color …”). While most people only get these warnings I could actually see that the layout of the controls in the Gantt chart was messed up. I had to find work-arounds for these issues which took a long time. I still see these messages but they seem to be harmless now. If anyone can point me to the root of this problem I would very much appreciate it.

msproject

I would like to say a special thank you to Gilberto Gomez, Werner Lehmann, and Christian Hollmann of MINT Media who provided very valuable input during the development of FlexGanttFX. I would also like to say thank you to the entire JavaFX developer community, especially the guys from Oracle and ControlsFX (Jonathan Giles, Eugene Ryzhikov).

JavaFX Tip 8: Beauty is Skin Deep

If you are developing a UI framework for JavaFX, then please make it a habit to always split your custom controls into a control class and a skin class. Coming from Swing myself this was not obvious to me right away. Swing also uses an MVC concept and delegates the actual component rendering to a UI delegate, but people extending Swing mostly subclassed one of its controls and added extensions / modifications to the subclass. Only very few frameworks actually worked with the UI delegates (e.g. MacWidgets).

I have the luxury of being able to compare the implementation of the same product / control once done in Swing and once done in JavaFX and I noticed that the JavaFX implementation is so much cleaner, largely because of the splitting in controls and skins (next in row: CSS styling and property binding). In Swing I was exposing a lot of things to the framework user that I personally considered “implementation detail” but that became public API nevertheless. The JavaFX architecture makes it much more obvious where the framework developer draws the line between public and internal API.

The Control

The control class stores the state of the control and provides methods to interact with it. State information can be: the data visualized by the control (e.g. the items in TableView), visual attributes (show this, hide that), factories (e.g. cell factories). Interaction can be: scroll to an item, show a given time, do this, do that. The control class is the contract between your framework code and the application using the framework. It should be well designed, clean, stable, and final.

The Skin

This is the place to go nuts, the Wild West. The skin creates the visual representation of your control by composing already existing controls or by extending the very basic classes, such as Node or Region. Skins are often placed in separate packages with package names that imply that the API contained inside of them is not considered for public use. If somebody does use them then at their own risk because the framework developer (you) might decide to change them from release to release.

 

 

 

JavaFX Tip 7: Use CSS Color Constants / Derive Colors

When working on FlexCalendarFX I got to the point where I had to define a set of colors to visualize the controls for different calendars in different colors. And not just one color per calendar but several: a background and a text color for deselected / selected / hover states.

The  colors were used in several places but for the sake of brevity I only focus on the visual calendar entries in the day view of FlexCalendarFX. The two screenshots below show the same entry, first deselected, then selected.deselected-entry
selected-entry

What is important to notice is that these are not completely different colors but they all have the same base color (green) but with different saturation.

The code below shows the best way I could find to define related colors in JavaFX CSS. I define the base color globally under “.root” and derive all other colors using this constant.

.root {
   -style1-color: rgb(119, 192, 75, .9);
}

.style1-entry {
   -fx-background-color: derive(-style1-color, 50%);
}

.style1-entry:selected {
   -fx-background-color: -style1-color;
}

.style1-entry-time-label, .style1-entry-title-label {
   -fx-text-fill: derive(-style1-color, -50%);
}

Please notice that the base color is using transparency as described in my previous blog about transparent colors. The other background colors in this CSS fragment are all derived from the base color. They are either brighter (positive percentage value in derive function) or darker (negative percentage value).

By using this approach to defining colors you can achieve a consistent and smooth look for your application and it will not look like your child’s coloring book.

JavaFX Tip 6: Use Transparent Colors

Picking the right colors for your user interface elements is always a great challenge, but it is even more challenging when you develop reusable framework controls where you as a developer have no control over the look and feel of the application using them. While you might always add elements on top of the default gray background the developers embedding your controls  might have more of a gothic tendency and use a black background. All of a sudden the nice colors your picked clash with the rest of the application.

To tackle this problem the best way I found while working on FlexGanttFX and FlexCalendarFX was to use semi-transparent colors. When you do the color of your UI elements will always be a mix of their own color and the background color. Your colors will become brighter if the application uses a white background and darker if it is using a black background. The contrast between your element and the background will never be strong, which makes for a smooth appearance.

The following screenshots were taken from FlexCalendarFX (work-in-progress).

opacity1

Same UI now with a darker background. You might not see it at first, but the green and blue are actually different between these two screenshots. These are very subtle differences, but they make a big difference in the overall impression of your application.

opacity2

In JavaFX you can define colors in CSS with an alpha channel value smaller than 1 to achieve transparency:

.my-style {
    -fx-background-color: rgba(255, 255, 255, .7); // transparent white
}

Using opacity also has the nice side-effect that you can still distinguish different elements even when they overlap each other.

JavaFX Tip 5: Be Observable

Even in this time of total NSA surveillance it is still a good idea to implement your JavaFX controls with observability in mind. This is easy to achieve in JavaFX especially compared to Swing.

The Old Days

Coming from Swing I was used to spending a lot of energy and time on making custom controls observable. It usually required adding methods to add and remove listeners of a certain type. This listener type was a new interface, the single method of that interface accepted a new event object. To send this event object the control had to “fire” it inside my custom control, so I ended up writing fireXYZ() methods. A lot of work only to let somebody know that some aspect of the control’s state has changed.

The New Age

In JavaFX observability can be achieved much more easily by using properties and observable collections. In the FlexGanttFX framework almost every attribute of its controls are properties and all collections are created via the FXCollections class, which returns observable collections. This makes a lot of sense because the total of the attributes of each control define its state and this state needs to be observable so that other parts of the application (especially other controls) can react to state changes.

Boilerplate Code

The downside of using properties is that you end up writing a lot of boilerplate code but still much less than in Swing. In the case of a boolean property it will look like this:

public final BooleanProperty showStuff =
     new SimpleBooleanProperty(this, "showStuff", true);

public final BooleanProperty showStuffProperty() {
   return showStuff;
}

public final boolean isShowStuff() {
   return showStuff.get();
}

public final void setShowStuff(boolean show) {
   showStuff.set(show);
}

And yes, you should follow exactly this coding convention. For a property called xxx provide a property accessor method called xxxProperty(), a setter called setXXX() and a getter called getXXX(). This is the way it is used throughout JavaFX and you should stick to it.

When working with collections you typically end up with at least this code:

private final ObservableList<String> names =
     FXCollections.observableArrayList();

public final ObservableList<String> getNames() {
   return names;
}

In the JavaFX core controls collections are often stored in a property so that the whole collection can be replaced by a new collection. So far I haven’t really seen a strong requirement for this in my controls and not doing so means I do’t have to write property listeners for this case.

Listeners

Now that our control attributes are properties we can easily react to state changes by adding listeners to them (using lambda expressions).

myControl.showStuffProperty().
   addListener(it -> showStuffChanged());

myControl.getNames().
   addListener((Observable observable) -> namesChanged());

Conclusion

When designing your own custom control expose its state in the control class via properties and observable collections. By doing so everyone will be able to observe the state of your controls in a way that is consistent with the entire JavaFX framework and that will enable other developers to seamlessly integrate their controls / their application with your controls.

JavaFX Tip 4: Have the Final Word

When developing custom controls for JavaFX I would highly recommend to follow in the footsteps of  the core JavaFX controls and to make the API of your controls as final as possible and to put the “final” keyword in front of all your method declarations.

Example

In FlexGanttFX I have a lot of code that looks like this:

public final Activity getActivityAt(double x, double y) { ... }
public final Row getRowAt(double y) { ... }
public final void setShowLinks(boolean show) { ... }

 

Why?

When you design a control you have a specific behaviour of the control in mind. This behaviour can be protected by using “final”. If you do not use it then other developers will subclass the control, they will override its methods, they will run into problems, and they will submit a defect ticket to your issue management tool. In the end you will waste your time on chasing their bugs. Bugs that only exist because your control was used in a way that you couldn’t possibly foresee.

Where?

Protection is especially needed for the public API of the control class, which is managing the “state” of the control. It is the contract between you and the user of your control. It is less true for the skin of the control, because skins are “implementation detail” and people modifying skins know that they are interfering with the inner workings of the control. You still want to make it easy for other developers to modify the “appearance” of the control.

New Concept?

Protecting your controls this way is not a new concept but it wasn’t used very much in Swing. The case for using “final” is stronger now because JavaFX controls are much more observable than Swing controls. They are exposing their state via properties and observable collections. This way applications can react to state changes by “listening” to the control instead of plugging themself into the control by overriding its methods. Another reason is the clean separation into “control” and “skin” in JavaFX. Swing components often had “skin” aspects right in the component itself and not in the UI delegate (e.g. paintComponent()).