Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » JFace » [Databinding] Binding a string to an EMF enum inside a table viewer
[Databinding] Binding a string to an EMF enum inside a table viewer [message #906064] Fri, 31 August 2012 10:44 Go to next message
Cedric Moonen is currently offline Cedric Moonen
Messages: 269
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 09:40 Go to previous messageGo to next message
Cedric Moonen is currently offline Cedric Moonen
Messages: 269
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.
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 Go to previous message
Cedric Moonen is currently offline Cedric Moonen
Messages: 269
Registered: August 2009
Senior Member
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 ?
Previous Topic:Customizing content assistant
Next Topic:java.lang.NoClassDefFoundError: Could not initialize class org.eclipse.jface.text.TextSelection
Goto Forum:
  


Current Time: Wed Jul 30 07:06:51 EDT 2014

Powered by FUDForum. Page generated in 0.01754 seconds