Как привязать индексированное свойство к jface viewer
Я хочу привязать индексированное свойство к JFace ComboViewer.
Допустим, у меня есть класс DataModel, как это:
class DataModel {
private String[] props = {"A","B","C"};
private PropertyChangeSupport pcs = new PropertyChangeSupport(this);
public String getProperties( int idx ){
return props[idx];
}
public void setProperties( int idx, String value ){
String oldVal = props[idx];
props[idx] = value;
pcs.fireIndexedPropertyChange( "properties", idx, oldVal, value );
}
// code to add/remove PropertyChangeListener
// ...
}
Код привязки данных для простого свойства будет выглядеть так:
DataModel dataModel = ...
ComboViewer propertyChoice = ...
DataBindingContext ctx = new DataBindingContext();
IObservableValue target = ViewerProperties.singleSelection().observe( propertyChoice );
IObservableValue model = BeanProperties.value( DataModel.class, "properties" ).observe(dataModel);
ctx.bindValue( target, model );
но с индексированным свойством я должен сообщить ctx, для какого индекса это значение, которое я хочу связать. я пытался
IObservableValue model = BeanProperties.value( DataModel.class, "properties[0]" ).observe(dataModel);
но это не работает
Возможно ли привязать индексированное свойство вместо простого свойства? Как?
1 ответ
К сожалению, это, кажется, не поддерживается. Я искал точно такую же функциональность. В BeanProperties нет документации, подтверждающей, что она поддерживается.
Анализируя реализацию BeanProperties.value, вы обнаруживаете, что он делегирует BeanPropertyHelper для чтения и записи свойства. Метод Object readProperty(Object source, PropertyDescriptor propertyDescriptor)
не знает о подклассе IndexedPropertyDescriptor. Когда он вызывается для индексированного свойства, readProperty пытается использовать метод read, который читает весь массив. Я думаю, что этот метод является необязательным для индексированных свойств. Для индексированных свойств следует использовать IndexedPropertyDescriptor.getIndexedReadMethod().
В зависимости от вашего варианта использования вы можете обойти проблему, используя BeanProperties.list. Однако вы не можете использовать это в сочетании с индексированными свойствами. Я попытался это, добавив метод, который возвращает весь массив, но при этом сохраняя метод, который делает "fireIndexedPropertyChange". К сожалению, это дает ClassCastException: Eclipse's BeanListProperty, кажется, предполагает, что значение в событии изменения является массивом или списком. Однако для индексированного свойства это единственный элемент массива.
Или, возможно, вместо этого вы можете использовать наблюдаемую карту?