emf_tutorial5 [GMF Samples And Tutorials]
 

Overview

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 :

  • Eclipse 3.6
  • Graphical Modeling Framework SDK 2.3.0
  • Eclipse Modeling Framework 2.6.0

Plugin management strategies

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 :

  1. you ONLY plan to use the default EMF tree editor : in that case, the 3 java classes can reside directly in the EMF editor plugin
  2. you ONLY plan to use the diagram editor that has been created on top of GMF : in that case, the 3 java classes can reside directly in the GMF diagram editor plugin
  3. you want to be able to use both EMF tree editor and GMF diagram editor : in that case, the 3 classes need to reside in a place that is reachable from both EMF editor & GMF diagram editor ; which means that you can put theses classes in the EMF edit plugin (the worst way) or create a new plugin (the best way)

In this tutorial we will apply the third strategy with a new dedicated plugin. Feel free to adapt it to your own needs.

New plugin creation

  • Create a new plugin project named School.edit.ui
  • In the source folder, create a new java package named jfb.examples.gmf.school.ui.provider
  • Open the META-INF/MANIFEST.MF file
  • Go to the dependencies tab and add the following dependencies :
    • org.eclipse.emf.edit.ui
    • School
  • Go to the Runtime tab and add the package you've just created in the Exported Packages list
  • Save the file

Custom property editor implementation

The custom property source provider

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);
	}
 
}

The custom property source

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);
		}
	}
 
}

The custom property descriptor

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;
			}
		};
	}
 
}

EMF Tree Editor integration

  • In the School.editor plugin :
  • Open the META-INF/MANIFEST.MF file of the School.editor plugin project
  • Go to the dependencies tab and add the following dependency : School.edit.ui
  • Save the file
  • In the 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)

GMF Diagram Editor integration

  • In the School.diagram plugin :
  • Open the META-INF/MANIFEST.MF file of the School.diagram plugin project
  • Go to the dependencies tab and add the following dependency : School.edit.ui
  • Save the file
  • In the 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)

Run and test

  • Run the eclipse configuration that had been created in the first tutorial.
  • If you open you model (with the EMF tree editor or with the GMF diagram editor), and click on the friends property of a student, you should get this result (the default EMF dialog has been replaced by the element selection dialog) :

Thank you

I hope that this material will be helpful for you. If you want to support it, your help is welcome :

Discussion

Laquisha, 2011/12/07 16:30

Many many qaliuty points there.

Jean-Fran├žois Brazeau, 2011/12/07 21:28

Thank you !

Adnan, 2013/02/11 16:11

I am getting error in MANIFEST.MF file of School.edit.ui

 
emf_tutorial5.txt · Last modified: 2011/08/08 20:05 by jfbraz
 
Except where otherwise noted, content on this wiki is licensed under the following license:CC Attribution-Noncommercial-Share Alike 3.0 Unported
Recent changes RSS feed Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki