The View Objects Pattern & automated tests with TestFX

When developing an application you should add automated tests. Oh, sorry – I mean you MUST add automated test. So when developing a JavaFX application there will come the moment when you ask yourself “How should I test this UI? A normal JUnit tests won’t work here…”

TestFX basics

That’s right but the JavaFX community is prepared for this problem by offering TestFX. With TestFX you can create unit tests for JavaFX applications. Let’s imagine you have an application that only contains a login dialog:
login
You can automatically test this dialog by using the TestFX API. I coded test might look like this:

As you can see you can control and fake all user events by using TestFX. At github you can find a general documentation of the API.

Dialog Objects Pattern

Mostly your application will contain more than a simple login dialog and in that case a test could become confusing:

Web developers already know this problem and introduced a pattern to avoid it: PageObject
Since we don’t have pages in JavaFX applications I would call it “View Objects Pattern” instead. By using this pattern you will define a class / object for each view in your application. Let’s image we have a music application with the following workflow:
workflow
The applications contains 4 different views. To write tests for the application we should create a view object for each view. Here is an pseudo code example for the album overview:

You can see some important facts in the code:

  • Each user interaction is defined as a method
  • The class provides methods to check important states
  • Each method returns the view object for the page that is visible after the method has been executed
  • If the view won’t change by calling a method the method will return “this

By doing so it is very easy to write understandable tests. Because all the methods will return a view object you can use it as a fluent API:

How to integrate custom fonts in your JavaFX application by using CSS

This is one of the CSS tips that were part of my “Extreme Guimaker” talk at JavaOne this year and will show how you can change to font for a complete application or only a specific control by using CSS.
Before explaining the CSS solution I want to show a short example in Java code:

In the code the font of a button is set to “Arial” with a size of 24. All basic nodes in JavaFX that contains a text provide a font property that can be simply used to define a new font for the node. I don’t think that this is best practice because the font is an attribute that styles the application and therefore it should be separated from the application code.

Set fonts by CSS

Fortunately JavaFX supports CSS and therefore we can extract the font specification from the Java code and add it to CSS. I won’t discuss how IDs and style classes in CSS work in this post (If you not familiar with CSS you should have a look in my book). The font of a node can be defined by using the -fx-font-* attributes in CSS. You can find a documentation of these attributes here. Here is an example that defines the font for a button:

If you want to define a global font for all controls in your application you can simply set the font to the .text style class. The Text shape in JavaFX contains this pseudo class by default and all nodes that render a text on screen use the Text shape internally. Here is the css rule that will set the font for a complete application:

Adding custom fonts

In the examples “Arial” is used as the custom font. Normally you can assume that this font will be installed on a client system. But sometimes you want to use a custom font to create a unique UI. In the following example I want to use the Roboto font that is the official font of Googles Material Design. Normally this font won’t be installed on a client system. So if you define the font by CSS and a customer will run the application without installing the specific font on the OS JavaFX will select a system font as fallback and the cool UI of the app is broken. But thankfully there is a good solution for this problem. Since Java 8 JavaFX supports the @font-face rule that can be used to add fonts. As a first step the font file must be added to the application. As best practice the file should be added to the resources folder:
font
Once this is done the font can be defined in CSS by using the @font-face rule:

Now the font will be used in our application even if it isn’t installed on the OS:
font-loaded

Enrich your List UI by using the MediaListCell

By default the cells of a ListView will show only a string representation of your data on screen. This is ok for a basic implementation and will work for a lot of use cases. But if you have a application that contains a big list like a news feed or a chat you need a better skin for the cells. For JavaOne I created some JavaFX APIs that contains basic utilities and controls that can be easily integrated in any JavaFX application. The ui-basics module contains some custom list cells that can be used to enrich your JavaFX application. By using this cells we can achieve the following UI change with only a few lines of Java code:
media-cell
The following graphics shows the inheritance of the new cell classes:
ext
The StructuredListCell defines a cell that splits a cell in 3 regions: left, center and right. The center region will grow by default:
cell layout
You can add any content to the cell by calling the following methods:

In addition the cell provides some new CSS attributes to style it:

  • -fx-left-alignment (VPos): Defines the vertical alignment of the left content
  • -fx-center-alignment (VPos): Defines the vertical alignment of the center content
  • -fx-right-alignment (VPos): Defines the vertical alignment of the right content
  • -fx-spacing (number): Defines the spacing between the 3 regions
  • -fx-height-rule (HPos): Defines which region should be used for the height calculation. By default the center content is used. This means that the cell will be as high as the center content.

The MediaListCell extends this cell definition. It sets the center content to a a title and a description label. If you want to use the cell you only need to call setTitle(…) and setDescription(…) to define the center content:
tite-desc
The class provides default style classes for both labels:

  • media-cell-title
  • media-cell-description

In addition the class provides two new CSS properties:

  • -fx-show-description (boolean): Defines if the description label should be visible
  • -fx-text-spacing (number): Defines the spacing between the title and description label

If you want the UI as shown in the demo you should use the SimpleMediaListCell class. This adds a rounded image view as the left content. By using this cell its very easy to create a list view like you know from many modern applications. To make the use of the cell even easier I introduced the Media interface. The SimpleMediaListCell is defined as SimpleMediaListCell and therefore it can only used with data that implements the Media interface. This interface is quite simple as you can see in its source:

The properties of the nodes in the cell are automatically bound to the properties that are provided by the interface and therefore the SimpleMediaListCell class can be used like shown in the following example:

All the cell classes are part of the ui-basics module that can be found at github:

further development

At the moment I plan some new features for the cells. As you might have registered the right region wasn’t used in this example. In most UIs this is used to define a user action or hint like shown in this image:
showroom
I plan to add this as a default feature. In addition I will provide different styles for the image view. Maybe you don’t want a rounded view. In this case it would be perfect to define a style by css. Please ping me if you have some other cool improvements :)

Interview at FX Experience

JavaOne is coming closer and closer. On the one hand I can’t wait to be there but on the other hand I need to finish all my talks in only a few days fearful
At canoo we prepared a short overview of all our talks. If you fare interested in a preview of the canoo talks watch them.
In addition a interview with me about JavaOne and my current work was posted at FX Experience and another overview about my talks can be found at the JavaOne blog.
I think that I won’t have time to add an additional blog post before JavaOne. But at the moment I have several post finished that describes new APIs and tricks that I want to show at JavaOne :) I you can’t be there you should stay tuned and wait for these posts.

Back to all the slides… Here are some previews of my work today (DataFX & Extreme Gui Makeover):
sneak peak
sneak peek 2

JavaOne Preview: Enterprise JavaFX

Today I want to give a short preview of one of my talks at JavaOne: Enterprise JavaFX.
In this talk I will discuss different problems in enterprise development with JavaFX. The talk will introduce some solutions and best practice how to handle background threads, call web services or make use of Java EE specifications like dependency injection. In addition some frameworks will be shown.

If you are in this topics meet me at Java One :)
Venue / Room: Hilton – Plaza A
Date and Time: 9/29/14, 16:00 – 17:00

Because I think a good talk must contain cool demos, I created some examples especially for my talks. Today I will introduce one of them with a short video. The video shows how you can login with Twitter in JavaFX. You can use this as an alternative workflow for users to login or register in your application. If you want to know how this is done you should visit my “Enterprise JavaFX” talk :)

JavaOne 2014 Preview

As I mentioned last week I will give 6 talks at JavaOne this year. To get a better overview of this talks I recorded a short video in that I introduce the talks and show a short preview of some JavaFX demos:

Most of the talks will be hold with other speakers. Here is a list of all the people I’m currently working on cool stuff for JavaOne:

My JavaOne 2014 Sessions

Uh, as a featured speaker I will give a lot sessions this year at JavaOne. This is the main reason why I found no time to blog about JavaFX the last weeks ;)
If you will attend JavaOne I will be happy to see you at one of my session:

Enterprise JavaFX
Venue / Room: Hilton – Plaza A
Date and Time: 9/29/14, 16:00 – 17:00

DataFX: From External Data to a UI Flow and Back
Venue / Room: Hilton – Plaza B
Date and Time: 9/29/14, 11:00 – 12:00

Smart UIs for Mobile and Embedded in JavaFX
Venue / Room: Hilton – Plaza B
Date and Time: 9/30/14, 19:00 – 19:45

The JavaFX Community and Ecosystem
Venue / Room: Hilton – Plaza B
Date and Time: 9/30/14, 11:00 – 12:00

Extreme GUI Makeover
Venue / Room: Hilton – Yosemite B/C
Date and Time: 10/1/14, 13:00 – 14:00

Test-Driven Development with JavaFX
Venue / Room: Hilton – Plaza B
Date and Time: 10/1/14, 11:30 – 12:30

Maybe I can organize some “Mastering JavaFX 8 Controls” books for the audience :)