I am attempting to use JGoodies Binding 2.9.1 to bind the enabled
property of a JTextField
to an enum property. I want this to be a one-way operation: when the property changes, I want the JTextField
to become enabled or disabled, but I never want to go the other way and set the enum property based on the enabled
value.
Although I think I set up everything properly, I am getting a PropertyAccessException: Failed to set an adapted Java Bean property.
My model is a standard Java Bean with property change events:
public static String MY_PROPERTY = "myProperty";
private MyEnum myProperty;
public MyEnum getMyProperty() { return myProperty; }
public void setMyProperty(final MyEnum newValue) {
final MyEnum oldValue = myProperty;
if (newValue == oldValue) { return; }
myProperty = newValue;
changeSupport.firePropertyChange(MY_PROPERTY, oldValue, newValue);
}
In my view I have a one-way converter that will return true when the bound value matches the provided value:
private final class EnumMatchToEnabledConverter implements BindingConverter<MyEnum, Boolean> {
private MyEnum match;
public EnumMatchToEnabledConverter (MyEnum match) {
this.match = match;
}
@Override
public Boolean targetValue(MyEnum source) {
return (source == match);
}
@Override
public MyEnum sourceValue(Boolean target) {
// this wouldn't make sense
throw new UnsupportedOperationException();
}
}
Then I set up the binding:
PresentationModel<MyModel> pm = new PresentationModel<MyModel>(model);
Bindings.bind(
myTextField, "enabled", new ConverterValueModel(
pm.getModel(MyModel.MY_PROPERTY),
new EnumMatchToEnabledConverter(MyEnum.MyValue)));
To my surprise, EnumMatchToEnabledConverter
's sourceValue()
method gets called, and because it raises an UnsupportedOperationException
I get a PropertyAccessException
from the binding.
I also tried explicitly telling the binding not to use the setter, but I still got the same behavior:
Bindings.bind(
myTextField, "enabled", new ConverterValueModel(
pm.getModel(MyModel.MY_PROPERTY, "getMyProperty", null), // null setter!
new EnumMatchToEnabledConverter(MyEnum.MyValue)));
Where am I going wrong?
I found a workaround. It's ugly, but it works.
I wrap my ConverterValueModel
with a BufferedValueModel
whose ValueModel
trigger never triggers.
Bindings.bind(
myTextField,
"enabled",
new BufferedValueModel(
new ConverterValueModel(
pm.getModel(MyModel.MY_PROPERTY),
new EnumMatchToEnabledConverter(MyEnum.MyValue)),
new AbstractValueModel() {
@Override public Object getValue() { return null; }
@Override public void setValue(Object o) {}
}));