Changes for page Graphical Modeling with Graphiti
Last modified by msp on 2025/01/30 12:03
From version 8.1
edited by msp
on 2012/11/06 16:47
on 2012/11/06 16:47
Change comment:
There is no comment for this version
Summary
-
Page properties (2 modified, 0 added, 0 removed)
-
Attachments (0 modified, 2 added, 0 removed)
-
Objects (1 modified, 0 added, 0 removed)
Details
- Page properties
-
- Parent
-
... ... @@ -1,0 +1,1 @@ 1 +Tutorials - Content
-
... ... @@ -62,7 +62,7 @@ 62 62 1. Include the new plugin in your Eclipse run configuration and start it. Create a Turing Machine diagram with your new wizard: //File//→ //New//→ //Other...//→ //Other//→ //Turing Machine//. This opens a Graphiti diagram editor for the new file, but you cannot do anything in that editor, since the palette is still empty. 63 63 1. In order to open a previously created {{code language="none"}}tudi{{/code}} file, right-click it → //Open With//→ //Other...//→ //Graphiti Diagram Editor//. This setting for {{code language="none"}}tudi{{/code}} files will be saved in your workspace preferences. 64 64 65 -= Creating and Adding Elements =65 += Creating and Adding Shapes = 66 66 67 67 The next step is to write so-called //features// for creating and adding elements to the diagrams. Each type of graphical element requires a //create// feature for the creation of corresponding meta model (//business model//) elements, and an //add// feature for adding a specific graphical representation to the diagram. A graphical representation is modeled with a so-called //pictogram element//, which contains a structure of //graphics algorithms// that specify how the element is rendered. 68 68 ... ... @@ -142,7 +142,7 @@ 142 142 {{/code}} 143 143 ))) 144 144 1. ((( 145 -Add the following feature class to your plugin and implement the {{code language="none"}}add{{/code}} method: 145 +Add the following feature class to your plugin and implement the {{code language="none"}}add{{/code}} method at the TODO note: 146 146 147 147 {{code theme="Eclipse" language="java"}} 148 148 import org.eclipse.graphiti.features.IFeatureProvider; ... ... @@ -188,8 +188,9 @@ 188 188 ContainerShape containerShape = Graphiti.getPeCreateService().createContainerShape( 189 189 context.getTargetContainer(), true); 190 190  191 - // TODO specify the concrete representation by adding at least one graphics algorithm 192 - 191 + // TODO specify the concrete representation by adding at least one graphics algorithm to the shape 192 +  193 + Graphiti.getPeCreateService().createChopboxAnchor(containerShape); 193 193 link(containerShape, context.getNewObject()); 194 194 return containerShape; 195 195 } ... ... @@ -217,4 +217,177 @@ 217 217 } 218 218 {{/code}} 219 219 ))) 220 -1. Test the features in the diagram editor. You should now be able to select "State" in the editor's palette. Use this to create a few states. Note that if you create a state and later change the graphical representation in StateAddFeature, the previously created state will still look the same, since the add feature code is only applied to new states created from the palette. 221 +1. Test the features in the diagram editor. You should now be able to select "State" in the editor's palette. Use this to create a few states. Note that if you create a state and later change the graphical representation in {{code language="none"}}StateAddFeature{{/code}}, the previously created state will still look the same, since the add feature code is only applied to new states created from the palette. 222 + 223 += Creating and Adding Connections = 224 + 225 +While states can be represented as simple shapes, transitions are connections between two shapes. The process of creating such connections is similar to that for shapes. 226 + 227 +1. ((( 228 +Add the following feature class to your plugin, adapting references to meta model elements to your Turing Machine definition and implementing the TODO part: 229 + 230 +{{code theme="Eclipse" language="java"}} 231 +import org.eclipse.graphiti.features.IFeatureProvider; 232 +import org.eclipse.graphiti.features.context.ICreateConnectionContext; 233 +import org.eclipse.graphiti.features.context.impl.AddConnectionContext; 234 +import org.eclipse.graphiti.features.impl.AbstractCreateConnectionFeature; 235 +import org.eclipse.graphiti.mm.pictograms.Anchor; 236 +import org.eclipse.graphiti.mm.pictograms.Connection; 237 + 238 +import de.cau.cs.rtprak.login.turingmodel.State; 239 +import de.cau.cs.rtprak.login.turingmodel.Transition; 240 +import de.cau.cs.rtprak.login.turingmodel.TuringFactory; 241 + 242 +/** 243 + * A create feature for Turing Machine transitions. 244 + * 245 + * @author msp 246 + */ 247 +public class TransitionCreateFeature extends AbstractCreateConnectionFeature { 248 + 249 + /** 250 + * Constructor for a transition create feature. 251 + * 252 + * @param fp the feature provider for which the feature is created 253 + */ 254 + public TransitionCreateFeature(IFeatureProvider fp) { 255 + super(fp, "Transition", "Create a Transition"); 256 + } 257 + 258 + /** 259 + * Retrieve the state linked with the given anchor's parent. 260 + * 261 + * @param anchor an anchor for the source or target of the new connection 262 + * @return the corresponding state, or {@code null} if there is none 263 + */ 264 + private State getState(Anchor anchor) { 265 + if (anchor != null) { 266 + Object object = getBusinessObjectForPictogramElement(anchor.getParent()); 267 + if (object instanceof State) { 268 + return (State) object; 269 + } 270 + } 271 + return null; 272 + } 273 + 274 + /** 275 + * {@inheritDoc} 276 + */ 277 + public boolean canStartConnection(ICreateConnectionContext context) { 278 + return getState(context.getSourceAnchor()) != null; 279 + } 280 + 281 + /** 282 + * {@inheritDoc} 283 + */ 284 + public boolean canCreate(ICreateConnectionContext context) { 285 + return getState(context.getSourceAnchor()) != null 286 + && getState(context.getTargetAnchor()) != null; 287 + } 288 + 289 + /** 290 + * {@inheritDoc} 291 + */ 292 + public Connection create(ICreateConnectionContext context) { 293 + State source = getState(context.getSourceAnchor()); 294 + State target = getState(context.getTargetAnchor()); 295 + if (source == null || target == null) { 296 + throw new IllegalStateException("Cannot retrieve the source or target."); 297 + } 298 + 299 + // TODO create new transition with the specified source and target state 300 + 301 + AddConnectionContext addContext = new AddConnectionContext(context.getSourceAnchor(), 302 + context.getTargetAnchor()); 303 + addContext.setNewObject(transition); 304 + return (Connection) getFeatureProvider().addIfPossible(addContext); 305 + } 306 + 307 +} 308 +{{/code}} 309 +))) 310 +1. ((( 311 +Add the following method to {{code language="none"}}TuringFeatureProvider{{/code}}, adding more content to the diagram editor's palette: 312 + 313 +{{code theme="Eclipse" language="java"}} 314 +/** 315 + * {@inheritDoc} 316 + */ 317 +@Override 318 +public ICreateConnectionFeature[] getCreateConnectionFeatures() { 319 + return new ICreateConnectionFeature[] { new TransitionCreateFeature(this) }; 320 +} 321 +{{/code}} 322 +))) 323 +1. ((( 324 +Add the following feature class to your plugin and implement the {{code language="none"}}add{{/code}} method at the TODO note: 325 + 326 +{{code theme="Eclipse" language="java"}} 327 +import org.eclipse.graphiti.features.IFeatureProvider; 328 +import org.eclipse.graphiti.features.context.IAddConnectionContext; 329 +import org.eclipse.graphiti.features.context.IAddContext; 330 +import org.eclipse.graphiti.features.impl.AbstractAddFeature; 331 +import org.eclipse.graphiti.mm.pictograms.Connection; 332 +import org.eclipse.graphiti.mm.pictograms.PictogramElement; 333 +import org.eclipse.graphiti.services.Graphiti; 334 +import org.eclipse.graphiti.services.IGaService; 335 + 336 +import de.cau.cs.rtprak.login.turingmodel.Transition; 337 + 338 +/** 339 + * An add feature for Turing Machine transitions. 340 + * 341 + * @author msp 342 + */ 343 +public class TransitionAddFeature extends AbstractAddFeature { 344 + 345 + /** 346 + * Constructor for a transition add feature. 347 + * 348 + * @param fp the feature provider for which the feature is created 349 + */ 350 + public TransitionAddFeature(IFeatureProvider fp) { 351 + super(fp); 352 + } 353 + 354 + /** 355 + * {@inheritDoc} 356 + */ 357 + public boolean canAdd(IAddContext context) { 358 + return context instanceof IAddConnectionContext 359 + && context.getNewObject() instanceof Transition; 360 + } 361 + 362 + /** 363 + * {@inheritDoc} 364 + */ 365 + public PictogramElement add(IAddContext context) { 366 + IAddConnectionContext addConnContext = (IAddConnectionContext) context; 367 + Connection connection = Graphiti.getPeCreateService().createFreeFormConnection(getDiagram()); 368 + connection.setStart(addConnContext.getSourceAnchor()); 369 + connection.setEnd(addConnContext.getTargetAnchor()); 370 + 371 + // TODO specify the concrete representation by adding at least one graphics algorithm to the connection 372 + 373 + link(connection, context.getNewObject()); 374 + return connection; 375 + } 376 + 377 +} 378 +{{/code}} 379 + 380 +Use {{code language="none"}}Graphiti.getGaService(){{/code}} to get a service class for creating graphics algorithms and modifying their properties. You are free to design your model elements as you like. Find more information on how to solve this task in the official [[Graphiti Tutorial>>url:http://help.eclipse.org/juno/nav/23_1||shape="rect"]]. 381 +))) 382 +1. Register the {{code language="none"}}TransitionAddFeature{{/code}} in the {{code language="none"}}getAddFeature{{/code}} method of the {{code language="none"}}TuringFeatureProvider{{/code}} in the same way as done before for the {{code language="none"}}StateAddFeature{{/code}}. 383 +1. Test the features in the diagram editor. The palette should now contain an entry for creating transitions. 384 + 385 += Handling Text Labels = 386 + 387 +The last section of this tutorial is about text labels in the graphical editor. We will use such labels for displaying state names. The steps required for these tasks are given only coarsely here, since you should now be able to find out yourself about the details using the [[Graphiti documentation>>url:http://www.eclipse.org/graphiti/documentation/||shape="rect"]]. 388 + 389 +1. Add a {{code language="none"}}Text{{/code}} element to states in the {{code language="none"}}StateAddFeature{{/code}} in order to display the name of each state. 390 +1. Create a new class {{code language="none"}}StateDirectEditingFeature{{/code}} extending {{code language="none"}}AbstractDirectEditingFeature{{/code}} and register it by overriding {{code language="none"}}getDirectEditingFeature{{/code}} in the {{code language="none"}}TuringFeatureProvider{{/code}}. This new feature is responsible for connecting the name attribute of states with the in-diagram text editing box, i.e. retrieving the current text from the attribute and updating it after the user has entered a new value. 391 +1. Create a new class {{code language="none"}}StateUpdateFeature{{/code}} extending {{code language="none"}}AbstractUpdateFeature{{/code}} and register it by overriding {{code language="none"}}getUpdateFeature{{/code}} in the {{code language="none"}}TuringFeatureProvider{{/code}}. This new feature is responsible for updating the displayed text when the corresponding attribute in the domain model is changed outside the Graphiti editor. For example you could open the Turing Machine model with the //Sample Reflective Ecore Model Editor //in order to modify attributes. You can activate automatic updates of the diagram by extending {{code language="none"}}isAutoUpdateAtRuntime{{/code}} (resp. {{code language="none"}}Startup{{/code}} / {{code language="none"}}Reset{{/code}}) in the {{code language="none"}}TuringDiagramTypeProvider{{/code}} and returning {{code language="none"}}true{{/code}}. The update feature can be invoked explicitly in other features by calling the superclass method {{code language="none"}}updatePictogramElement{{/code}}. 392 +1. Create a new class {{code language="none"}}StateLayoutFeature{{/code}} extending {{code language="none"}}AbstractLayoutFeature{{/code}} and register it by overriding {{code language="none"}}getLayoutFeature{{/code}} in the {{code language="none"}}TuringFeatureProvider{{/code}}. This new feature is responsible for updating the position and size of graphics algorithms of a state when the state is resized in the graphical editor or when the displayed text for the state name is updated. The layout feature can be invoked explicitly in other features by calling the superclass method {{code language="none"}}layoutPictogramElement{{/code}}. 393 + 394 +Implement all created feature classes such that the editor behaves correctly when state names are modified or states are resized. You should aim for a good look-and-feel of your Turing Machine editor. If you like, you may also implement transition labels for displaying triggers and actions of transitions (not required for finishing the tutorial).
- CreationWizardPage.java
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.XWikiGuest - Size
-
... ... @@ -1,0 +1,1 @@ 1 +5.6 KB - Content
-
... ... @@ -1,0 +1,177 @@ 1 +/* 2 + * KIELER - Kiel Integrated Environment for Layout Eclipse RichClient 3 + * 4 + * http://www.informatik.uni-kiel.de/rtsys/kieler/ 5 + * 6 + * Copyright 2010 by 7 + * + Christian-Albrechts-University of Kiel 8 + * + Department of Computer Science 9 + * + Real-Time and Embedded Systems Group 10 + * 11 + * This code is provided under the terms of the Eclipse Public License (EPL). 12 + * See the file epl-v10.html for the license text. 13 + */ 14 +package de.cau.cs.rtprak.turing.graphiti; 15 + 16 +import org.eclipse.core.resources.IWorkspaceRoot; 17 +import org.eclipse.core.resources.ResourcesPlugin; 18 +import org.eclipse.core.runtime.IPath; 19 +import org.eclipse.core.runtime.Path; 20 +import org.eclipse.emf.common.util.URI; 21 +import org.eclipse.jface.viewers.IStructuredSelection; 22 +import org.eclipse.jface.wizard.IWizardPage; 23 +import org.eclipse.swt.widgets.Composite; 24 +import org.eclipse.ui.dialogs.WizardNewFileCreationPage; 25 + 26 +/** 27 + * Wizard page to create diagram or model files. 28 + * 29 + * @author msp 30 + */ 31 +public class CreationWizardPage extends WizardNewFileCreationPage { 32 + 33 + /** the file extension to use for this wizard page. */ 34 + private String extension; 35 + 36 + /** 37 + * Creates a page with given settings. 38 + * 39 + * @param pageName the name of the page 40 + * @param selection the current resource selection 41 + * @param theextension the file extension 42 + */ 43 + public CreationWizardPage(final String pageName, final IStructuredSelection selection, 44 + final String theextension) { 45 + super(pageName, selection); 46 + this.extension = theextension; 47 + } 48 + 49 + /** 50 + * {@inheritDoc} 51 + */ 52 + @Override 53 + public void createControl(final Composite parent) { 54 + super.createControl(parent); 55 + setPageComplete(true); 56 + } 57 + 58 + /** 59 + * Creates a URI for the selected file path. 60 + * 61 + * @return a URI for the file 62 + */ 63 + public URI getURI() { 64 + IPath path = getContainerFullPath(); 65 + if (path == null) { 66 + path = new Path(""); 67 + } 68 + String fileName = getFileName(); 69 + if (fileName == null || fileName.length() == 0) { 70 + fileName = copyFileName(); 71 + } 72 + path = path.append(getUniqueFileName(path, fileName, extension)); 73 + return URI.createPlatformResourceURI(path.toString(), false); 74 + } 75 + 76 + /** 77 + * {@inheritDoc} 78 + */ 79 + @Override 80 + public void setVisible(final boolean visible) { 81 + if (visible && (getFileName() == null || getFileName().length() == 0)) { 82 + setFileName(getUniqueFileName(getContainerFullPath(), copyFileName(), extension)); 83 + } 84 + super.setVisible(visible); 85 + } 86 + 87 + private String copyFileName() { 88 + String fileName = null; 89 + IWizardPage previousPage = getPreviousPage(); 90 + if (previousPage instanceof CreationWizardPage) { 91 + CreationWizardPage copyPage = (CreationWizardPage) previousPage; 92 + fileName = copyPage.getFileName(); 93 + if (fileName.endsWith(copyPage.extension)) { 94 + fileName = fileName.substring(0, fileName.length() 95 + - (copyPage.extension.length() + 1)); 96 + } 97 + } 98 + return fileName; 99 + } 100 + 101 + /** 102 + * Creates a unique file name. 103 + * 104 + * @param containerFullPath the container full path, or {@code null} 105 + * @param fileName the initial file name, or {@code null} 106 + * @param extension the required file extension 107 + * @return a unique file name 108 + */ 109 + private static String getUniqueFileName(final IPath containerFullPath, final String fileName, 110 + final String extension) { 111 + IPath contPath = containerFullPath == null ? new Path("") : containerFullPath; 112 + String name = (fileName == null || fileName.trim().length() == 0) ? "default" : fileName; 113 + IPath filePath = contPath.append(name); 114 + if (extension.equals(filePath.getFileExtension())) { 115 + name = name.substring(0, name.length() - (extension.length() + 1)); 116 + } else { 117 + filePath = filePath.addFileExtension(extension); 118 + } 119 + IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot(); 120 + if (workspaceRoot.exists(filePath)) { 121 + int x = getNumber(name); 122 + if (x >= 0) { 123 + name = name.substring(0, name.length() - digits(x)); 124 + } else { 125 + x = 0; 126 + } 127 + do { 128 + x++; 129 + String newName = name + x + "." + extension; 130 + filePath = filePath.append(newName); 131 + } while (workspaceRoot.exists(filePath)); 132 + } 133 + return filePath.lastSegment(); 134 + } 135 + 136 + /** 137 + * Returns the greatest number that is a suffix of the given string. 138 + * 139 + * @param string a string 140 + * @return a suffix number, of -1 if the string has no such suffix 141 + */ 142 + private static int getNumber(final String string) { 143 + int index = string.length(); 144 + while (index > 0 && Character.isDigit(string.charAt(index - 1))) { 145 + index--; 146 + } 147 + if (index < string.length()) { 148 + try { 149 + return Integer.parseInt(string.substring(index)); 150 + } catch (NumberFormatException exception) { 151 + // ignore exception and return 0 152 + } 153 + } 154 + return -1; 155 + } 156 + 157 + /** the base for integer numbers. */ 158 + private static final int BASE = 10; 159 + 160 + /** 161 + * Returns the number of digits of a number. 162 + * 163 + * @param x an integer number 164 + * @return the number of digits of x 165 + */ 166 + private static int digits(final int x) { 167 + int digits = 1; 168 + int a = x; 169 + while (a >= BASE) { 170 + a /= BASE; 171 + digits++; 172 + } 173 + return digits; 174 + } 175 + 176 +} 177 +
- GraphitiNewWizard.java
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.XWikiGuest - Size
-
... ... @@ -1,0 +1,1 @@ 1 +13.8 KB - Content
-
... ... @@ -1,0 +1,362 @@ 1 +/* 2 + * KIELER - Kiel Integrated Environment for Layout Eclipse RichClient 3 + * 4 + * http://www.informatik.uni-kiel.de/rtsys/kieler/ 5 + * 6 + * Copyright 2010 by 7 + * + Christian-Albrechts-University of Kiel 8 + * + Department of Computer Science 9 + * + Real-Time and Embedded Systems Group 10 + * 11 + * This code is provided under the terms of the Eclipse Public License (EPL). 12 + * See the file epl-v10.html for the license text. 13 + */ 14 +package de.cau.cs.rtprak.turing.graphiti; 15 + 16 +import java.io.IOException; 17 +import java.lang.reflect.InvocationTargetException; 18 +import java.util.HashMap; 19 +import java.util.Map; 20 + 21 +import org.eclipse.core.resources.IFile; 22 +import org.eclipse.core.resources.IResource; 23 +import org.eclipse.core.resources.ResourcesPlugin; 24 +import org.eclipse.core.runtime.CoreException; 25 +import org.eclipse.core.runtime.IProgressMonitor; 26 +import org.eclipse.core.runtime.IStatus; 27 +import org.eclipse.core.runtime.NullProgressMonitor; 28 +import org.eclipse.core.runtime.Path; 29 +import org.eclipse.core.runtime.Status; 30 +import org.eclipse.emf.common.command.CommandStack; 31 +import org.eclipse.emf.common.util.URI; 32 +import org.eclipse.emf.ecore.EObject; 33 +import org.eclipse.emf.ecore.resource.Resource; 34 +import org.eclipse.emf.ecore.resource.ResourceSet; 35 +import org.eclipse.emf.ecore.xmi.XMLResource; 36 +import org.eclipse.emf.transaction.RecordingCommand; 37 +import org.eclipse.emf.transaction.TransactionalEditingDomain; 38 +import org.eclipse.emf.workspace.util.WorkspaceSynchronizer; 39 +import org.eclipse.graphiti.mm.pictograms.Diagram; 40 +import org.eclipse.graphiti.mm.pictograms.PictogramLink; 41 +import org.eclipse.graphiti.mm.pictograms.PictogramsFactory; 42 +import org.eclipse.graphiti.services.Graphiti; 43 +import org.eclipse.graphiti.ui.services.GraphitiUi; 44 +import org.eclipse.jface.operation.IRunnableWithProgress; 45 +import org.eclipse.jface.viewers.IStructuredSelection; 46 +import org.eclipse.jface.wizard.Wizard; 47 +import org.eclipse.ui.INewWizard; 48 +import org.eclipse.ui.IWorkbench; 49 +import org.eclipse.ui.IWorkbenchPage; 50 +import org.eclipse.ui.PartInitException; 51 +import org.eclipse.ui.actions.WorkspaceModifyOperation; 52 +import org.eclipse.ui.part.FileEditorInput; 53 +import org.eclipse.ui.statushandlers.StatusManager; 54 + 55 +/** 56 + * A generic wizard for creation of new Graphiti diagrams. 57 + * 58 + * @author msp 59 + */ 60 +public abstract class GraphitiNewWizard extends Wizard implements INewWizard { 61 + 62 + /** the workbench. */ 63 + private IWorkbench workbench; 64 + /** the current selection. */ 65 + private IStructuredSelection selection; 66 + /** the diagram model wizard page. */ 67 + private CreationWizardPage diagramModelFilePage; 68 + /** the domain model wizard page. */ 69 + private CreationWizardPage domainModelFilePage; 70 + /** the name of the wizard. */ 71 + private String wizardName; 72 + /** the diagram file extension. */ 73 + private String diagramFileExtension; 74 + /** the domain model file extension. */ 75 + private String domainFileExtension; 76 + /** the diagram type name of the graphiti diagram. */ 77 + private String diagramTypeName; 78 + /** the identifier of the diagram editor. */ 79 + private String editorId; 80 + /** the grid size (0 means no grid). */ 81 + private int gridSize = 0; 82 + /** the setting for snapping to grid. */ 83 + private boolean snapToGrid = false; 84 + 85 + /** 86 + * Creates a new-wizard for Graphiti, with no grid. 87 + * 88 + * @param name 89 + * the name of the wizard 90 + * @param diagExt 91 + * the diagram file extension 92 + * @param domainExt 93 + * the domain model file extension 94 + * @param thediagramTypeName 95 + * the diagram type name of the graphiti diagram 96 + */ 97 + public GraphitiNewWizard(final String name, final String diagExt, final String domainExt, 98 + final String thediagramTypeName) { 99 + this.wizardName = name; 100 + this.diagramFileExtension = diagExt; 101 + this.domainFileExtension = domainExt; 102 + this.diagramTypeName = thediagramTypeName; 103 + } 104 + 105 + /** 106 + * Creates a new-wizard for Graphiti, with no grid. 107 + * 108 + * @param name 109 + * the name of the wizard 110 + * @param diagExt 111 + * the diagram file extension 112 + * @param domainExt 113 + * the domain model file extension 114 + * @param thediagramTypeName 115 + * the diagram type of the graphiti diagram 116 + * @param theeditorId 117 + * identifier of the diagram editor, or {@code null} if no editor shall be opened 118 + * after model creation 119 + */ 120 + public GraphitiNewWizard(final String name, final String diagExt, final String domainExt, 121 + final String thediagramTypeName, final String theeditorId) { 122 + this(name, diagExt, domainExt, thediagramTypeName); 123 + this.editorId = theeditorId; 124 + } 125 + 126 + /** 127 + * Creates a new-wizard for Graphiti, with customizable grid. 128 + * 129 + * @param name 130 + * the name of the wizard 131 + * @param diagExt 132 + * the diagram file extension 133 + * @param domainExt 134 + * the domain model file extension 135 + * @param thediagramTypeName 136 + * the diagram type name of the graphiti diagram 137 + * @param theeditorId 138 + * identifier of the diagram editor, or {@code null} if no editor shall be opened 139 + * after model creation 140 + * @param thegridSize 141 + * the grid size (0 means no grid) 142 + * @param thesnapToGrid 143 + * the setting for snapping to grid 144 + */ 145 + public GraphitiNewWizard(final String name, final String diagExt, final String domainExt, 146 + final String thediagramTypeName, final String theeditorId, final int thegridSize, 147 + final boolean thesnapToGrid) { 148 + this(name, diagExt, domainExt, thediagramTypeName, theeditorId); 149 + this.gridSize = thegridSize; 150 + this.snapToGrid = thesnapToGrid; 151 + } 152 + 153 + /** 154 + * {@inheritDoc} 155 + */ 156 + public final void init(final IWorkbench theworkbench, final IStructuredSelection theselection) { 157 + this.workbench = theworkbench; 158 + this.selection = theselection; 159 + setWindowTitle("New " + wizardName + " Diagram"); 160 + setNeedsProgressMonitor(true); 161 + } 162 + 163 + /** 164 + * {@inheritDoc} 165 + */ 166 + @Override 167 + public final void addPages() { 168 + diagramModelFilePage = new CreationWizardPage("DiagramModelFile", selection, 169 + diagramFileExtension); 170 + diagramModelFilePage.setTitle("Create " + wizardName + " Diagram"); 171 + diagramModelFilePage.setDescription("Select file that will contain diagram model."); 172 + addPage(diagramModelFilePage); 173 + 174 + domainModelFilePage = new CreationWizardPage("DomainModelFile", selection, 175 + domainFileExtension); 176 + domainModelFilePage.setTitle("Create " + wizardName + " Domain Model"); 177 + domainModelFilePage.setDescription("Select file that will contain domain model."); 178 + addPage(domainModelFilePage); 179 + } 180 + 181 + /** 182 + * {@inheritDoc} 183 + */ 184 + @Override 185 + public final boolean performFinish() { 186 + IRunnableWithProgress op = new WorkspaceModifyOperation(null) { 187 + @Override 188 + protected void execute(final IProgressMonitor monitor) throws CoreException, 189 + InterruptedException { 190 + Resource diagramResource = createDiagram(diagramModelFilePage.getURI(), 191 + domainModelFilePage.getURI(), monitor); 192 + if (diagramResource != null && editorId != null) { 193 + try { 194 + openDiagram(diagramResource); 195 + } catch (PartInitException exception) { 196 + throw new CoreException(new Status(IStatus.ERROR, 197 + "de.cau.cs.rtprak.turing.graphiti", 198 + "Error opening diagram", exception)); 199 + } 200 + } 201 + } 202 + }; 203 + try { 204 + getContainer().run(false, true, op); 205 + } catch (InterruptedException exception) { 206 + return false; 207 + } catch (InvocationTargetException exception) { 208 + if (exception.getTargetException() instanceof CoreException) { 209 + StatusManager.getManager().handle(((CoreException) exception.getTargetException()), 210 + "de.cau.cs.rtprak.turing.graphiti"); 211 + } else { 212 + IStatus status = new Status(IStatus.ERROR, "de.cau.cs.rtprak.turing.graphiti", 213 + "Error creating diagram", exception.getTargetException()); 214 + StatusManager.getManager().handle(status, StatusManager.LOG); 215 + } 216 + return false; 217 + } 218 + return true; 219 + } 220 + 221 + /** 222 + * Create a diagram with given URIs. 223 + * 224 + * @param diagramURI 225 + * URI for the diagram file 226 + * @param modelURI 227 + * URI for the model file 228 + * @param progressMonitor 229 + * progress monitor 230 + * @return a resource for the new diagram file 231 + */ 232 + private Resource createDiagram(final URI diagramURI, final URI modelURI, 233 + final IProgressMonitor progressMonitor) { 234 + progressMonitor.beginTask("Creating diagram and model files", 2); 235 + // create a resource set and editing domain 236 + TransactionalEditingDomain editingDomain = GraphitiUi.getEmfService() 237 + .createResourceSetAndEditingDomain(); 238 + ResourceSet resourceSet = editingDomain.getResourceSet(); 239 + CommandStack commandStack = editingDomain.getCommandStack(); 240 + // create resources for the diagram and domain model files 241 + final Resource diagramResource = resourceSet.createResource(diagramURI); 242 + final Resource modelResource = resourceSet.createResource(modelURI); 243 + if (diagramResource != null && modelResource != null) { 244 + commandStack.execute(new RecordingCommand(editingDomain) { 245 + @Override 246 + protected void doExecute() { 247 + createModel(diagramResource, diagramURI.lastSegment(), modelResource, 248 + modelURI.lastSegment()); 249 + } 250 + }); 251 + progressMonitor.worked(1); 252 + 253 + try { 254 + modelResource.save(createSaveOptions()); 255 + diagramResource.save(createSaveOptions()); 256 + } catch (IOException exception) { 257 + IStatus status = new Status(IStatus.ERROR, "de.cau.cs.rtprak.turing.graphiti", 258 + "Unable to store model and diagram resources", exception); 259 + StatusManager.getManager().handle(status); 260 + } 261 + setCharset(WorkspaceSynchronizer.getFile(modelResource)); 262 + setCharset(WorkspaceSynchronizer.getFile(diagramResource)); 263 + } 264 + progressMonitor.done(); 265 + return diagramResource; 266 + } 267 + 268 + /** 269 + * Creates save options for the resources. 270 + * 271 + * @return new save options 272 + */ 273 + public static Map<?, ?> createSaveOptions() { 274 + HashMap<String, Object> saveOptions = new HashMap<String, Object>(); 275 + saveOptions.put(XMLResource.OPTION_ENCODING, "UTF-8"); //$NON-NLS-1$ 276 + saveOptions.put(Resource.OPTION_SAVE_ONLY_IF_CHANGED, 277 + Resource.OPTION_SAVE_ONLY_IF_CHANGED_MEMORY_BUFFER); 278 + return saveOptions; 279 + } 280 + 281 + /** 282 + * Set the character set for the given file to UTF-8. 283 + * 284 + * @param file 285 + * a file 286 + */ 287 + public static void setCharset(final IFile file) { 288 + try { 289 + if (file != null) { 290 + file.setCharset("UTF-8", new NullProgressMonitor()); 291 + } 292 + } catch (CoreException e) { 293 + StatusManager.getManager().handle(e, "de.cau.cs.rtprak.turing.graphiti"); 294 + } 295 + } 296 + 297 + /** 298 + * Open the diagram from the given resource. 299 + * 300 + * @param diagramResource 301 + * a resource for a diagram file 302 + * @throws PartInitException 303 + * if the diagram could not be opened 304 + */ 305 + private void openDiagram(final Resource diagramResource) throws PartInitException { 306 + String path = diagramResource.getURI().toPlatformString(true); 307 + IResource workspaceResource = ResourcesPlugin.getWorkspace().getRoot() 308 + .findMember(new Path(path)); 309 + if (workspaceResource instanceof IFile) { 310 + IWorkbenchPage page = workbench.getActiveWorkbenchWindow().getActivePage(); 311 + page.openEditor(new FileEditorInput((IFile) workspaceResource), editorId); 312 + } 313 + } 314 + 315 + /** 316 + * Create a model in the given resources. 317 + * 318 + * @param diagramResource 319 + * resource for the diagram model 320 + * @param diagramName 321 + * name of the diagram model 322 + * @param modelResource 323 + * resource for the domain model 324 + * @param modelName 325 + * name of the domain model 326 + */ 327 + private void createModel(final Resource diagramResource, final String diagramName, 328 + final Resource modelResource, final String modelName) { 329 + modelResource.setTrackingModification(true); 330 + EObject domainModel = createModel(modelName); 331 + modelResource.getContents().add(domainModel); 332 + diagramResource.setTrackingModification(true); 333 + Diagram diagram = Graphiti.getPeCreateService().createDiagram(diagramTypeName, diagramName, 334 + gridSize, snapToGrid); 335 + PictogramLink link = PictogramsFactory.eINSTANCE.createPictogramLink(); 336 + link.setPictogramElement(diagram); 337 + link.getBusinessObjects().add(domainModel); 338 + configureDiagram(diagram); 339 + diagramResource.getContents().add(diagram); 340 + } 341 + 342 + /** 343 + * Configure the diagram. May be overridden by subclasses. 344 + * 345 + * @param diagram 346 + * the top-level element of the pictogram model 347 + */ 348 + protected void configureDiagram(final Diagram diagram) { 349 + // the default implementation does nothing 350 + } 351 + 352 + /** 353 + * Create an instance of the top-level object for the domain model. 354 + * 355 + * @param name 356 + * name of the model 357 + * @return an instance of the domain model object 358 + */ 359 + protected abstract EObject createModel(final String name); 360 + 361 +} 362 +
- Confluence.Code.ConfluencePageClass[0]
-
- Id
-
... ... @@ -1,1 +1,1 @@ 1 -36045 831 +3604565 - URL
-
... ... @@ -1,1 +1,1 @@ 1 -https://rtsys.informatik.uni-kiel.de/confluence//wiki/spaces/WS12EclPract/pages/36045 83/Graphical Modeling with Graphiti1 +https://rtsys.informatik.uni-kiel.de/confluence//wiki/spaces/WS12EclPract/pages/3604565/Graphical Modeling with Graphiti