有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java只读绑定和使用JGoodies绑定的单向转换器

我正在尝试使用JGoodies Binding 2.9.1将JTextFieldenabled属性绑定到enum属性。我希望这是一个单向操作:当属性更改时,我希望启用或禁用JTextField,但我永远不希望以另一种方式根据enabled值设置enum属性

尽管我认为我已经正确地设置了一切,但我得到了一个属性访问异常:未能设置一个经过调整的JavaBean属性

我的模型是一个带有属性更改事件的标准Java Bean:

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

在我看来,我有一个单向转换器,当绑定值与提供的值匹配时,它将返回true:

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

然后我设置了绑定:

PresentationModel<MyModel> pm = new PresentationModel<MyModel>(model);
Bindings.bind(
    myTextField, "enabled", new ConverterValueModel(
        pm.getModel(MyModel.MY_PROPERTY),
        new EnumMatchToEnabledConverter(MyEnum.MyValue)));

令我惊讶的是,EnumMatchToEnabledConvertersourceValue()方法被调用,因为它引发了一个UnsupportedOperationException,我从绑定中得到了一个PropertyAccessException

我还试图明确地告诉绑定不要使用setter,但我仍然得到了相同的行为:

Bindings.bind(
    myTextField, "enabled", new ConverterValueModel(
        pm.getModel(MyModel.MY_PROPERTY, "getMyProperty", null), // null setter!
        new EnumMatchToEnabledConverter(MyEnum.MyValue)));

我哪里做错了


共 (1) 个答案

  1. # 1 楼答案

    我找到了解决办法。这很难看,但很管用

    我用一个BufferedValueModel来包装我的ConverterValueModel,它的ValueModel触发器从不触发

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