This chapter covers each WidgetProcessor in detail. For an explanation of how WidgetProcessors fit into the overall architecture of Metawidget, see Chapter 2, Architecture.
Metawidget supports multiple WidgetProcessors for each desktop framework, targeting specific features within each environment.
Swing does not include an automatic JComponent to Object binding mechanism, but Metawidget supports third-party alternatives via addWidgetProcessor.
BeansBindingProcessor binds properties using Beans Binding (JSR-295). It supports the various Beans Binding update strategies:
myMetawidget.addWidgetProcessor( new BeansBindingProcessor( new BeansBindingProcessorConfig() .setUpdateStrategy( UpdateStrategy.READ )) );
If set to READ or READ_WRITE (the default is READ_ONCE), the object being inspected must provide PropertyChangeSupport. If set to READ_WRITE, updates to the UI are automatically sync'ed back to the setToInspect, otherwise the client must manually call save:
myMetawidget.getWidgetProcessor( BeansBindingProcessor.class ).save( myMetawidget )
After JComponents have been generated for the initial setToInspect, clients can load values for a new Object into the same UI without a full re-inspection by using rebind:
myMetawidget.getWidgetProcessor( BeansBindingProcessor.class ).rebind( newObject, myMetawidget )
For more details, see Section 9.5.4, “Rebinding”.
Make sure you use the correct version of BeansBinding | |
---|---|
There are unfortunately two versions of BeansBinding 1.2.1 available. The version at http://repo2.maven.org/maven2/net/java/dev/beansbinding/beansbinding/1.2.1 has serious bugs related to PropertyChangeListeners. The version at http://download.java.net/maven/2/org/jdesktop/beansbinding/1.2.1 is the correct one. This issue has been reported here. |
Consider BetterBeansBinding | |
---|---|
BeansBinding 1.2.1 has known performance issues when working with large numbers of widgets. Consider a more recent JSR-295 implementation such as BetterBeansBinding. |
BeanUtilsProcessor binds properties using Apache BeanUtils. It supports arbitrary property styles:
myMetawidget.addWidgetProcessor( new BeanUtilsBindingProcessor( new BeanUtilsBindingProcessorConfig() .setPropertyStyle( new ScalaPropertyStyle() ) );
Updates to the UI can be saved back to the setToInspect by calling save:
myMetawidget.getWidgetProcessor( BeanUtilsBindingProcessor.class ).save( myMetawidget )
After JComponents have been generated for the initial setToInspect, clients can load values for a new Object into the same UI without a full re-inspection by using rebind:
myMetawidget.getWidgetProcessor( BeanUtilsBindingProcessor.class ).rebind( newObject, myMetawidget )
For more details, see Section 9.5.4, “Rebinding”.
Swing supplies javax.swing.Action for binding JButtons to backing objects, and this is typically combined with Java-based reflection to support runtime binding. This is exactly what the default action binding, ReflectionBinding, does.
However, Metawidget makes action bindings pluggable to support other use cases. In particular, use cases where there is no backing object, and instead the JButton should invoke, say, an RPC call. Implement your own pluggable binding by implementing WidgetProcessor:
public class RpcWidgetProcessor implements WidgetBuilder<JComponent, SwingMetawidget> { JComponent processWidget( JComponent widget, String elementName, Map<String, String> attributes, SwingMetawidget metawidget ) { ...decide whether to attach event handler... widget.add( new AbstractAction() { public void actionPerformed( ActionEvent e ) { String actionName = attributes.get( NAME ); ...make RPC using actionName... } } } }
This can be set either in code:
myMetawidget.addWidgetProcessor( new RpcWidgetProcessor() );
Or via metawidget.xml:
<swingMetawidget xmlns="java:org.metawidget.swing"> <widgetProcessors> <array> <rpcWidgetProcessor xmlns="java:com.myapp"/> </array> </widgetProcessors> </swingMetawidget>
DataBindingProcessor binds properties using org.eclipse.core.databinding. Once bound, values can be saved back from the UI by calling save:
myMetawidget.getWidgetProcessor( DataBindingProcessor.class ).save( myMetawidget )
ReflectionBindingProcessor binds Buttons to backing objects using Java-based reflection to support runtime binding.
After JComponents have been generated for the initial setToInspect, clients can load values for a new Object into the same UI without a full re-inspection by using rebind:
myMetawidget.getWidgetProcessor( ReflectionBindingProcessor.class ).rebind( newObject, myMetawidget )
For more details, see Section 9.5.4, “Rebinding”.