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; }