Visualizing REST XML Data in JavaFX controls

http://sertik.net/blog/js/shCore.js
http://sertik.net/blog/js/shBrushJava.js
http://sertik.net/blog/js/shBrushXml.js

$(document).ready(function() {
SyntaxHighlighter.config.bloggerMode = true;
SyntaxHighlighter.config.clipboardSwf =
http://sertik.net/blog/swf/clipboard.swf’;
SyntaxHighlighter.all();
});

I’m currently working on a number of projects that use JavaFX. One of the
characteristics all those projects share, is the requirement to be able
to communicate with an enterprise backend.
That justifies the work I spend on RedFX and DataFX, two JavaFX libraries
that deal with retrieving, rendering and synchronizing data.

The focus of RedFX is the communication
between JavaFX Clients and Java EE servers. RedFX allows clients to share
data with each other and with backend modules. The original code was based
on JavaFX 1.3.1 and has been ported to JavaFX 2.0. A number of brave
beta-testers are now working with the new code, and a public release will
be available soon.

The DataFX project enables
client developers to populate JavaFX controls with data coming from different
sources, and to visualize this data in a convenient way without the need
of writing lots of boilerplate code.

In this blog entry, I will quickly show how you can use the DataFX library
to retrieve and visualize XML data obtained via a REST call.


Today, many enterprise projects make their data available via REST calls.
The result of a REST call is often an XML document, containing lots of
information. Not all this information is relevant to the particular
JavaFX project. Retrieving the relevant parts and populating a TableView
with this information can become rather cumbersome.

For this reason, the DataFX project contains the
XMLDataSource class. Using this class, developers can populate
a TableView with the parts in the XML that they want, without having to
parse the XML manually.

I’m using the XMLDataSource class myself in the Uitpas
project that LodgON and
ACA-IT Solutions are building
for Cultuurnet Vlaanderen.
The project contains a backend that (amongst other things) can be queried
to obtain information about cultural events. The JavaFX frontend should show
the events that are relevant to a given location, and operators should
get a list-view of these events.
Somewhat simplified, the XML that is returned from a back-end call looks
like this:


<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<CultureEvents xmlns:ns2="http://www.cultuurdatabank.com/XMLSchema/CdbXSD/3.1/FINAL">
<event>
<cdbid>77f811ca-ac5d-40a4-9d73-80335b6288cd</cdbid>
<discountPrice>5.0</discountPrice>
<id>1</id>
<item title="Biljarten" cdbid="77f811ca-ac5d-40a4-9d73-80335b6288cd"/>
<normalPrice>20.0</normalPrice>
<promotion>false</promotion>
</event>
<event>
...
</event>
<event>
...
</event>
</CultureEvents>


The non-relevant parts are already omitted from this example.

In the TableView, we want to show the name of the events (in the first event, this is “Biljarten”, the normal price (5 EUR) and the discounted price (20 EUR).

The following code will achieve this:

    NetworkSource ns = new NetworkSource("http://192.168.130.115:8080/uitpas/rest/uitpas/cultureevent?from=2011-11-01&to=2011-11-15");
    XMLDataSource dataSource = new XMLDataSource(ns,"event","item/@title","normalPrice", "discountPrice");
    TableView tv = new TableView();
    tv.setItems(dataSource);
    tv.getColumns().setAll(dataSource.getColumns());

Rendering the TableView will show a table with 3 columns: the title, the normal price and the discounted price. Each event will be on a single row in the table.

The XMLDataSource constructor used in this example takes a number of arguments:

  • a DataSourceReader. In this case, this is the URL of a REST endpoint.
    For my local development, however, I store the returned XML in a local file
    and I use a FileSource instead of a NetworkSource.

  • the tagname that separates the different “rows” we want to visualize. In
    this case, we want one row for one “event”

  • a number of columns we want to show. The XMLDataSource accepts xpath
    expressions, and can render both XML elements (e.g. the normalPrice) as
    well as attributes (e.g. the “title” attribute on the “item” element)

The DataFX project contains another very useful part: convenient
CellFactories. The Currency CellFactory can be used to render the normal price
and the discount price.

I want to stress that there are a number of ways for having interactions
between desktop clients and remote backends. There is no single solutions
to all problems. Developers should be aware of this. I am convinced that
both DataFX and RedFX can contribute to faster development of enterprise
JavaFX applications, but we want to hear from developers what they think
is missing, or why we should support different patterns.