Remarks: I am basically building a utility which can bind a TableViewer to a list of model entities of one type in just a few lines with complete label and editing support. Each property of the entity corresponds to a column in the table and the correct label and editor for a column should be automatically determined by inspecting the class of the property.
This strategy could be made pluggable with convention-over-configuration, i.e. java.util.Date gets a rendere that shows only the date part and an editor which is date picker without time, but it can be overriden to show a time and use a picker for only the time part.
For relations to other entities a celleditor should show a combobox and use a pluggable strategy for populating them.
This seems like an extremely (!) common usecase which can save loads of time for writing the code to create tables. Before I reinvent the wheel, does there already exist such a utility which I can download somewhere?
My specific question:
I can already bind numerical values and Strings by using ObservableValueEditingSupport from Snippet032TableViewerColumnEditing.
I am stuck getting ObservableValueEditingSupport to work with other CellEditors than the TextCellEditor, specifically the ComboBoxViewerCellEditor.
From Snippet032TableViewerColumnEditing (and the bug report) I know I can bind a model property to a column with the TextCellEditor in this way:
...
IValueProperty cellEditorControlText = CellEditorProperties
.control().value(WidgetProperties.text(SWT.Modify));
columnName.setEditingSupport(ObservableValueEditingSupport.create(
tableViewer, bindingContext,
new TextCellEditor(table), cellEditorControlText,
propertyName));
...
My model class for the table row has a property of my own type whose value I would like to bind to a combo box of possible values. So I tried to use the ComboBoxViewerCellEditor which I populated with a few values of the same type as the property.
So I replaced the TextCellEditor by a ComboBoxViewerCellEditor. The binding should be to the single selection in the ComboViewer that is embedded in the ComboBoxViewerCellEditor. My first attempt was to replace cellEditorControlText by
CellEditorProperties
.control().value(WidgetProperties.selection())
The combo box editor does show, but after selecting an item I get an "argument type mismatch" exception. I figured that I should really bind to the single selection of the "viewer" property inside the ComboBoxViewerCellEditor, so I replaced the above by
IValueProperty valueProperty = BeanProperties.value("viewer")
.value(ViewerProperties.singleSelection());
This DOES correctly write the selected object to the property of my model, but every time I select something I get the following exception:
java.lang.NoSuchMethodException: org.eclipse.jface.viewers.ComboBoxViewerCellEditor.addPropertyChangeListener(java.beans.PropertyChangeListener)
at java.lang.Class.getMethod(Class.java:1605)
at org.eclipse.core.internal.databinding.beans.BeanPropertyListenerSupport.processListener(BeanPropertyListenerSupport.java:96)
at org.eclipse.core.internal.databinding.beans.BeanPropertyListenerSupport.hookListener(BeanPropertyListenerSupport.java:44)
at org.eclipse.core.internal.databinding.beans.BeanPropertyListener.doAddTo(BeanPropertyListener.java:56)
at org.eclipse.core.databinding.property.NativePropertyListener.addTo(NativePropertyListener.java:41)
at org.eclipse.core.internal.databinding.property.value.SimplePropertyObservableValue$3.run(SimplePropertyObservableValue.java:83)
at org.eclipse.core.databinding.observable.Realm$1.run(Realm.java:148)
at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42)
at org.eclipse.core.databinding.observable.Realm.safeRun(Realm.java:152)
at org.eclipse.core.databinding.observable.Realm.exec(Realm.java:170)
at org.eclipse.core.internal.databinding.property.value.SimplePropertyObservableValue.firstListenerAdded(SimplePropertyObservableValue.java:78)
at org.eclipse.core.databinding.observable.ChangeManager.addListener(ChangeManager.java:70)
at org.eclipse.core.databinding.observable.value.AbstractObservableValue.addValueChangeListener(AbstractObservableValue.java:46)
at org.eclipse.core.databinding.observable.value.DecoratingObservableValue.firstListenerAdded(DecoratingObservableValue.java:71)
at org.eclipse.core.databinding.observable.ChangeManager.addListener(ChangeManager.java:70)
at org.eclipse.core.databinding.observable.value.DecoratingObservableValue.addValueChangeListener(DecoratingObservableValue.java:44)
at org.eclipse.core.databinding.observable.value.DecoratingObservableValue.firstListenerAdded(DecoratingObservableValue.java:71)
at org.eclipse.core.databinding.observable.ChangeManager.addListener(ChangeManager.java:70)
at org.eclipse.core.databinding.observable.value.DecoratingObservableValue.addValueChangeListener(DecoratingObservableValue.java:44)
at org.eclipse.core.internal.databinding.observable.masterdetail.DetailObservableValue.<init>(DetailObservableValue.java:81)
at org.eclipse.core.databinding.observable.masterdetail.MasterDetailObservables.detailValue(MasterDetailObservables.java:52)
at org.eclipse.core.databinding.property.value.ValueProperty.observeDetail(ValueProperty.java:55)
at org.eclipse.core.internal.databinding.property.ValuePropertyDetailValue.observe(ValuePropertyDetailValue.java:57)
at org.eclipse.core.databinding.property.value.ValueProperty.observe(ValueProperty.java:35)
at org.eclipse.jface.databinding.viewers.ObservableValueEditingSupport$1.doCreateCellEditorObservable(ObservableValueEditingSupport.java:64)
at org.eclipse.jface.databinding.viewers.ObservableValueEditingSupport.initializeCellEditorValue(ObservableValueEditingSupport.java:150)
at org.eclipse.jface.viewers.ColumnViewerEditor.activateCellEditor(ColumnViewerEditor.java:194)
at org.eclipse.jface.viewers.ColumnViewerEditor.handleEditorActivationEvent(ColumnViewerEditor.java:444)
at org.eclipse.jface.viewers.ColumnViewer.triggerEditorActivationEvent(ColumnViewer.java:680)
at org.eclipse.jface.viewers.ColumnViewer.handleMouseDown(ColumnViewer.java:664)
at org.eclipse.jface.viewers.ColumnViewer.access$0(ColumnViewer.java:660)
at org.eclipse.jface.viewers.ColumnViewer$1.mouseDown(ColumnViewer.java:89)
at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:179)
at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1003)
at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:3880)
at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3473)
at nl.hm.ilja.core.databinding.ManualTestColumnViewerSupport$1.run(ManualTestColumnViewerSupport.java:143)
at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
at nl.hm.ilja.core.databinding.ManualTestColumnViewerSupport.main(ManualTestColumnViewerSupport.java:134)
And the same Exception with removePropertyChangeListener.
I also tried using a CheckboxCellEditor with
CellEditorProperties
.control().value(WidgetProperties.selection());
and this doesn't seem to have any effect when I click the cell which is bound to a boolean property.