04 October 2009

Eclipse Forms and Data Binding

Our map compiler Anaconda reads all parameters and settings from a configuration file, which over time has evolved from a simple Java properties file to a not-so-simple XML file which is validated by an XML schema.

To access the configuration at runtime, we use Java XML Bindings generated from our schema by xjc in a straightforward manner, without any fancy customizations.

Using the XML editing support in Eclipse, it is very easy to edit and validate a configuration file, at least from a developer perspective. However, our customers will not be too happy about editing large XML files by hand, so the idea is to develop a form-based configuration editor for our RCP application Anaconda Workbench, similar to the manifest editor of Eclipse PDE or the POM editor of m2eclipse.

These editors are based on Eclipse UI forms, another layer on top of SWT and JFace, which is obviously powerful enough for complex tasks, as demonstrated by the above examples. Less obviously, it is rather poorly documented. The Eclipse online help has just 10 brief pages about UI Forms and the Javadocs which, as usual, are not very useful for getting started.

The Eclipe Rich Client Platform book also has not more than one page on UI Forms and a link to an online article from 2004. On the Eclipse site, there are two more recent articles
Looking for futher tutorials, I came across Marco van Meegen's critical review Eclipse Forms im Härtetest. I decided to make up my own mind, but after implementing a few examples with Eclipse Forms, I largely agree to his criticism: the API forces you to write lots of repetitive code and it is not easy to figure out how to wire up the different classes to do your job.

To alleviate the shortcomings of Eclipse Forms, Marco created yet another layer called RCPForms. So I gave it a try, and I found it a lot easier to use than working with UI Forms directly. I had to use the sources from the Subversion trunk at Sourceforge, the older tagged or released versions do not seem to work with Eclipse 3.5.

Eclipse forms are usually wrapped by a ManagedForm which manages the state of the form parts and the underlying data models.

The form parts and the models can vary independently, and one model can be shared by multiple form parts.

A managed form is dirty, when one of its parts is more recent than the underlying model. Conversely, it is stale, when a change in the underlying model is not yet reflected on the UI.

To handle this form lifecycle, RCPForms expects the model to support PropertyChangeListeners, which again requires you to add some boilerplate code to your model beans. For my example with a JAXB model, I managed to tweak xjc to generate the required listeners, which is to be discussed in detail in a separate article.

Here is a screenshot of a simple example:


The warnings result from validators on missing mandatory fields.

8 comments:

lonewolf said...

Why don't you consider Gecko? Too far away from OSGi / RCP world, I guess?

Harald Wellmann said...

Yes, exactly. And pnut drives me nuts.

Sergei said...

I see your point, it makes sense not to mix flies with cutlets. However, a product is not only a set of technologies behind it. Gecko is known to your customers, it is well-documented, the work instructions are developed for your employees on how to create forms, merge data, etc. It takes care of non-trivial use-cases, such as how to paste the data from the last-year form into this-year one (i.e. some configuration switches have been changed since that, some - removed, etc.) Better think twice :)
Happy Holiday Season, Merry Christmas and Happy New Year!

remsy said...

"To handle this form lifecycle, RCPForms expects the model to support PropertyChangeListeners"

The design of RCP Forms does not make any assumptions about the datamodel. To support different types of models it uses the concept of model adapters (see the already implemented BeanAdapter and EMFAdapter).
I hacked a small sample for showing the support for pojo data models (without any PropertyChangeListener). You'll find the sample ("net.sf.rcpforms.pojosample") in the svn trunk.
If you want to use datamodels which do not fire change events you may have to do your own implementation of an Editor part for tracking dirty states, update targets manually if model changes or implement your own table refresh mechanism for table editing support.
If you implement PropertyChangeListener support in your models you get all this stuff for free.

Btw: since RCP Forms 1.1 there is support for Eclipse 3.5.1.

mstahlberg said...

Interesting post!

Did you write that article how to tweak xjc to generate the required listeners?

mstahlberg said...

"I managed to tweak xjc to generate the required listeners, which is to be discussed in detail in a separate article."

I'm curious about how you tweaked xjc to generate the listeners. Did you write that article?

Harald Wellmann said...

@mstahlberg: Not yet, but if you're interested, I'll dig out my solution and write it up...

mstahlberg said...

Yes that would be nice, I'm still interested. Sorry for the double posting. I didn't remeber that I already posted the same question.