[Databinding] Binding a string to an EMF enum inside a table viewer [message #906064] |
Fri, 31 August 2012 14:44 |
Cedric Moonen Messages: 274 Registered: August 2009 |
Senior Member |
|
|
Hello,
I'm having a rather complex situation: I have an EMF model for which one of the element contains a list of "Views" which is made of a string attribute and of a enum type. So in pseudo-code:
class View {
String parameter;
ViewType type; // With ViewType being an enumeration.
}
Now, in my UI, I have a table viewer which is supposed to list all those views, and the table has 2 columns: one for the type and one for the parameter.
I'm trying to use databinding to bind this table to my EMF model and I was able to do so correclty except that this table has to be edited as well, and there comes my problem. In the table, the cell editor for my type has to be a drop down selection of available view types.
I am able to create an ObservableValueEditingSupport which works fine for the parameter property (since it has to convert a String to an EString which works fine) but I can't have a working ObservableValueEditingSupport for my view type column.
Here is my code to create the column viewers:
IObservableSet set = contentProvider.getKnownElements();
IValueProperty typeProperty = EMFEditProperties
.value(editingDomain,
StatementuiextensionPackage.Literals.STATEMENT_VIEW_DEFINITION__TYPE);
TableViewerColumn column = new TableViewerColumn(viewer, SWT.NONE);
column.getColumn().setText("Type");
column.getColumn().setWidth(100);
column.getColumn().setResizable(true);
column.setLabelProvider(new ObservableMapCellLabelProvider(typeProperty
.observeDetail(set)));
// Make column editable
String[] types = new String[ViewType.values().length];
int index = 0;
for (ViewType type : ViewType.values()) {
types[index] = type.getLiteral();
index++;
}
CellEditor editor = new ComboBoxCellEditor(
((TableViewer) viewer).getTable(), types, SWT.DROP_DOWN
| SWT.READ_ONLY);
column.setEditingSupport(EMFObservableValueEditingSupport.create(
viewer,
context,
editor,
CellEditorProperties.control().value(
WidgetProperties.selection()), typeProperty));
IValueProperty parametersroperty = EMFEditProperties
.value(editingDomain,
StatementuiextensionPackage.Literals.STATEMENT_VIEW_DEFINITION__PARAMETERS);
column = new TableViewerColumn(viewer, SWT.NONE);
column.getColumn().setText("Parameters");
column.getColumn().setWidth(200);
column.getColumn().setResizable(true);
column.setLabelProvider(new ObservableMapCellLabelProvider(
parametersroperty.observeDetail(set)));
// make column editable
column.setEditingSupport(ObservableValueEditingSupport.create(
viewer,
context, // EMFDataBindingContext
new TextCellEditor(viewer.getTable()), CellEditorProperties
.control().value(WidgetProperties.text(SWT.Modify)),
parametersroperty));
I already searched on the web for a solution and found this link: http://www.eclipse.org/forums/index.php/m/756876/#msg_756876 which I followed since I use a EMFObservableValueEditingSupport for my first column.
But still, the conversion doesn't happen. I tried to debug but this is really very complex but I narrowed the problem to the fact that the conversion does not occur because the constructor of a WidgetSelectionProperty uses the default constructor of DelegatingValueProperty (and thus doesn't pass any type). It means that a converter cannot be created.
This problem doesn't not occur when you use a WidgetProperties.text(...) observer.
I have no clue how to solve this problem. Does anybody have a clue about what I should do ?
Thanks
|
|
|
Re: [Databinding] Binding a string to an EMF enum inside a table viewer [message #906441 is a reply to message #906064] |
Sat, 01 September 2012 13:40 |
Cedric Moonen Messages: 274 Registered: August 2009 |
Senior Member |
|
|
I realized that there is also a ComboBoxViewerCellEditor which exists and which is more adapted to my case since the selection is a real element and not just a string (and thus no conversion is needed).
So, I updated my code to this thinking that it would solve the problem:
IObservableSet set = contentProvider.getKnownElements();
IValueProperty typeProperty = EMFEditProperties
.value(editingDomain,
StatementuiextensionPackage.Literals.STATEMENT_VIEW_DEFINITION__TYPE);
TableViewerColumn column = new TableViewerColumn(viewer, SWT.NONE);
column.getColumn().setText("Type");
column.getColumn().setWidth(100);
column.getColumn().setResizable(true);
column.setLabelProvider(new ObservableMapCellLabelProvider(typeProperty
.observeDetail(set)));
ComboBoxViewerCellEditor editor = new ComboBoxViewerCellEditor(
((TableViewer) viewer).getTable(), SWT.DROP_DOWN
| SWT.READ_ONLY);
editor.setContentProvider(new ArrayContentProvider());
editor.setLabelProvider(new LabelProvider() {
@Override
public String getText(Object element) {
if (element instanceof ViewType) {
return ((ViewType) element).getLiteral();
}
return super.getText(element);
}
});
editor.setInput(ViewType.values());
EditingSupport editingSupport = ObservableValueEditingSupport.create(
viewer,
context,
editor,
CellEditorProperties.control().value(
ViewerProperties.singleSelection()), typeProperty);
column.setEditingSupport(editingSupport);
Unfortunately it doesn't: an class cast exception is thrown when the combo box selection is validated.
Here is the full stack trace:
java.lang.ClassCastException: org.eclipse.swt.custom.CCombo cannot be cast to org.eclipse.jface.viewers.ISelectionProvider
at org.eclipse.jface.internal.databinding.viewers.SelectionChangedListener.doRemoveFrom(SelectionChangedListener.java:52)
at org.eclipse.core.databinding.property.NativePropertyListener.removeFrom(NativePropertyListener.java:48)
at org.eclipse.core.internal.databinding.property.value.SimplePropertyObservableValue.lastListenerRemoved(SimplePropertyObservableValue.java:91)
at org.eclipse.core.databinding.observable.ChangeManager.removeListener(ChangeManager.java:86)
at org.eclipse.core.databinding.observable.value.AbstractObservableValue.removeValueChangeListener(AbstractObservableValue.java:50)
at org.eclipse.core.internal.databinding.observable.masterdetail.DetailObservableValue.dispose(DetailObservableValue.java:163)
at org.eclipse.core.internal.databinding.observable.masterdetail.DetailObservableValue$3.handleDispose(DetailObservableValue.java:72)
at org.eclipse.core.databinding.observable.DisposeEvent.dispatch(DisposeEvent.java:38)
at org.eclipse.core.databinding.observable.ChangeManager.fireEvent(ChangeManager.java:119)
at org.eclipse.core.databinding.observable.AbstractObservable.dispose(AbstractObservable.java:86)
at org.eclipse.core.internal.databinding.property.value.SimplePropertyObservableValue.dispose(SimplePropertyObservableValue.java:151)
at org.eclipse.core.internal.databinding.property.PropertyObservableUtil$1.handleDispose(PropertyObservableUtil.java:37)
at org.eclipse.core.databinding.observable.DisposeEvent.dispatch(DisposeEvent.java:38)
at org.eclipse.core.databinding.observable.ChangeManager.fireEvent(ChangeManager.java:119)
at org.eclipse.core.databinding.observable.AbstractObservable.dispose(AbstractObservable.java:86)
at org.eclipse.core.internal.databinding.observable.masterdetail.DetailObservableValue.dispose(DetailObservableValue.java:157)
at org.eclipse.jface.databinding.viewers.ObservableValueEditingSupport$EditingState.dispose(ObservableValueEditingSupport.java:271)
at org.eclipse.jface.databinding.viewers.ObservableValueEditingSupport$ColumnViewerEditorActivationListenerHelper.afterEditorDeactivated(ObservableValueEditingSupport.java:234)
at org.eclipse.jface.viewers.ColumnViewerEditor.applyEditorValue(ColumnViewerEditor.java:341)
at org.eclipse.jface.viewers.ColumnViewerEditor$2.applyEditorValue(ColumnViewerEditor.java:154)
at org.eclipse.jface.viewers.CellEditor$1.run(CellEditor.java:335)
at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42)
at org.eclipse.ui.internal.JFaceUtil$1.run(JFaceUtil.java:49)
at org.eclipse.jface.util.SafeRunnable.run(SafeRunnable.java:175)
at org.eclipse.jface.viewers.CellEditor.fireApplyEditorValue(CellEditor.java:333)
at org.eclipse.jface.viewers.ComboBoxViewerCellEditor.applyEditorValueAndDeactivate(ComboBoxViewerCellEditor.java:252)
at org.eclipse.jface.viewers.ComboBoxViewerCellEditor$2.widgetDefaultSelected(ComboBoxViewerCellEditor.java:95)
at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:119)
at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1053)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1077)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1062)
at org.eclipse.swt.widgets.Widget.notifyListeners(Widget.java:774)
at org.eclipse.swt.custom.CCombo.textEvent(CCombo.java:1676)
at org.eclipse.swt.custom.CCombo$1.handleEvent(CCombo.java:111)
at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1053)
at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:4165)
at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3754)
at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.java:2696)
at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:2660)
at org.eclipse.ui.internal.Workbench.access$4(Workbench.java:2494)
at org.eclipse.ui.internal.Workbench$7.run(Workbench.java:674)
at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:667)
at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149)
at be.fmtc.logan2.ui.LogAnApplication.start(LogAnApplication.java:33)
at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:344)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:179)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:622)
at org.eclipse.equinox.launcher.Main.basicRun(Main.java:577)
at org.eclipse.equinox.launcher.Main.run(Main.java:1410)
at org.eclipse.equinox.launcher.Main.main(Main.java:1386)
This seems like a bug, since I have the impression that my code is correct. Or did I do something wrong ?
Thanks for the help.
|
|
|
|
Powered by
FUDForum. Page generated in 0.03519 seconds