Contenu connexe
Similaire à Graphiti and GMF Compared
Similaire à Graphiti and GMF Compared (20)
Graphiti and GMF Compared
- 1. Graphiti and GMF Compared
The Graph Editor Revisited
Koen Aers
1 Graphiti and GMF Compared : Revisiting the Graph Editor © 2011 by Koen Aers; made available under the EPL v1.0
- 2. Speaker
JBoss Tools: http://www.jboss.org/tools
Email: koen.aers@jboss.com
Blog:
http://community.jboss.org/people/koen.aers/blog
http://koentsje.blogspot.com/
2 Graphiti and GMF Compared : Revisiting the Graph Editor © 2011 by Koen Aers; made available under the EPL v1.0
- 3. Agenda
Introduction : Graphiti and GMF
Graph Editor: GEF Memories
Common Foundation : Graph EMF Model
Generating a Graph Editor : GMF Tools
Handcrafting a Graph Editor
Part 1 : Graphiti
Part 2 : the GMF Runtime
Graphiti and GMF Compared
Conclusion
3 Graphiti and GMF Compared : Revisiting the Graph Editor © 2011 by Koen Aers; made available under the EPL v1.0
- 4. Graphiti and GMF
Frameworks to create rich graphical editors easily
Part of the Graphical Modeling Platform
GMF:
Around @ Eclipse since 2005
Runtime (IBM) & Tools part (Borland R.I.P)
Graphiti
Initial contribution March 2010 (currently incubating)
Main backing company: SAP
`Separation of semantic graphical information
Stored either separately or together
4 Graphiti and GMF Compared : Revisiting the Graph Editor © 2011 by Koen Aers; made available under the EPL v1.0
- 5. GEF Memories
22 Java classes
1023 lines of code
17 lines of plugin.xml
No persistence
No alignment, popup
bars, zoom, etc.
Comprehensive
understanding of the
framework
5 Graphiti and GMF Compared : Revisiting the Graph Editor © 2011 by Koen Aers; made available under the EPL v1.0
- 6. An EMF Model For Graphs
<grph:graph <xsd:schema ...>
xmlns:grph="http://www.graph.org/model" <xsd:complexType name="Base" ...>
id="0" <xsd:attribute name="id" .../>
name="Base"> <xsd:attribute name="name" .../>
<grph:node id="1" name="f"/> </xsd:complexType>
<grph:node id="2" name="s"/> <xsd:complexType name="Node">
<grph:edge id="3" name="e" from="1 to="2"/> <xsd:complexContent>
</grph:graph> <xsd:extension base="Base"/>
</xsd:complexContent>
</xsd:complexType>
<xsd:complexType name="Edge">
<xsd:complexContent>
<xsd:extension base="Base">
<xsd:attribute name="from" .../>
<xsd:attribute name="to" .../>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
<xsd:complexType name="Graph">
...
</xsd:complexType>
<xsd:element name="graph" type="Graph"/>
</xsd:schema>
6 Graphiti and GMF Compared : Revisiting the Graph Editor © 2011 by Koen Aers; made available under the EPL v1.0
- 7. GMF Tools: Overview
7 Graphiti and GMF Compared : Revisiting the Graph Editor © 2011 by Koen Aers; made available under the EPL v1.0
- 8. GMF Tools : Generate a Graph Editor
Use GMF dashboard
Select domain model
Select domain gen model
Derive GMF graph model
Derive GMF tool model
Combine into GMF
mapping model
Transform into GMF
generator model
Generate Graph Editor
8 Graphiti and GMF Compared : Revisiting the Graph Editor © 2011 by Koen Aers; made available under the EPL v1.0
- 9. Graphiti: Overview
9 Graphiti and GMF Compared : Revisiting the Graph Editor © 2011 by Koen Aers; made available under the EPL v1.0
- 10. Handcrafting a Graph Editor with Graphiti
Plugin project + dependencies
Contribute the Editor
Contribute the Diagram Type and Diagram Type
Provider
Create a Feature Provider
Contribute a wizard to create graphs
Add the features to the Feature Provider
CreateNodeFeature, AddNodeFeature
CreateEdgeFeature, AddEdgeFeature
Contribute the property page to edit the attributes
10 Graphiti and GMF Compared : Revisiting the Graph Editor © 2011 by Koen Aers; made available under the EPL v1.0
- 11. Graphiti : First Steps
<plugin> Require-Bundle: org.eclipse.ui,
<extension point="org.eclipse.ui.editors"> org.eclipse.core.runtime,
<editor org.eclipse.graphiti,
class="org.eclipse.graphiti.ui.editor.DiagramEditor" org.eclipse.graphiti.ui,
default="false" org.graph.emf,
extensions="graphiti_diagram" org.eclipse.ui.views.properties.tabbed,
id="org.graph.graphiti.diagram.editor" org.eclipse.ui.ide,
name="Graphiti Graph Editor"/> org.eclipse.core.resources,
</extension> org.eclipse.emf.transaction
<extension
point="org.eclipse.graphiti.ui.diagramTypes">
<diagramType
id="org.graph.graphiti.diagram" Create plugin project
name="Graph Diagram"
type="org.graph.graphiti.diagram"/> Add dependencies
</extension>
<extension Contribute editor
point="org.eclipse.graphiti.ui.diagramTypeProviders">
<diagramTypeProvider Contribute diagram type
class="org.graph....GraphDiagramTypeProvider"
id="org.graph.graphiti.diagram" Contribute diagram type
name="Graph Editor">
<diagramType id="org.graph.graphiti.diagram"/>
provider
</diagramTypeProvider>
</extension>
</plugin>
11 Graphiti and GMF Compared : Revisiting the Graph Editor © 2011 by Koen Aers; made available under the EPL v1.0
- 12. Graphiti : Diagram Type and Feature Provider
public class GraphDiagramTypeProvider extends AbstractDiagramTypeProvider {
public static final String DIAGRAM_TYPE_ID = "org.graph.graphiti.diagram";
public static final String PROVIDER_ID = "org.graph.graphiti.diagram";
public GraphDiagramTypeProvider() {
super();
setFeatureProvider(new GraphDiagramFeatureProvider(this));
}
}
public class GraphDiagramFeatureProvider extends DefaultFeatureProvider {
public GraphDiagramFeatureProvider(IDiagramTypeProvider dtp) {
super(dtp);
}
}
12 Graphiti and GMF Compared : Revisiting the Graph Editor © 2011 by Koen Aers; made available under the EPL v1.0
- 13. Graphiti : Create a Graph
<plugin>
...
<extension point="org.eclipse.ui.newWizards">
<category
id="org.graph.graphiti.diagram"
name="Graph"/>
<wizard
category="org.graph.graphiti.diagram"
class="org.graph...GraphCreationWizard"
id="org.graph.graphiti.diagram.wizard"
name="Graphiti Graph"/>
</extension>
</plugin>
Semantic and graphic info stored separately
No ready to use wizards available
Mainly EMF related object manipulations
13 Graphiti and GMF Compared : Revisiting the Graph Editor © 2011 by Koen Aers; made available under the EPL v1.0
- 14. public static Resource createDiagram(URI d, URI m, IProgressMonitor pm) {
TransactionalEditingDomain ed = DiagramEditorFactory.createResourceSetAndEditingDomain();
final Resource dr = ed.getResourceSet().createResource(d);
final Resource mr = ed.getResourceSet().createResource(m);
final Graph model = GraphFactory.eINSTANCE.createGraph();
final DocumentRoot documentRoot = GraphFactory.eINSTANCE.createDocumentRoot();
documentRoot.setGraph(model);
String diagramName = d.lastSegment();
final Diagram diagram = Graphiti.getPeCreateService().createDiagram(
GraphDiagramTypeProvider.DIAGRAM_TYPE_ID, diagramName, true);
PictogramLink link = PictogramsFactory.eINSTANCE.createPictogramLink();
diagram.setLink(link);
link.getBusinessObjects().add(model);
final CommandStack commandStack = ed.getCommandStack();
commandStack.execute(new RecordingCommand(ed) {
protected void doExecute() {
mr.setTrackingModification(true);
dr.setTrackingModification(true);
dr.getContents().add(diagram);
mr.getContents().add(documentRoot);
try {
mr.save(Collections.EMPTY_MAP);
dr.save(Collections.EMPTY_MAP);
} catch (IOException e) {}
}
});
return dr;
}
14 Graphiti and GMF Compared : Revisiting the Graph Editor © 2011 by Koen Aers; made available under the EPL v1.0
- 15. Graphiti : Create Nodes (1/2)
public class CreateNodeFeature extends AbstractCreateFeature {
public CreateNodeFeature(IFeatureProvider fp) {
super(fp, "Node", "Create Node");
}
public boolean canCreate(ICreateContext context) {
return context.getTargetContainer() instanceof Diagram;
}
public Object[] create(ICreateContext context) {
Node node = GraphFactory.eINSTANCE.createNode();
addGraphicalRepresentation(context, node);
return new Object[] { node };
}
}
15 Graphiti and GMF Compared : Revisiting the Graph Editor © 2011 by Koen Aers; made available under the EPL v1.0
- 16. Graphiti : Create Nodes (2/2)
public class GraphDiagramFeatureProvider extends DefaultFeatureProvider {
...
public ICreateFeature[] getCreateFeatures() {
return new ICreateFeature[] { new CreateNodeFeature(this) };
}
}
16 Graphiti and GMF Compared : Revisiting the Graph Editor © 2011 by Koen Aers; made available under the EPL v1.0
- 17. Graphiti : Add Nodes (1/2)
public class AddNodeFeature extends AbstractAddShapeFeature {
public AddNodeFeature(IFeatureProvider fp) {
super(fp);
}
public boolean canAdd(IAddContext context) {
return ((context.getNewObject() instanceof Node)
&& (context.getTargetContainer() instanceof Diagram));
}
public PictogramElement add(IAddContext context) {
Diagram targetDiagram = (Diagram)context.getTargetContainer();
Graph graph = (Graph)targetDiagram.getLink().getBusinessObjects().get(0);
graph.getNode().add((Node)context.getNewObject());
ContainerShape cs = Graphiti.getPeCreateService().createContainerShape(targetDiagram, true);
RoundedRectangle rr = Graphiti.getGaService().createRoundedRectangle(cs, 8, 8);
rr.setFilled(false);
Graphiti.getGaService().setLocationAndSize(rr, context.getX(), context.getY(), 80, 40);
link(cs, (Node)context.getNewObject());
layoutPictogramElement(cs);
return cs;
}
}
17 Graphiti and GMF Compared : Revisiting the Graph Editor © 2011 by Koen Aers; made available under the EPL v1.0
- 18. Graphiti : Add Nodes (2/2)
public class GraphDiagramFeatureProvider extends DefaultFeatureProvider {
...
public IAddFeature getAddFeature(IAddContext context) {
if (context.getNewObject() instanceof Node) {
return new AddNodeFeature(this);
}
return super.getAddFeature(context);
}
}
18 Graphiti and GMF Compared : Revisiting the Graph Editor © 2011 by Koen Aers; made available under the EPL v1.0
- 19. Graphiti : Create Edges (1/3)
public class CreateEdgeFeature extends AbstractCreateConnectionFeature {
public CreateEdgeFeature(IFeatureProvider fp) {
super(fp, "Edge", "Create Edge");
}
public boolean canCreate(ICreateConnectionContext context) {
return (getNode(context.getSourceAnchor()) != null)
&& (getNode(context.getTargetAnchor()) != null);
}
private Node getNode(Anchor anchor) {
if (anchor == null) return null;
Object object = getBusinessObjectForPictogramElement(anchor.getParent());
if (object instanceof Node) return (Node)object;
return null;
}
public boolean canStartConnection(ICreateConnectionContext context) {
return getNode(context.getSourceAnchor()) != null;
}
...
19 Graphiti and GMF Compared : Revisiting the Graph Editor © 2011 by Koen Aers; made available under the EPL v1.0
- 20. Graphiti : Create Edges (2/3)
...
public Connection create(ICreateConnectionContext context) {
Edge edge = GraphFactory.eINSTANCE.createEdge();
edge.setFrom(getNode(context.getSourceAnchor()));
edge.setTo(getNode(context.getTargetAnchor()));
Graph graph = (Graph)getDiagram().getLink().getBusinessObjects().get(0);
graph.getEdge().add(edge);
AddConnectionContext addConnectionContext =
new AddConnectionContext(context.getSourceAnchor(), context.getTargetAnchor());
addConnectionContext.setNewObject(edge);
return (Connection)getFeatureProvider().addIfPossible(addConnectionContext);
}
}
public class GraphDiagramFeatureProvider extends DefaultFeatureProvider {
...
public ICreateConnectionFeature[] getCreateConnectionFeatures() {
return new ICreateConnectionFeature[] { new CreateEdgeFeature(this) };
}
}
20 Graphiti and GMF Compared : Revisiting the Graph Editor © 2011 by Koen Aers; made available under the EPL v1.0
- 21. Graphiti : Create Edges (3/3)
public class AddNodeFeature extends AbstractAddShapeFeature {
...
public PictogramElement add(IAddContext context) {
...
getPeCreateService().createChopboxAnchor(cs);;
return cs;
}
}
public class GraphDiagramFeatureProvider extends DefaultFeatureProvider {
...
public ICreateConnectionFeature[] getCreateConnectionFeatures() {
return new ICreateConnectionFeature[] { new CreateEdgeFeature(this) };
}
}
21 Graphiti and GMF Compared : Revisiting the Graph Editor © 2011 by Koen Aers; made available under the EPL v1.0
- 22. Graphiti : Add Edges (1/2)
public class AddEdgeFeature extends AbstractAddFeature {
public AddEdgeFeature(IFeatureProvider fp) {
super(fp);
}
public boolean canAdd(IAddContext context) {
return context instanceof IAddConnectionContext && context.getNewObject() instanceof Edge);
}
public PictogramElement add(IAddContext context) {
IAddConnectionContext addConnectionContext = (IAddConnectionContext)context;
Edge addedEdge = (Edge)context.getNewObject();
IPeCreateService peCreateService = Graphiti.getPeCreateService();
Connection connection = peCreateService.createFreeFormConnection(getDiagram());
connection.setStart(addConnectionContext.getSourceAnchor());
connection.setEnd(addConnectionContext.getTargetAnchor());
IGaService gaService = Graphiti.getGaService();
gaService.createPolyline(connection);
link(connection, addedEdge);
return connection;
}
}
22 Graphiti and GMF Compared : Revisiting the Graph Editor © 2011 by Koen Aers; made available under the EPL v1.0
- 23. Graphiti : Add Edges (2/2)
public class GraphDiagramFeatureProvider extends DefaultFeatureProvider {
...
public IAddFeature getAddFeature(IAddContext context) {
if (context.getNewObject() instanceof Node) {
return new AddNodeFeature(this);
} else if (context.getNewObject() instanceof Edge) {
return new AddEdgeFeature(this);
}
return super.getAddFeature(context);
}
}
23 Graphiti and GMF Compared : Revisiting the Graph Editor © 2011 by Koen Aers; made available under the EPL v1.0
- 24. Graphiti : Simple Graph Editor
24 Graphiti and GMF Compared : Revisiting the Graph Editor © 2011 by Koen Aers; made available under the EPL v1.0
- 25. Handcrafting a Graph Editor with GMF
Create plugin + Implement NodeEditPart
dependencies & EdgeEditPart
Contribute Add the NodeEditHelper
The Editor Add the
The Element Types DocumentProvider to
The View Provider
enable saving
Add the
Contribute and implement ActionBarContributor
a wizard to create graphs
Add the Properties Page
Contribute the Palette
Provider and implement a
PaletteFactory
25 Graphiti and GMF Compared : Revisiting the Graph Editor © 2011 by Koen Aers; made available under the EPL v1.0
- 26. GMF Runtime : First Steps
<plugin>
<extension point="org.eclipse.ui.editors">
<editor
class="org.eclipse.gmf.runtime.diagram.ui...ide.editor.FileDiagramEditorWithFlyoutPalette"
default="false"
extensions="gmf_runtime_diagram"
id="org.graph.gmf.runtime.diagram.editor"
name="GMF Runtime Graph Editor"/>
</extension>
</plugin>
Require-Bundle: org.eclipse.ui, Create plugin project
org.eclipse.core.runtime,
org.eclipse.core.resources, Add dependencies
org.eclipse.ui.ide,
org.eclipse.gmf.runtime.diagram.ui, Contribute editor
org.eclipse.gmf.runtime.diagram.ui.resources.editor.ide,
org.eclipse.gmf.runtime.diagram.ui.providers, Contribute element types
org.graph.emf
Contribute view provider
26 Graphiti and GMF Compared : Revisiting the Graph Editor © 2011 by Koen Aers; made available under the EPL v1.0
- 27. GMF Runtime : Element Types
<plugin>
...
<extension point="org.eclipse.gmf.runtime.emf.type.core.elementTypes">
<metamodel nsURI="http://www.graph.org/model">
<metamodelType
id="org.graph.gmf.runtime.graph"
eclass="Graph"
kind="org.eclipse.gmf.runtime.emf.type.core.IHintedType"
name="Graph">
<param name="semanticHint"value="org.graph.gmf.runtime.graph"/>
</metamodelType>
<metamodelType
id="org.graph.gmf.runtime.node"
name="Node"
eclass="Node"
kind="org.eclipse.gmf.runtime.emf.type.core.IHintedType">
<param name="semanticHint" value="org.graph.gmf.runtime.node"/>
</metamodelType>
<metamodelType
id="org.graph.gmf.runtime.edge"
name="Edge"
eclass="Edge"
kind="org.eclipse.gmf.runtime.emf.type.core.IHintedType">
<param name="semanticHint" value="org.graph.gmf.runtime.edge"/>
</metamodelType>
</metamodel>
</extension>
</plugin>
27 Graphiti and GMF Compared : Revisiting the Graph Editor © 2011 by Koen Aers; made available under the EPL v1.0
- 28. GMF Runtime : View Provider
<extension point="org.eclipse.gmf.runtime.diagram.core.viewProviders">
<viewProvider class="org.graph.gmf.runtime.diagram.providers.GraphViewProvider">
<Priority name="Lowest"/>
<context
viewClass="org.eclipse.gmf.runtime.notation.Diagram"
semanticHints="org.graph.gmf.runtime.graph"/>
<context
viewClass="org.eclipse.gmf.runtime.notation.Node"
semanticHints="org.graph.gmf.runtime.node"/>
<context
viewClass="org.eclipse.gmf.runtime.notation.Edge"
semanticHints="org.graph.gmf.runtime.edge"/>
</viewProvider>
</extension>
public class GraphViewProvider extends AbstractViewProvider {
protected Class getDiagramViewClass(IAdaptable semanticAdapter, String dk) {
return "org.graph.gmf.runtime.graph".equals(dk) ? StandardDiagramViewFactory.class : null;
}
protected Class getNodeViewClass(IAdaptable semanticAdapter, View containerView, String sh) {
return "org.graph.gmf.runtime.node".equals(sh) ? ShapeViewFactory.class : null;
}
protected Class getEdgeViewClass(IAdaptable semanticAdapter, View containerView, String sh) {
return "org.graph.gmf.runtime.edge".equals(sh) ? ConnectionViewFactory.class : null;
}
}
28 Graphiti and GMF Compared : Revisiting the Graph Editor © 2011 by Koen Aers; made available under the EPL v1.0
- 29. GMF Runtime : Create a Graph (1/4)
<plugin>
...
<extension point="org.eclipse.ui.newWizards">
<category
id="org.graph.gmf.runtime.diagram"
name="Graph GMF Runtime">
</category>
<wizard
category="org.graph.gmf.runtime.diagram"
class="org.graph.gmf.runtime.diagram.wizard.GraphCreationWizard"
id="org.graph.gmf.runtime.diagram.wizard"
name="Graph">
</wizard>
</extension>
</plugin>
public class GraphCreationWizard extends EditorCreationWizard{
public void addPages() {
addPage(page = new GraphCreationWizardPage(getWorkbench(), getSelection()));
}
public void init(IWorkbench workbench, IStructuredSelection sel) {
super.init(workbench, sel);
}
}
29 Graphiti and GMF Compared : Revisiting the Graph Editor © 2011 by Koen Aers; made available under the EPL v1.0
- 30. GMF Runtime : Create a Graph (2/4)
public class GraphCreationWizardPage extends EditorWizardPage {
private IDEEditorFileCreator dfc = null;
public GraphCreationWizardPage(IWorkbench aWorkbench, IStructuredSelection selection) {
super("GraphDiagramPage", aWorkbench, selection);
setTitle("Create Graph Diagram");
setDescription("Create a new Graph diagram.");
}
public DiagramFileCreator getDiagramFileCreator() {
if (dfc == null)
dfc = new IDEEditorFileCreator() {
public String getExtension() { return ".gmf_runtime_diagram"; }
}
return dfc;
}
protected String getDefaultFileName() { return "default"; }
protected String getDiagramKind() { return "org.graph.gmf.runtime.graph"; }
public IFile createAndOpenDiagram(IPath cp, String fn, InputStream ic, String k,
IWorkbenchWindow ww, IProgressMonitor pm, boolean sd) {
String srp = cp.append(fn).removeFileExtension().addFileExtension("graph").toString();
return GraphDiagramEditorUtil.createAndOpenDiagram(dfc, cp, fn, ic, k, ww, pm, srp);
}
}
30 Graphiti and GMF Compared : Revisiting the Graph Editor © 2011 by Koen Aers; made available under the EPL v1.0
- 31. GMF Runtime : Create a Graph (3/4)
public class GraphDiagramEditorUtil {
public static IFile createAndOpenDiagram(DiagramFileCreator dfc, IPath cp, String fn,
InputStream ic, String k, IWorkbenchWindow ww, IProgressMonitor pm, String srp) {
IFile newFile = createNewDiagramFile(dfc, cp, fn, ic, k, ww.getShell(), pm, srp);
if (newFile != null) {
IDEEditorUtil.openDiagram(newFile, ww, true, pm);
}
return newFile;
}
public static IFile createNewDiagramFile(DiagramFileCreator dfc, IPath cfp, String fn,
InputStream ic, String k, Shell s, IProgressMonitor pm, final String srp) {
IFile newDiagramFile = dfc.createNewFile(cfp, fn, ic, s, new WorkspaceOperationRunner());
TransactionalEditingDomain domain = GMFEditingDomainFactory.getInstance().createEditingDomain();
AbstractEMFOperation op = new GraphDiagramCreationOperation(newDiagramFile, srp, domain, k);
try {
op.execute(new NullProgressMonitor(), null);
} catch (ExecutionException e) {}
return newDiagramFile;
}
}
31 Graphiti and GMF Compared : Revisiting the Graph Editor © 2011 by Koen Aers; made available under the EPL v1.0
- 32. GMF Runtime : Create a Graph (4/4)
public class GraphDiagramCreationOperation extends AbstractEMFOperation {
private IFile ndf;
private String dk, srp;
public GraphDiagramCreationOperation(IFile ndf, String srp, TransactionalEditingDomain ed, String dk) {
super(ed, "Create Graph Diagram");
this.ndf = ndf; this.dk = dk; this.srp = srp;
}
protected IStatus doExecute(IProgressMonitor pm, IAdaptable adaptable) throws ExecutionException {
DocumentRoot documentRoot = GraphFactory.eINSTANCE.createDocumentRoot();
documentRoot.setGraph(GraphFactory.eINSTANCE.createGraph());
ResourceSet resourceSet = getEditingDomain().getResourceSet();
Resource semanticResource = resourceSet.createResource(URI.createPlatformResourceURI(srp, true));
semanticResource.getContents().add(documentRoot);
String completeFileName = ndf.getLocation().toOSString();
Resource notationResource = resourceSet.createResource(URI.createFileURI(completeFileName));
Diagram view = ViewService.createDiagram(dk, new PreferencesHint("org.graph.gmf.runtime.diagram"));
notationResource.getContents().add(view);
view.setName(ndf.getName());
view.setElement(documentRoot.getGraph());
try {
semanticResource.save(Collections.EMPTY_MAP);
notationResource.save(Collections.EMPTY_MAP);
} catch (IOException e) {}
return Status.OK_STATUS;
}
}
32 Graphiti and GMF Compared : Revisiting the Graph Editor © 2011 by Koen Aers; made available under the EPL v1.0
- 33. GMF Runtime : Palette Provider (1/2)
<extension point="org.eclipse.gmf.runtime.diagram.ui.paletteProviders">
<paletteProvider class="org.eclipse.gmf.runtime.diagram.ui.providers.DefaultPaletteProvider">
<Priority name="Lowest"/>
<editor id="org.graph.gmf.runtime.diagram.editor"/>
<contribution factoryClass="org.graph.gmf.runtime.diagram.providers.GraphPaletteFactory">
<entry
label="Graph"
kind="drawer"
path="/"
id="org.graph.gmf.runtime.graph">
<expand><content/></expand>
</entry>
<entry
label="Node"
kind="tool"
id="org.graph.gmf.runtime.node"
path="/org.graph.gmf.runtime.graph/"/>
<entry
label="Edge"
kind="tool"
id="org.graph.gmf.runtime.edge"
path="/org.graph.gmf.runtime.graph/"/>
</contribution>
</paletteProvider>
</extension>
33 Graphiti and GMF Compared : Revisiting the Graph Editor © 2011 by Koen Aers; made available under the EPL v1.0
- 34. GMF Runtime : Palette Provider (2/2)
public class GraphPaletteFactory extends PaletteFactory.Adapter {
public Tool createTool(String toolId) {
if ("org.graph.gmf.runtime.node".equals(toolId)) {
return new CreationTool(ElementTypeRegistry.getInstance().getType(toolId));
} else if ("org.graph.gmf.runtime.edge".equals(toolId)) {
return new ConnectionCreationTool(ElementTypeRegistry.getInstance().getType(toolId));
}
return null;
}
}
34 Graphiti and GMF Compared : Revisiting the Graph Editor © 2011 by Koen Aers; made available under the EPL v1.0
- 35. GMF Runtime : EditPart Provider
<plugin>
...
<extension point="org.eclipse.gmf.runtime.diagram.ui.editpartProviders">
<editpartProvider class="org.graph.gmf.runtime.diagram.providers.GraphEditPartProvider">
<Priority name="Lowest"/>
</editpartProvider>
</extension>
</plugin>
public class GraphEditPartProvider extends AbstractEditPartProvider {
protected Class getDiagramEditPartClass(View view ) {
return "org.graph.gmf.runtime.graph".equals(view.getType()) ? DiagramEditPart.class : null;
}
protected Class getNodeEditPartClass(View view) {
return "org.graph.gmf.runtime.node".equals(view.getType()) ? NodeEditPart.class : null;
}
protected Class getEdgeEditPartClass(View view) {
return "org.graph.gmf.runtime.edge".equals(view.getType()) ? EdgeEditPart.class : null;
}
}
35 Graphiti and GMF Compared : Revisiting the Graph Editor © 2011 by Koen Aers; made available under the EPL v1.0
- 36. GMF Runtime : NodeEditPart and EdgeEditPart
public class NodeEditPart extends ShapeNodeEditPart {
public NodeEditPart(View view) {
super(view);
}
protected NodeFigure createNodeFigure() {
NodeFigure result = new NodeFigure();
result.setLayoutManager(new StackLayout());
result.add(new RoundedRectangle());
return result;
}
}
public class EdgeEditPart extends ConnectionEditPart {
public EdgeEditPart(View view) {
super(view);
}
protected Connection createConnectionFigure() {
return new PolylineConnection();
}
}
36 Graphiti and GMF Compared : Revisiting the Graph Editor © 2011 by Koen Aers; made available under the EPL v1.0
- 37. GMF Runtime : Creating Edges (1/2)
<metamodelType
id="org.graph.gmf.runtime.node"
name="Node"
edithelper="org.graph.gmf.runtime.diagram.edithelper.NodeEditHelper"
eclass="Node"
kind="org.eclipse.gmf.runtime.emf.type.core.IHintedType">
<param name="semanticHint" value="org.graph.gmf.runtime.node"/>
</metamodelType>
public class NodeEditHelper extends AbstractEditHelper {
private static final IElementType EDGE_ELEMENT_TYPE =
ElementTypeRegistry.getInstance().getType("org.graph.gmf.runtime.edge");
protected ICommand getCreateRelationshipCommand(CreateRelationshipRequest req) {
if (req.getElementType() == EDGE_ELEMENT_TYPE
&& req.getSource() instanceof Node
&& req.getTarget() instanceof Node) {
return new CreateEdgeCommand(req);
}
return super.getCreateRelationshipCommand(req);
}
}
37 Graphiti and GMF Compared : Revisiting the Graph Editor © 2011 by Koen Aers; made available under the EPL v1.0
- 38. GMF Runtime : Creating Edges (2/2)
public class CreateEdgeCommand extends CreateRelationshipCommand {
public CreateEdgeCommand(CreateRelationshipRequest request) {
super(request);
}
protected EObject getElementToEdit() {
return ((Node)super.getElementToEdit()).eContainer();
}
protected EClass getEClassToEdit() {
return GraphPackage.eINSTANCE.getGraph();
}
protected EReference getContainmentFeature() {
return GraphPackage.eINSTANCE.getGraph_Edge();
}
}
38 Graphiti and GMF Compared : Revisiting the Graph Editor © 2011 by Koen Aers; made available under the EPL v1.0
- 39. GMF Runtime : Saving the Diagram
<extension point="org.eclipse.emf.ecore.extension_parser">
<parser
type="gmf_runtime_diagram"
class="org.eclipse.gmf.runtime.emf.core.resources.GMFResourceFactory"/>
</extension>
<extension
point="org.eclipse.gmf.runtime.diagram.ui.resources.editor.documentProviders">
<provider
class="org.graph.gmf.runtime.diagram.providers.GraphDocumentProvider"
extensions="gmf_runtime_diagram"
documentType="org.eclipse.gmf.runtime.diagram.ui.resources.editor.document.IDiagramDocument"
id="org.graph.gmf.runtime.diagram">
</provider>
</extension>
public class GraphDocumentProvider extends FileDiagramDocumentProvider {
protected void saveDocumentToFile(
IDocument d, IFile f, boolean o, IProgressMonitor m) throws CoreException {
try {
for (Resource r : ((IDiagramDocument)d).getEditingDomain().getResourceSet().getResources())
r.save(Collections.EMPTY_MAP);
} catch (IOException e) {}
}
protected ISchedulingRule getSaveRule(Object element) { return null; }
}
39 Graphiti and GMF Compared : Revisiting the Graph Editor © 2011 by Koen Aers; made available under the EPL v1.0
- 40. GMF Runtime : the ActionBarContributor
<extension point="org.eclipse.ui.editors">
<editor
class="org...FileDiagramEditorWithFlyoutPalette"
contributorClass="org.graph.gmf.runtime.diagram.GraphDiagramActionBarContributor"
default="false"
extensions="gmf_runtime_diagram"
id="org.graph.gmf.runtime.diagram.editor"
name="GMF Runtime Graph Editor">
</editor>
</extension>
public class GraphDiagramActionBarContributor extends DiagramActionBarContributor {
protected String getEditorId() {
return "org.graph.gmf.runtime.diagram.editor";
}
protected Class getEditorClass() {
return FileDiagramEditorWithFlyoutPalette.class;
}
}
40 Graphiti and GMF Compared : Revisiting the Graph Editor © 2011 by Koen Aers; made available under the EPL v1.0
- 41. GMF Runtime : Simple Graph Editor
41 Graphiti and GMF Compared : Revisiting the Graph Editor © 2011 by Koen Aers; made available under the EPL v1.0
- 42. Example From the Trenches : BPMN 2.0
<?xml version="1.0" encoding="UTF-8"?>
<bpmn2:definitions
xmlns:bpmn2="..."
xmlns:bpmndi="..."
xmlns:dc="..."
xmlns:di="..."
id="d0">
<bpmn2:process id="pr1">
<bpmn2:userTask id="t1" name="task"/>
</bpmn2:process>
<bpmndi:BPMNDiagram id="d1">
<bpmndi:BPMNPlane id="pl1" bpmnElement="pr1">
<bpmndi:BPMNShape id="s1" bpmnElement="t1">
<dc:Bounds
height="-1.0"
width="-1.0"
x="140.0"
y="100.0"/>
<bpmndi:BPMNLabel id="l1"/>
</bpmndi:BPMNShape>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</bpmn2:definitions>
42 Graphiti and GMF Compared : Revisiting the Graph Editor © 2011 by Koen Aers; made available under the EPL v1.0
- 43. Example From the Trenches : BPMN 2.0
GMF Solution:
Create wrapper objects for BPMNDiagram,
BPMNShape, etc from the BPMN DI EMF model project.
Wrappers implement the Diagram, Shape, etc interfaces
from the GMF Graphical Notation
Make sure these wrappers are created e.g. by view
provider when adding semantic objects
Graphiti:
AFAICS no 'direct' way of doing this
Workaround by transforming the models when
serializing/deserializing
43 Graphiti and GMF Compared : Revisiting the Graph Editor © 2011 by Koen Aers; made available under the EPL v1.0
- 44. Graphiti and GMF Compared
Graphiti : GMF Runtime :
Contained API (using Extends GEF/Draw2D
GEF/Draw2D) Adds complexity but
Hides complexity at also functionality
expense of flexibility Examples and
Decent documentation documentation are
in form of tutorial available
Low cost of entry But no simple tutorials
High cost of entry
44 Graphiti and GMF Compared : Revisiting the Graph Editor © 2011 by Koen Aers; made available under the EPL v1.0
- 45. Graphiti and GMF Compared
Which way do I go?
GMF Tools:
Quick kickstart
Easy entry to learn about the GMF Runtime
Almost always continues with modifying generated code
Graphiti
Quick kickstart
Probably you will meet some limitations
GMF Runtime
Getting started is difficult, lack of docs
Complete flexibility as Draw2D and GEF is at your fingertips
=> It depends
45 Graphiti and GMF Compared : Revisiting the Graph Editor © 2011 by Koen Aers; made available under the EPL v1.0
- 46. Conclusion
Implementing a graph editor has become less tedious!
No GEF/Draw2D boiler plate code anymore
GMF Tools: generative approach
Graphiti: contained API using well-defined services
GMF Runtime: contributing services making use of
preimplemented defaults and helpers
46 Graphiti and GMF Compared : Revisiting the Graph Editor © 2011 by Koen Aers; made available under the EPL v1.0
- 47. Questions?
47 Graphiti and GMF Compared : Revisiting the Graph Editor © 2011 by Koen Aers; made available under the EPL v1.0