Thanks Ollie and pdbruycker,

Originally Posted by
oliverhutchison
You need to create a subclass of CustomNumberEditor
Code:
class MyIntEditor extends CustomNumberEditor {
public MyIntEditor() {
super(Integer.class, true);
}
}
and then register that class with the PropertyEditorRegistry.
I did try the above PropertyEditorRegistry technique yesterday before I even posted my previous message. But for some reason it didn't work. My editor registered correctly without throwing exceptions but when I tried to call setFormObject() on my Form I got a ClassCastException when the framework tried to set the value of an Integer property into a JTextField that is on the Form:
Code:
java.lang.ClassCastException
at org.springframework.richclient.forms.AsYouTypeTextValueSetter.setComponentValue(AsYouTypeTextValueSetter.java:50)
at org.springframework.richclient.forms.AbstractValueSetter.valueChanged(AbstractValueSetter.java:63)
at org.springframework.binding.value.support.AbstractValueModel.fireValueChanged(AbstractValueModel.java:71)
at org.springframework.binding.value.support.BufferedValueModel.onWrappedValueChanged(BufferedValueModel.java:82)
at org.springframework.binding.value.support.BufferedValueModel$WrappedModelValueChangeHandler.valueChanged(BufferedValueModel.java:70)
at org.springframework.binding.value.support.AbstractValueModel.fireValueChanged(AbstractValueModel.java:71)
at org.springframework.binding.value.support.PropertyAdapter$DomainObjectChangeHandler.valueChanged(PropertyAdapter.java:70)
at org.springframework.binding.value.support.AbstractValueModel.fireValueChanged(AbstractValueModel.java:71)
at org.springframework.binding.value.support.ValueHolder.setValue(ValueHolder.java:52)
at org.springframework.binding.form.support.AbstractFormModel.setFormObject(AbstractFormModel.java:76)
at org.springframework.richclient.forms.SwingFormModel.setFormObject(SwingFormModel.java:269)
at org.springframework.richclient.forms.AbstractForm.setFormObject(AbstractForm.java:454)
at com.cbconstantini.spring.locationapp.ui.LocationView$2.getSelectedObjectName(LocationView.java:236)
at org.springframework.richclient.progress.TreeStatusBarUpdater.onSingleSelection(TreeStatusBarUpdater.java:36)
at org.springframework.richclient.tree.TreeSelectionListenerSupport.valueChanged(TreeSelectionListenerSupport.java:49)
at javax.swing.JTree.fireValueChanged(JTree.java:2406)
at javax.swing.JTree$TreeSelectionRedirector.valueChanged(JTree.java:2777)
at javax.swing.tree.DefaultTreeSelectionModel.fireValueChanged(DefaultTreeSelectionModel.java:629)
at javax.swing.tree.DefaultTreeSelectionModel.notifyPathChange(DefaultTreeSelectionModel.java:1076)
at javax.swing.tree.DefaultTreeSelectionModel.setSelectionPaths(DefaultTreeSelectionModel.java:287)
at javax.swing.tree.DefaultTreeSelectionModel.setSelectionPath(DefaultTreeSelectionModel.java:170)
at javax.swing.JTree.setSelectionPath(JTree.java:1181)
at javax.swing.plaf.basic.BasicTreeUI.selectPathForEvent(BasicTreeUI.java:2192)
at javax.swing.plaf.basic.BasicTreeUI$MouseHandler.handleSelection(BasicTreeUI.java:2840)
at javax.swing.plaf.basic.BasicTreeUI$MouseHandler.mousePressed(BasicTreeUI.java:2801)
at java.awt.AWTEventMulticaster.mousePressed(AWTEventMulticaster.java:218)
at java.awt.Component.processMouseEvent(Component.java:5131)
at java.awt.Component.processEvent(Component.java:4931)
at java.awt.Container.processEvent(Container.java:1566)
at java.awt.Component.dispatchEventImpl(Component.java:3639)
at java.awt.Container.dispatchEventImpl(Container.java:1623)
at java.awt.Component.dispatchEvent(Component.java:3480)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:3450)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:3162)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:3095)
at java.awt.Container.dispatchEventImpl(Container.java:1609)
at java.awt.Window.dispatchEventImpl(Window.java:1590)
at java.awt.Component.dispatchEvent(Component.java:3480)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:450)
at java.awt.EventDispatchThread.pumpOneEventForHierarchy(EventDispatchThread.java:197)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:144)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:136)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:99)
Note that when I used the other technique (i.e. register a PropertyEditor in the FormModel), setFormObject() worked (i.e. it did NOT throw a ClassCastException) and the Integer field in my domain object was successfully bound to the control on the form. Unfortunately, I would much rather use the PropertyEditorRegistry technique so that I don't have to register my custom integer editor on every single form that is bound to a domain object with an Integer property.
I'll list the relevant code and bean config below to see if you can figure out what is happening. First, the bean config:
Code:
<bean id="propertyEditorRegistry"
class="org.springframework.richclient.application.support.DefaultPropertyEditorRegistry">
<property name="propertyEditors">
<list>
<props>
<prop key="objectClass">java.lang.Integer</prop>
<prop key="propertyEditorClass">com.cbconstantini.spring.beans.propertyeditors.CustomIntegerEditor</prop>
</props>
</list>
</property>
</bean>
Here's the editor:
Code:
package com.cbconstantini.spring.beans.propertyeditors;
import org.springframework.beans.propertyeditors.CustomNumberEditor;
public class CustomIntegerEditor extends CustomNumberEditor
{
public CustomIntegerEditor()
{
super(Integer.class, true);
}
}
Here's the domain object:
Code:
package com.cbconstantini.spring.locationapp.domain;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import org.springframework.beans.support.MutableSortDefinition;
import org.springframework.beans.support.PropertyComparator;
/**
* Simple JavaBean domain object representing a Country.
*/
public class Country extends Entity
{
private String code;
private String name;
private Integer longDistanceCode;
private String phoneNumFmt;
private Set provinces;
public Integer getLongDistanceCode()
{
return longDistanceCode;
}
public void setLongDistanceCode(Integer longDistanceCode)
{
this.longDistanceCode = longDistanceCode;
}
// other code omitted
// ...
}
Here's the Form:
Code:
package com.cbconstantini.spring.locationapp.ui;
// code omitted
// ...
public class CountryForm extends AbstractForm {
public static final String COUNTRY_FORM = "countryForm";
private JComponent name;
public CountryForm(FormModel formModel) {
super(formModel, COUNTRY_FORM);
}
protected JComponent createFormControl() {
FormLayout layout = new FormLayout("left:pref, 5dlu, pref:grow");
BeanFormBuilder formBuilder = new JGoodiesBeanFormBuilder(
getFormModel(), layout);
this.name = formBuilder.add("name")[1];
formBuilder.add("code");
formBuilder.add("longDistanceCode");
formBuilder.add("phoneNumFmt");
return formBuilder.getForm();
}
public boolean requestFocusInWindow() {
return name.requestFocusInWindow();
}
}
Here's the view where I create the Form and call setFormObject():
Code:
public class LocationView extends AbstractView implements ApplicationListener
{
private CountryForm countryForm;
private JTree locationTree;
// code omitted
// ...
private void createCountryForm()
{
SwingFormModel countryFormModel = SwingFormModel.createFormModel(new Country());
// countryFormModel.registerCustomEditor(Integer.class,
// new CustomIntegerEditor());
countryForm = new CountryForm(countryFormModel);
}
// code omitted
// ...
private void createLocationTree()
{
// code omitted
// ...
locationTree.addTreeSelectionListener(new TreeStatusBarUpdater(
getStatusBar())
{
public String getSelectedObjectName()
{
Object obj = getSelectedNode().getUserObject();
if (obj instanceof Country)
{
Country country = (Country) obj;
countryForm.setFormObject(country); // ClassCastException thrown during this call
cardLayout.show(cardPanel, COUNTRY_CARD);
return country.getName();
}
else if
// code omitted
// ...
}
}
Okay, I think that's all of the relevant code. PLEASE NOTE AGAIN, that when I used the other technique (i.e. register a PropertyEditor in the FormModel), setFormObject() WORKED with the above code (with the countryFormModel.registerCustomEditor() call UNcommented and with the "propertyEditorRegistry" bean config commented, of course).
For the moment, I'll assume that I have done something incorrectly but to me it looks like there might be a bug somewhere in the framework that is preventing the PropertyEditorRegistry technique from working correctly. I tried tracing the code the figure out what that bug might be but I got a bit lost in the details.
So, have I done something wrong?