[Databinding] Binding a string to an EMF enum inside a table viewer [message #906064] |
Fri, 31 August 2012 10:44  |
Eclipse User |
|
|
|
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 09:40   |
Eclipse User |
|
|
|
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.
|
|
|
Re: [Databinding] Binding a string to an EMF enum inside a table viewer [message #907222 is a reply to message #906441] |
Mon, 03 September 2012 11:01  |
Eclipse User |
|
|
|
This is strange as it seems that this is not a common use case (after a lot of searching on the web, I didn't find a lot of information about it). Seems to me like a pretty standard use case...
Anyway, during while searching on the web, I found this link. Apparently the guy has the same problem as me and Thomas replied that support for this was missing (this was in 2009, so 3 years ago). Apparently this has not been yet fixed.
Should I open a bug request for that ?
And for myself, how can I fix the problem so that it works ?
|
|
|
Powered by
FUDForum. Page generated in 0.04053 seconds