2014-09-04 59 views
0

我嘗試在SWT Widgets上使用DataBinding在Combo上使用DataBinding

我想知道是否有方法將Combo Box連接到模型中的底層String。 因此,我的模型中有String,我的View上有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,反之亦然。

回答

0

我現在有一個乾淨的解決方案,即使用Converter。

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

當然,您可以將轉換器外包給自定義類,我只是爲了在此處顯示快速解決方案而使用它。