This tutorial is an EMF & GMF tutorial. To go fast, it takes the output of the GMF tutorial 7 as an input (in order not to have to build a new ecore model).
It shows how to replace the default EMF editor associated to a property in the properties view by a custom dialog editor.
This tutorial is based on the model built in the seventh GMF tutorial wich is availabale through :
Full code is availabale through :
This tutorial has been built with :
In this tutorial, we will add three java classes to add our custom property editor.
Depending on what you want to do, you have the choice among three plugin management strategies :
In this tutorial we will apply the third strategy with a new dedicated plugin. Feel free to adapt it to your own needs.
School.edit.ui
jfb.examples.gmf.school.ui.provider
META-INF/MANIFEST.MF
fileorg.eclipse.emf.edit.ui
School
Runtime
tab and add the package you've just created in the Exported Packages
list
First we create a new property source provider. The role of this property source provider is only to return a custom PropertySource
in the createPropertySource
method (in our case, the SchoolPropertySource
which is presented in the next paragraph).
package jfb.examples.gmf.school.ui.provider; import org.eclipse.emf.common.notify.AdapterFactory; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.edit.provider.IItemPropertySource; import org.eclipse.ui.views.properties.IPropertySource; import org.eclipse.ui.views.properties.IPropertySourceProvider; public class SchoolPropertySourceProvider implements IPropertySourceProvider { private AdapterFactory adapterFactory; public SchoolPropertySourceProvider(AdapterFactory adapterFactory) { this.adapterFactory = adapterFactory; } @Override public IPropertySource getPropertySource(Object object) { if (object instanceof IPropertySource) { return (IPropertySource) object; } else { IItemPropertySource itemPropertySource = (IItemPropertySource) (object instanceof EObject && ((EObject) object).eClass() == null ? null : adapterFactory.adapt(object, IItemPropertySource.class)); return itemPropertySource != null ? createPropertySource(object, itemPropertySource) : null; } } protected IPropertySource createPropertySource(Object object, IItemPropertySource itemPropertySource) { // Returns the custom property source return new SchoolPropertySource(object, itemPropertySource); } }
Our custom property source simply overrides the default EMF IPropertySource
implementation. The role of this object is to choose whether to create a default EMF property descriptor or to create a custom one. In the createPropertyDescriptor
method, it is possible to take look at the EMF feature associated to the property and then, to choose the appropriate property descriptor.
package jfb.examples.gmf.school.ui.provider; import jfb.examples.gmf.school.SchoolPackage; import org.eclipse.emf.edit.provider.IItemPropertyDescriptor; import org.eclipse.emf.edit.provider.IItemPropertySource; import org.eclipse.emf.edit.ui.provider.PropertySource; import org.eclipse.ui.views.properties.IPropertyDescriptor; public class SchoolPropertySource extends PropertySource { public SchoolPropertySource(Object object, IItemPropertySource itemPropertySource) { super(object, itemPropertySource); } @Override protected IPropertyDescriptor createPropertyDescriptor( IItemPropertyDescriptor itemPropertyDescriptor) { SchoolPackage pkg = SchoolPackage.eINSTANCE; Object feature = itemPropertyDescriptor.getFeature(object); if (pkg.getStudent_Friends().equals(feature)) { return new StudentFriendsPropertyDescriptor(object, itemPropertyDescriptor); } // Other cases to handle ? // else if (pkg.get<AnotherFeature>().equals(feature)) { // return myPropertyDescriptor(object, itemPropertyDescriptor); // } // Else, default EMF behavior else { return super.createPropertyDescriptor(itemPropertyDescriptor); } } }
This class is the place where you have to implement the custom editor UI. In this example we simply open a ElementListSelectionDialog
initialized with the students list available in the current model.
package jfb.examples.gmf.school.ui.provider; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import jfb.examples.gmf.school.Classroom; import jfb.examples.gmf.school.School; import jfb.examples.gmf.school.Student; import org.eclipse.emf.common.ui.celleditor.ExtendedDialogCellEditor; import org.eclipse.emf.edit.provider.IItemPropertyDescriptor; import org.eclipse.emf.edit.ui.provider.PropertyDescriptor; import org.eclipse.jface.viewers.CellEditor; import org.eclipse.jface.window.Window; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.dialogs.ElementListSelectionDialog; public class StudentFriendsPropertyDescriptor extends PropertyDescriptor { public StudentFriendsPropertyDescriptor(Object object, IItemPropertyDescriptor itemPropertyDescriptor) { super(object, itemPropertyDescriptor); } @Override public CellEditor createPropertyEditor(Composite parent) { return new ExtendedDialogCellEditor(parent, getLabelProvider()) { @Override protected Object openDialogBox(Control cellEditorWindow) { // Here you are free to open a custom dialog that you have // created. In this example, we simply open an // ElementListSelectionDialog // Let's retrieve the current student and all the available // students Student student = (Student) object; School school = (School) student.eContainer().eContainer(); List<Student> allStudents = new ArrayList<Student>(); for (Classroom classroom : school.getClassrooms()) { allStudents.addAll(classroom.getStudents()); } // The student cannot be a friend of himself allStudents.remove(student); // Dialog creation ElementListSelectionDialog dialog = new ElementListSelectionDialog( PlatformUI.getWorkbench().getDisplay().getActiveShell(), getLabelProvider()); dialog.setElements(allStudents.toArray()); dialog.setInitialSelections(student.getFriends().toArray()); dialog.setTitle("Available friends list"); dialog.setMessage("Select the friends of '" + student.getName() + "'"); dialog.setMultipleSelection(true); // Open the dialog and retrieve the user selection int result = dialog.open(); labelProvider.dispose(); return result == Window.OK ? Arrays.asList(dialog.getResult()) : null; } }; } }
School.editor
plugin :META-INF/MANIFEST.MF
file of the School.editor
plugin projectSchool.edit.ui
getPropertySheetPage
method of the SchoolEditor
class, replace the following line : propertySheetPage.setPropertySourceProvider(new AdapterFactoryContentProvider(adapterFactory));
by this one :
propertySheetPage.setPropertySourceProvider(new SchoolPropertySourceProvider(adapterFactory));
(and don't forget to add NOT
after the @generated
string in the javadoc comments)
School.diagram
plugin :META-INF/MANIFEST.MF
file of the School.diagram
plugin projectSchool.edit.ui
getPropertySource
method of the jfb.examples.gmf.school.diagram.sheet.SchoolPropertySection
class, replace the following line : return new PropertySource(object, ips);
by this one :
return new SchoolPropertySource(object, ips);
(and don't forget to add NOT
after the @generated
string in the javadoc comments)
I hope that this material will be helpful for you. If you want to support it, your help is welcome :
Discussion
Many many qaliuty points there.
Thank you !
I am getting error in MANIFEST.MF file of School.edit.ui