Notice: This Wiki is now read only and edits are no longer possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.
Papyrus/Papyrus Developer Guide/CreateProgrammatically
Create graphical elements programmatically
It is possible to create graphical elements programmatically. You need to obtain first a reference to an existing graphical view, for instance to obtain a reference to the current diagram in an Eclipse handler.
// event is an ExecutionEvent passed to an Eclipse handler
ISashWindowsContainer windowsContainer = ServiceUtilsForHandlers.getInstance().getISashWindowsContainer(event);
Object model = windowsContainer.getActiveSashWindowsPage().getRawModel();
if(model instanceof PageRef) {
EObject diagramEObj = ((PageRef)model).getEmfPageIdentifier();
if(diagramEObj instanceof Diagram) {
Diagram diagram = (Diagram)diagramEObj;
...
The Interfaces Diagram, Edge, View and Node can be found in the package org.eclipse.gmf.runtime.notation.
Once the diagram is recovered, you can use the UMLViewProvider of a specific diagram to create new elements within. In general, you need to create a UML element first and then use the provider to create the associated view. For instance, if you want to create a view for a lifeLine within a sequence diagram, you can use the following code. Note that the lifeline is not placed directly into the passed interaction view. Instead, the interaction view has a child corresponding to its compartment.
/**
* Add a lifeline view for a given UML lifeline within an interaction view
* @param lifeline the UML lifeline
* @param interactionView the view associated with the interaction
* @param x layout hint
* @param y layout hint
* @return the created view
*/
public View addLifeline(Lifeline lifeline, View interactionView, int x, int y)
{
// get first compartment of view
Object compartment = interactionView.getChildren().get(1);
// use the generic view service to create views This is a bit cleaner than using specific operations of the sequence-diagram view
// provider (as we do below for the message)
final String nodeType =
UMLVisualIDRegistry.getType( org.eclipse.papyrus.uml.diagram.sequence.edit.parts.LifelineEditPart.VISUAL_ID);
Node lifelineView =
ViewService.createNode((View) compartment, lifeline, nodeType, UMLDiagramEditorPlugin.DIAGRAM_PREFERENCES_HINT);
Bounds location = NotationFactory.eINSTANCE.createBounds();
location.setX(x);
location.setY(40);
if(lifelineView instanceof Node) {
((Node)lifelineView).setLayoutConstraint(location);
}
return lifelineView;
}
The interaction has a single compartment. Other graphical elements like classes have severals (you can find out via the filters->show/hide compartment dialog). In this case, you need to make sure to obtain the right one.
Edges (lines) are created in a similar way, for instance a message betweeen two lifelines can be added with the following function. It is typically required to set source and target.
/**
* Add a message view for a given UML message within a given diagram
* @param message UML message
* @param diagram Sequence diagram
* @param lifelineSrcV view of source lifeline
* @param lifelineDstV view of destination lifeline
*/
public void addMessage(Message message, Diagram diagram, View lifelineSrcV, View lifelineDstV)
{
View messageView = sequenceDiagViewProvider.createMessage_4004(message, diagram, -1, true,
UMLDiagramEditorPlugin.DIAGRAM_PREFERENCES_HINT);
if(messageView instanceof Edge) {
((Edge)messageView).setSource(lifelineSrcV);
((Edge)messageView).setTarget(lifelineDstV);
}
}
The whole plugin, called org.eclipse.papyrus.uml.diagram.example.programmaticcreation, can be found in the Papyrus git. The plugin provides commands that create two lifelines and a message in a sequence diagram and a collaboration use in a composite diagram (when a composite class is selected). If you use the plugin, you have to create the respective diagram first as usual and then call commands from the context menu (sub-menu "Test diagram creation") to call code that programmatically adds elements to UML and the diagram.
Caveat: the example is very simple and does not check whether the user invokes the creation of lifelines in the context of an interaction within a sequence diagram or an interaction within another diagram. The lifeline example only works for interactions within a sequence diagram, the collaboration-use example only for composite classes within a composite structure diagram.