:: 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.
|