Allow for custom data binding of DataObjects in a Swing UI
----------------------------------------------------------
Key: TUSCANY-1527
URL: https://issues.apache.org/jira/browse/TUSCANY-1527
Project: Tuscany
Issue Type: New Feature
Reporter: bert.robben
We're developing 3-tier applications with a swing client, JBoss app server and
a couple of databases in the back-end. On the client side we use sdo objects as
model objects for our UI. As such, we need a mechanism for binding our objects
to the UI controls such that changes in the objects are reflected in the UI and
vice versa.
At the moment, there is no real standard for data binding and many different
implementations exist. As such, it would not be a good idea to build support
for this directly into the sdo core. Ideally, the sdo core would allow
implementations supporting data binding to be added as extensions [an extension
as in jar, module, bundle, component, ...]. This is a request for supporting
this in Tuscany SDO.
-----------------
For our applications, we developed our own implementation of the sdo
specification. This implementation is designed to support that kind of
extensions. In the rest of this description, I'd like to show more details on
our implementation to make this more clear and to serve as food for a possible
discussion.
Our sdo core module defines the abstract class AbstractPartialDataObject
implementing DataObject. This class (together with its superclasses) implements
the majority of the bevahiour of DataObject. This includes bi-directional
property updates, type-safe properties, containment, ... It doesn't implement
however the basic access to property values.
Here's a code fragment.
public abstract class AbstractPartialDataObject extends AbstractDataObject
implements PartialDataObject {
protected abstract Object basicGet(Property property);
protected abstract void basicSet(Property property, Object value);
public Object get(Property property) { ... }
public void set(Property property, Object value) { ... }
...
}
The sdo core module also provides a non-abstract class DataObjectImplementation
that provides a simple implementation of this abstract behaviour where the
property values are stored in an ArrayList.
On top of that we defined an extension that deals with our UI requirements. Our
UI is based on a proprietary UI framework. This framework has the following
requirements:
- single valued properties should be exposed as XObservables. An XObservable is
a kind of ValueModel that provides access to a value (get/set) and also allows
for registration of change listeners
- multi valued properties should be exposed as ListModel instances. A ListModel
is a proprietary class (a bit similar to the javax.swing.ListModel) that
provides List functionality and also allows for change listeners
- the data object itself should allow registration of attribute change
listeners that are notified each time a property changes
The extension implements these requirements by providing an appropriate
subclass ObservableDataObject of AbstractPartialDataObject. The only other
pieces of code needed in the extension is an appropriate implementation of
DataFactory and a wrapper to deal with the differences between ListModel and
List.
Here's the class with the most important code snippets.
public class ObservableDataObject extends CompositePartialDataObject implements
{
private XObservable[] properties;
protected ObservableDataObject(com.agfa.hap.sdo.Type type) {
super(type);
this.properties = new XObservable[type.getProperties().size()];
for (int i = 0; i < properties.length; i++) {
initializeProperty(type.getProperty(i));
}
}
private XObservable<Object> initializeProperty(Property prop) {
XObservable<Object> observable =
XObservableFactory.create(prop.getType().getInstanceClass(), this);
if (prop.isMany()) {
observable.init(new DataObjectListModel(this, prop));
}
properties[prop.getIndex()] = observable;
return observable;
}
public XObservable getObservable(commonj.sdo.Property property) {
XObservable result = properties[property.getIndex()];
return result;
}
public ListModel getListModel(Property property) {
return (ListModel) getObservable(property).get();
}
public ListModel getListModel(String property) {
return (ListModel) getObservable(type.getProperty(property)).get();
}
@Override
public List getList(Property property) {
return ((DataObjectListModel) getObservable(property).get()).asList();
}
@Override
protected Object basicGet(Property property) {
Object result = properties[property.getIndex()].get();
if (property.isMany()) {
result = ((DataObjectListModel) result).asList();
}
return result;
}
@Override
protected void basicSet(Property property, Object value) {
XObservable observable =
properties[property.getIndex()];
if (observable == UNINITIALIZED) {
observable = initializeProperty(property);
}
observable.set(value);
}
}
--
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]