:: JGOODIES Looks :: Professional Swing Look&Feels

:: Guide :: Introduction ::

The JGoodies Binding builds adapter chains between the domain layer and the presentation layer and updates both sides: views are updated if domain object properties have been changed, and domain properties are updated if the presentation has been changed.

Related Documentation

You can find a presentation about Binding techniques at the JGoodies Articles page.

Currently the primary documentation are the accompanying tutorial sources. These demonstrate typical uses of the Binding library. It is strongly recommended to browse and study all tutorial example classes.

Martin Fowler is in the process of adding further patterns to his catalog of "Patterns for Enterprise Application Architecture" [P of EAA]. These additions contain the Presentation Model pattern that can significantly improve the architecture and maintainability of your Swing applications.

An overview of the application architecture around this data binding is available at pp. 255 in this Application Guide. There's an introduction to ValueModels, and you may read the Comparison of our approach with MVP.

Domain Layer

The tutorial is built around the Album class. It provides 'aspects' that we want to present in a UI, and a UI may upate the values of these aspects, or we build up a two-way connection between the UI and the aspects and each side can update the other. In other words, the model's aspects are bound to UI components.

The aspects can be read-write, read-only, or write-only; typically they are read-write. In addition such an aspect can be observable, i.e. other objects can observe changes of the aspect's value. There are different approaches to implement aspects.

In the Java world there's a well-received standard that many people work with: the Java Bean standard. Beans provide everything necessary for accessing and observing aspects - here they are called properties. And it's quite easy to follow the Java Bean naming conventions. Basically you provide a pair of getter and setter methods for each property. And typically you fire a PropertyChangeEvent in the setter to notify observers about property changes. The Binding works with other domain object styles, but many convenience classes focus on Beans. Also, if you use Beans, you need no references from your domain classes to the JGoodies Binding library. This makes it easier to change the binding style later.

In the tutorial the Album class extends Model and provides getters and setters for each property, for example #getTitle() and setTitle(String).

From Domain to ValueModel

The PresentationModel class vends adapters that convert the domain Bean properties into the ValueModel interface. For example to access an Album's title we write: new PresentationModel(anAlbum).getModel("title"). We can then read and write the title via the ValueModel methods #getValue/#setValue.

ValueModel

We now can read and write domain aspects using a uniform and very simple API (getValue/setValue) and can observe value changes. We can operate on these values to convert types, to buffer values, to cache values, etc. We can reuse a set of classes for each of these tasks. For example the BufferedValueModel delays value changes until you commit them. Or we can change the value source using a multiplexer, so that we can change the customer instance we're asking for the last name. Think of a JList of albums where you select different albums and a details view shows the title and artist of the current selection in a form with text field.

From ValueModel to Swing Model

To use a ValueModel with a Swing component, we've to convert from the #getValue/#setValue interface to the model interface as required by the component class. For example ValueModels that holds Strings can be converted to the Document interface that is the model for JTextComponent. Or a ValueModel that holds a Boolean can be converted to a ToggleButtonModel for use in a JCheckBox or JRadioButton. All these adapters can replace the Swing convenience model implementations. The Binding library provides prepared adapters to Swing components in package com.jgoodies.binding.adapter.

In some cases we need to set Swing component properties that have no underlying model. For example, the value property of the JFormattedTextField has no model that stores this value. The PropertyConnector class can connect two properties in two beans and synchronizes each property value with the other.

Pros and Cons

This binding approach can be used in many applications - I'd say in about 70 or 80% of all Swing applications. It can significantly save time to bind and buffer domain aspects in a Swing UI. However, the downside is that this approach increases the learning curve that is already quite high in Swing. And so, check carefully whether this binding is appropriate in your project.

Our binding leads to clean code and helps developers understand where to put what code: 1) implement domain aspects in domain Bean classes, 2) build panel classes that consist only of UI components and panel building code, 3) connect these two layers using a chain of adapters or using a middle code layer that holds these adapter so that other views can present the same data.

A true alternative to this binding is to copy values from the domain object to the convenience models of the Swing components and write the values back to the domain if you click on OK. The copying approach is easy to understand and works well if each aspect is presented by a single view. If multiple views present the same value, you may end up with cluttered code.

Anyway, even with the copying approach you can (and should) benefit from the Presentation Model pattern and a 3-tier architecture.

(c) 2007 JGoodies