在组合上使用DataBinding

时间:2014-09-04 07:51:45

标签: java eclipse swt converter

我尝试在SWT Widgets上使用DataBinding

我想知道是否有办法将Combo Box连接到模型中的基础String。 我在模型中有一个String,在我的视图上有Combo吗?

由于标准方式不起作用:

//View
DataBindingContext ctx = new DataBindingContext();
IObservableValue target1 = WidgetProperties.singleSelectionIndex().observe(combo);
IObservableValue model1 = BeanProperties.value(OutputVariable.class, "type").observe(outputVariable);
ctx.bindValue(target1, model1);

//Model
public void setType(String type) {
    //TYPES is a constant with the possible Combo values
    if (contains(TYPES, type)) {
        String oldType = this.type;
        this.type = type;
        firePropertyChange("type", oldType, this.type);
    }else {
        throw new IllegalArgumentException();
    }
}

我尝试使用无法正常工作的fireIndexedPropertyChangeMethod

有没有办法将这两者连接在一起?也许我必须使用其他WidgetPropertiesBeanProperties方法?

作为一种解决方法,我可以在模型中使用一个新属性,它定义组合选择索引,将其连接到Combo并将此索引的更改传递给类型属性,反之亦然。但这对我来说似乎不是一个很好的解决方案。

编辑: 使用selectionIndex属性的解决方案正在运行。但是一个更干净的方法仍然会很好,因为现在模型中的类型属性更改也必须重置selectionIndex,反之亦然。

1 个答案:

答案 0 :(得分:0)

我现在有一个干净的解决方案,即使用转换器。

//View
    IObservableValue comboObservable = WidgetProperties.singleSelectionIndex().observe(combo);
    IObservableValue viewTypeObservable = BeanProperties.value(DebugModel.class, "type").observe(debugModel);

    IConverter viewTypeToIntConverter = createViewTypeToIntConverter();
    UpdateValueStrategy toTargetStrategy = new UpdateValueStrategy();
    toTargetStrategy.setConverter(viewTypeToIntConverter);

    IConverter intToViewTypeConverter = createIntToViewTypeConverter();
    UpdateValueStrategy toModelStrategy = new UpdateValueStrategy();
    toModelStrategy.setConverter(intToViewTypeConverter);

    DataBindingContext context = new DataBindingContext();
    context.bindValue(comboObservable, viewTypeObservable, toModelStrategy, toTargetStrategy);

//Converter
private IConverter createIntToViewTypeConverter() {
    return new IConverter() {

        @Override
        public Object convert(Object value) {
            if(value instanceof Integer) {
                for(ViewType type : ViewType.values()) {
                    if(type.toString().equals(ViewType.getStringAtIndex((int)value))) {
                        return type;
                    }
                }
            }
            throw new IllegalArgumentException("We need an Integer to convert it but got an " + value.getClass());
        }

        @Override
        public Object getFromType() {
            return Integer.class;
        }

        @Override
        public Object getToType() {
            return ViewType.class;
        }

    };
}

private IConverter createViewTypeToIntConverter() {
    return new IConverter() {

        @Override
        public Object convert(Object value) {
            if(value instanceof ViewType) {
                String[] viewTypes = ViewType.getStringValues();
                for(int i=0;i<viewTypes.length;i++) {
                    if(viewTypes[i].equals(((ViewType)value).toString())) {
                        return i;
                    }
                } 
            }
            throw new IllegalArgumentException("We need a View Type to be converted but got a " + value.getClass());
        }

        @Override
        public Object getFromType() {
            return ViewType.class;
        }

        @Override
        public Object getToType() {
            return Integer.class;
        }

    };
}

//Model
public class DebugModel extends ModelObject {
    private ViewType type;
    public ViewType getType() {
         return type;
    }

    public void setType(ViewType type) {
        firePropertyChange("type", this.type, this.type = type);
    }
}

//Just to complete the example, be sure the Model class extends a ModelObject class like this
public class ModelObject {
    private PropertyChangeSupport changeSupport = new PropertyChangeSupport(
        this);

    public void addPropertyChangeListener(PropertyChangeListener listener) {
        changeSupport.addPropertyChangeListener(listener);
    }

    public void removePropertyChangeListener(PropertyChangeListener listener) {
        changeSupport.removePropertyChangeListener(listener);
    }

    public void addPropertyChangeListener(String propertyName,
        PropertyChangeListener listener) {
        changeSupport.addPropertyChangeListener(propertyName, listener);
    }

    public void removePropertyChangeListener(String propertyName,
        PropertyChangeListener listener) {
        changeSupport.removePropertyChangeListener(propertyName, listener);
    }

    protected void firePropertyChange(String propertyName, Object oldValue,
        Object newValue) {
        changeSupport.firePropertyChange(propertyName, oldValue, newValue);
    }

    protected void fireIndexedPropertyChange(String propertyName, int index, Object oldValue, Object newValue) {
        changeSupport.fireIndexedPropertyChange(propertyName, index, oldValue, newValue);
    }
}

当然你可以将转换器外包给自定义类,我这样使用它只是为了在这里展示一个快速的解决方案。