Skip to main content
Jump to: navigation, search

Papyrus/Papyrus Developer Guide/CreateProgrammatically

< Papyrus‎ | Papyrus Developer Guide
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

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.

Back to the top