Hi!
In my new job I've worked a lot with Swing GUI code. I immediately saw the
strong need for a framework, in order to provide better abstractions, events
and data binding between GUI and the model layer. The framework market for
Swing applications is very close to dead, but I found a decent dead
framework that could be resurrected, named Genesis. After working with it
for a couple of months, I can see very clear similarities with Tapestry on
several concepts:
- POJO controller instrumented by annotations.
- Seamless client event binding.
- Convention over configuration: Model properties are mapped to GUI controls
with the same name
- Automatic type coercion between model and GUI
- Swing code is isolated and simplified, even more so than T5 templates
Enough off topic :)
When working with T5, one of the (very few) things that I found sub-optimal
is the Select component. You have to implement 2 interfaces, and it requires
extra work when dealing with AJAX, which is a very common requirement. In
Genesis, it is done like the example below. Methods that provide content for
Select boxes are annotated with @DataProvider. If a Select is dependent on
some change in the GUI, the data provider method can be annotated with
@CallWhen to refresh the list when some property on the controller changes.
I would really like to see something similar in T5, allowing the developers
to specify a collection and a property, without using the T5 custom models
for Selects. Also, providing AJAX refresh of the content of a Select,
without exposing AJAX plumbing. I'm thinking the opposite of the zone
support introduced, allowing a refresh something else. I would like the
Select to refresh itself on some condition. Please see examples below.
public class MyGuiPanel extends JPanel {
private javax.swing.JComboBox mySelect;
private javax.swing.JComboBox dependsOnMySelect;
}
public class MyGuiPanelController {
private MyDomainObject someProperty;
private MyDomainObject someOtherProperty;
@DataProvider(widgetId="mySelect", property="someProperty")
public List<MyDoimainObject> getProperties() {
return db.getProperties();
}
@CallWhen("genesis.hasChanged('form:someProperty')")
@DataProvider(widgetId="dependsOnMySelect", property="someOtherProperty")
public List<MyDoimainObject> getOtherProperties() {
return db.getProperties();
}
}
Example ideal T5 code for this:
public class MyPage {
@Component(parameters="value=someProperty, list=properties")
private Select mySelect;
@Component(parameters="value=someOtherProperty, list=otherProperties,
listenForChangesTo=someProperty")
private Select mySelect;
}