我尝试在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。
有没有办法将这两者连接在一起?也许我必须使用其他WidgetProperties或BeanProperties方法?
作为一种解决方法,我可以在模型中使用一个新属性,它定义组合选择索引,将其连接到Combo并将此索引的更改传递给类型属性,反之亦然。但这对我来说似乎不是一个很好的解决方案。
编辑: 使用selectionIndex属性的解决方案正在运行。但是一个更干净的方法仍然会很好,因为现在模型中的类型属性更改也必须重置selectionIndex,反之亦然。
答案 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);
}
}
当然你可以将转换器外包给自定义类,我这样使用它只是为了在这里展示一个快速的解决方案。