Как привязать индексированное свойство к 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, кажется, предполагает, что значение в событии изменения является массивом или списком. Однако для индексированного свойства это единственный элемент массива.

Или, возможно, вместо этого вы можете использовать наблюдаемую карту?

Другие вопросы по тегам