Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » Papyrus » How to create diagram elements programatically
How to create diagram elements programatically [message #696191] Wed, 13 July 2011 13:09 Go to next message
Neslepaks  is currently offline Neslepaks
Messages: 37
Registered: April 2011
Member
Hi,

I would need to create diagram element after triggering an action and I am wondering how to do that.

I have tried to read the simplediagram example code from Papyrus SVN but I don't understand how to do that. I suppose the ComponentCreateCommand could the key to find out the mechanism but I feel it's quite complex.

Is there a simpler (more readable) way to do that?

[Updated on: Wed, 13 July 2011 13:16]

Report message to a moderator

Re: How to create diagram elements programatically [message #698903 is a reply to message #696191] Wed, 20 July 2011 12:47 Go to previous messageGo to next message
Miriam  is currently offline Miriam
Messages: 29
Registered: April 2011
Junior Member
Hi,
When exporting the simplediagram project from the svn, you can find in the folder docs a tutorial. I tried it myself, but I have some errors. I tried to export the siplediagram into a .jar and i put it in the plugin folder of eclipse, but nothing appears when I want to create a new diagram with a "simplediagram" type.
Please could anyone help us with this? we are two now facing the same problem...
Thanks

Miriam
Re: How to create diagram elements programatically [message #701732 is a reply to message #698903] Mon, 25 July 2011 14:02 Go to previous messageGo to next message
Amine EL KOUHEN is currently offline Amine EL KOUHEN
Messages: 2
Registered: July 2011
Junior Member
Hi All,

Neslepaks : The code that you tried to read is a generated code from the file .GMFGEN of the SampleDiagram. To read and understand this code users need to know GMF and GEF framworks, and the architecture of Papyrus.

For GMF : http: // wiki.eclipse.org / GMF_Documentation_Index#Overview_2
For Papyrus : {the SVN repository/trunk}\doc\DevelopperDocuments\architecture

Miriam : Try to check the version of GMF required in the tutorial and compare it to your environment.

Contact me if you have any problem.

Amine
Re: How to create diagram elements programatically [message #701740 is a reply to message #701732] Mon, 25 July 2011 14:12 Go to previous messageGo to next message
Miriam  is currently offline Miriam
Messages: 29
Registered: April 2011
Junior Member
I tried the tutorial in indigo, I could make it it run, but I had to change a lot of things (imports in the major cases).
still, I have an other question please, can I modify the sequence diagram gmf files in the model folder, that I could have as a result a sequence diagram with an additional component? or can I modify the state invariant behavior (I need to make it cover several lifelines)?
Thanks a lot
Re: How to create diagram elements programatically [message #703394 is a reply to message #701732] Wed, 27 July 2011 14:26 Go to previous messageGo to next message
Neslepaks  is currently offline Neslepaks
Messages: 37
Registered: April 2011
Member
Ok, thanks for the links. I'll try check if can find any help from there.
Of course the knowledge of frameworks and architectures
would be useful, but at this point, any kind of relevant code snippet would
be helpful.

For me, it seems that most of the GMF tutorials concentrate on how to
generate a graphical editor. I don't need to make a whole new editor
but just to add, for example, an action to main toolbar that
creates a diagram element to opened diagram. I have also read PapyrusDevelopperTutorial_OnDiagramCreating.odt and wonder if there is any help of the GMF wizards on such a task.

The following code is what I've been able to made but I am not sure if I'm on the right path:

CreateElementRequest req = new CreateElementRequest(UMLElementTypes.Component_2001);

IProgressMonitor monitor = null;
IAdaptable info = null;

ComponentCreateCommand ccc = new ComponentCreateCommand(req);
try {
	ccc.doExecuteWithResult(monitor,info);
} catch (ExecutionException e1) {
	e1.printStackTrace();
}


Then I have the ComponentCreateCommand.java from org.eclipse.papyrus.example.diagram.simplediagram.edit.commands
and the most relevant part of the class is the function

public CommandResult doExecuteWithResult(IProgressMonitor monitor,
		IAdaptable info) throws ExecutionException {

	Component newElement = UMLFactory.eINSTANCE.createComponent();

	Package owner = (Package) getElementToEdit();
	owner.getPackagedElements().add(newElement);
		
	//doConfigure(newElement, monitor, info);

	((CreateElementRequest) getRequest()).setNewElement(newElement);
	return CommandResult.newOKCommandResult(newElement);
}


The problem in this, is that the line owner.getPackagedElements().add(newElement); throws a NullPointerException. Does anyone have ideas how to get rid of that or is the line even needed?

Also is it necessary to initialize IProgressMonitor and IAdaptable to something else than null as they are used in doConfigure?
Re: How to create diagram elements programatically [message #704295 is a reply to message #703394] Thu, 28 July 2011 13:24 Go to previous messageGo to next message
Neslepaks  is currently offline Neslepaks
Messages: 37
Registered: April 2011
Member
And another approach:

I found this page that seems quite relevant to my problem and at least the code part looks quite promising.

http://wiki.eclipse.org/Graphical_Modeling_Framework/Tutorial/Part_3

I made the following changes to the code example to get it running.

I have the selectedElement defined like this:
private ShapeNodeEditPart selectedElement;


And the modified source code:

CompoundCommand cc = new CompoundCommand("Create component");
		
//next line changed 
CreateViewRequest topicRequest = CreateViewRequestFactory.getCreateShapeRequest(UMLElementTypes.Component_2001, selectedElement.getDiagramPreferencesHint());

//this part is mostly useless but least the element should get some location
Point p = selectedElement.getFigure().getBounds().getTopRight().getCopy();
topicRequest.setLocation(p.translate(100, 100));
				
//next line changed MapEditPart to DiagramEditPart
DiagramEditPart mapEditPart = (DiagramEditPart) selectedElement.getParent();
Command createTopicCmd = mapEditPart.getCommand(topicRequest);
		
cc.add(createTopicCmd);

selectedElement.getDiagramEditDomain().getDiagramCommandStack().execute(cc);


I can get the code running but I cannot see any added elements on the diagram. Is this a Papyrus related problem or am I doing something wrong?

Also I found out that someone here was facing a similar problem:
http://www.eclipse.org/forums/index.php/m/107284/
So should I wrap my code into some kind of a transaction?
Re: How to create diagram elements programatically [message #717222 is a reply to message #704295] Fri, 19 August 2011 15:54 Go to previous messageGo to next message
Neslepaks  is currently offline Neslepaks
Messages: 37
Registered: April 2011
Member
Somehow I managed to do that successfully. I'll report later how.
Re: How to create diagram elements programatically [message #717730 is a reply to message #696191] Mon, 22 August 2011 07:55 Go to previous messageGo to next message
Neslepaks  is currently offline Neslepaks
Messages: 37
Registered: April 2011
Member
I guess the example could be simpler but hopefully this is useful as well. This works with a class diagram.

Some attributes:
/** The diagram editor. */
protected UMLDiagramEditor diagramEditor=null;

/** The clazzdiagramedit part. */
protected DiagramEditPart clazzdiagrameditPart;



/** The papyrus editor. */
protected PapyrusMultiDiagramEditor papyrusEditor;




The code:
IEditorPart editorPart = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getActiveEditor();
papyrusEditor =((PapyrusMultiDiagramEditor)editorPart);

EObject model = null;
try {
			
	//get root element
	model = UmlUtils.getUmlModel().lookupRoot();
	} catch (org.eclipse.papyrus.resource.NotFoundException e) {
	e.printStackTrace();
}

//it is possible to add new elements to packages
final org.eclipse.uml2.uml.Package modelpackage = (org.eclipse.uml2.uml.Package) model;

//Add new class to model
TransactionalEditingDomain ted = TransactionUtil.getEditingDomain(model);
ted.getCommandStack().execute(new RecordingCommand(ted) {
	protected void doExecute() {
		modelpackage.createOwnedClass("ClassName", true);
	}
});


//Make some checks and place the new class to diagram.
for(int i = 0; i < modelpackage.getOwnedElements().size(); ++i)
{
	if( modelpackage.getOwnedElements().get(i) instanceof org.eclipse.uml2.uml.Class )
	{
		org.eclipse.uml2.uml.Class c = (org.eclipse.uml2.uml.Class) modelpackage.getOwnedElements().get(i);
		if( c instanceof NamedElement)
		{
			NamedElement ne = c;
			if (ne.getName().equals("ClassName"))
			{
				Object object = c;

				//add the new class element to diagram
				DropObjectsRequest dropObjectsRequest = new DropObjectsRequest();
				ArrayList list = new ArrayList();
				list.add((org.eclipse.uml2.uml.Element)object);
				dropObjectsRequest.setObjects(list);
				dropObjectsRequest.setLocation(new Point(20,100));
				Command commandDrop = getDiagramEditPart().getCommand(dropObjectsRequest);
				diagramEditor.getDiagramEditDomain().getDiagramCommandStack().execute(commandDrop);
			}
		}
	}
}



And also a function used in the code above:
protected DiagramEditPart getDiagramEditPart()
{

	diagramEditor = (UmlClassDiagramForMultiEditor)papyrusEditor.getActiveEditor();
	clazzdiagrameditPart = (DiagramEditPart)diagramEditor.getGraphicalViewer().getEditPartRegistry().get(diagramEditor.getDiagram());
	return clazzdiagrameditPart;

}

[Updated on: Mon, 22 August 2011 12:04]

Report message to a moderator

Re: How to create diagram elements programatically [message #725551 is a reply to message #717730] Thu, 15 September 2011 07:01 Go to previous messageGo to next message
Yang Liu is currently offline Yang Liu
Messages: 9
Registered: June 2010
Junior Member
Hi Neslepaks,


Your work is valuable for me. But this will not draw property editpart together if there is some property of that class.

Maybe can use ClassAttributeCompartmentEditPart to replace DiagramEditPart to get drop command? For the ClassEditPart is just generated with command, and there is no return value. Can I use EMF listener and notification to get ClassAttributeCompartmentEditPart?

Thanks.


Re: How to create diagram elements programatically [message #725590 is a reply to message #725551] Thu, 15 September 2011 09:52 Go to previous messageGo to next message
Neslepaks  is currently offline Neslepaks
Messages: 37
Registered: April 2011
Member
LiuYang wrote on Thu, 15 September 2011 03:01
Hi Neslepaks,


Your work is valuable for me. But this will not draw property editpart together if there is some property of that class.

Maybe can use ClassAttributeCompartmentEditPart to replace DiagramEditPart to get drop command? For the ClassEditPart is just generated with command, and there is no return value. Can I use EMF listener and notification to get ClassAttributeCompartmentEditPart?

Thanks.




Sorry but I don't know anything about these topics.
Re: How to create diagram elements programatically [message #725864 is a reply to message #725590] Fri, 16 September 2011 02:29 Go to previous messageGo to next message
Yang Liu is currently offline Yang Liu
Messages: 9
Registered: June 2010
Junior Member
Hi Neslepaks,


Sorry that I didn't describe my question clearly.

How to draw diagram elements with its owned diagram elements programatically? For instance, class-diagram-element with its attribute/operation/nestedClassifier-diagram-element.

In the attached figure, how to generate leftside diagram element from rightside model element programatically?

Thank you!


Yang
Re: How to create diagram elements programatically [message #725928 is a reply to message #725864] Fri, 16 September 2011 08:13 Go to previous messageGo to next message
Neslepaks  is currently offline Neslepaks
Messages: 37
Registered: April 2011
Member
Yeah, I understood your problem by reading it carefully. But still, unfortunately, I have no idea.
Re: How to create diagram elements programatically [message #730342 is a reply to message #725928] Wed, 28 September 2011 08:06 Go to previous messageGo to next message
Yang Liu is currently offline Yang Liu
Messages: 9
Registered: June 2010
Junior Member
Eventually, I finish this. Maybe it is helpful for some guys, so post the code as following..

1. get result of gef command execution.
Collection results = DiagramCommandStack.getReturnValues(commandDrop);
for (Object res : results) {
if (res instanceof IAdaptable) {
IAdaptable adapter = (IAdaptable) res;
View view = (View) adapter.getAdapter(View.class);
if (view != null) {
addCompartment(view);
}
}
}

2. get its relevant editpart and model object.
void addCompartment(View view){
...
EditPart cep = (EditPart) getGraphicalViewer().getEditPartRegistry().get(view);
//GraphicalViewer can get from DiagramEditor.getDiagramGraphicalViewer().
EObject eObject = view.getElement();
...
}
and then, can get compartment editPart from this one, with cep.getChildren().

3. add contained EObject to CompartmentEditPart.
Other is almost the same as code to add EObject to canvas in this post, except this time we drop to compartment area.


btw, http://wiki.eclipse.org/GMF/Tips is a good reference.
Re: How to create diagram elements programatically [message #836246 is a reply to message #730342] Wed, 04 April 2012 09:13 Go to previous messageGo to next message
Alexandra Bardiau is currently offline Alexandra Bardiau
Messages: 21
Registered: March 2012
Junior Member
Thanks a lot for the code snippet, it was very helpful indeed!
Re: How to create diagram elements programatically [message #837195 is a reply to message #836246] Thu, 05 April 2012 11:35 Go to previous message
Alexandra Bardiau is currently offline Alexandra Bardiau
Messages: 21
Registered: March 2012
Junior Member
Hi,

Since I've had a similar problem and spent a few hours trying to figure out how to do it (I needed to programmatically generate Interface UML elements in the model and then add them to a Class diagram), and since some of the classes used in Neslepaks's example don't exist anymore in the newer versions of Papyrus, here's to code I used to solve my problem (working, maybe needs a few adjustments like better placement of elements on the diagram, for example):


                EObject model = null;
	
		try {
					
			// Get root element
			model = UmlUtils.getUmlModel().lookupRoot();
			} catch (org.eclipse.papyrus.resource.NotFoundException e) {
			e.printStackTrace();
		}
		
		// Get the model package
		final org.eclipse.uml2.uml.Package modelpackage = (org.eclipse.uml2.uml.Package) model;

		// Add new elements to the model
		TransactionalEditingDomain ted = TransactionUtil.getEditingDomain(model);
		ted.getCommandStack().execute(new RecordingCommand(ted) {
			
			EList<Element> elementsInModel;
			EList<Element> elementsInComponent;
			Component c;
			Port p;
			Interface newItf;
			Stereotype s;
			
			protected void doExecute() {
				
				String text = "";
					
				elementsInModel = modelpackage.allOwnedElements();
				
				/*
				 * Get all the components in the model.
				 */
				
				for (int i=0; i<elementsInModel.size(); i++) {
					if (elementsInModel.get(i).eClass().getName().compareTo("Component") == 0) {
						c = (Component) elementsInModel.get(i);
						text = text + "Component: " + c.getName() + System.getProperty("line.separator");
						/*
						 * For each component, get all the ports (stereotyped).
						 */
						elementsInComponent = c.getOwnedElements();
						for (int j=0; j<elementsInComponent.size(); j++) {
							if (elementsInComponent.get(j).eClass().getName().compareTo("Port") == 0) {
								p = (Port) elementsInComponent.get(j);
								text = text + "      Port: " + p.getName() + System.getProperty("line.separator");
								/*
								 * For each port, generate a new Interface, stereotyped with the same
								 * stereotype as the port.
								 * Rename the port from [name] to [_name].
								 * Associate the new interface to its corresponding port
								 * by typing the port with the new interface
								 * (port.setType(newInterface)).
								 */
								newItf = c.createOwnedInterface(p.getName());
								p.setName("_" + p.getName());
								s = p.getAppliedStereotypes().get(0);
								newItf.applyStereotype(s);
								p.setType(newItf);
								
								text = text + "      New inteface: " + newItf.getName() + System.getProperty("line.separator");
							}
						}
					}
				}
				JOptionPane.showMessageDialog(null, text);				
			}
		});
		
		/*
		 * Generate the Class diagram containing all the newly created
		 * interfaces.
		 */
		
		DropObjectsRequest dropObjectsRequest = new DropObjectsRequest();
		ArrayList list = new ArrayList();
		EList<Element> elementsInModel = modelpackage.allOwnedElements();
		for (int i=0; i<elementsInModel.size(); i++) {
			if (elementsInModel.get(i).eClass().getName().compareTo("Interface") == 0)
				list.add((org.eclipse.uml2.uml.Element)elementsInModel.get(i));
		}
		dropObjectsRequest.setObjects(list);
		dropObjectsRequest.setLocation(new Point(20,100));
		Command commandDrop = getDiagramEditPart().getCommand(dropObjectsRequest);
		
		((UmlClassDiagramForMultiEditor) EditorUtils.getMultiDiagramEditor().getActiveEditor()).getDiagram();
		
		getDiagramEditPart().getDiagramEditDomain().getDiagramCommandStack().execute(commandDrop);



Cheers!
Previous Topic:Class Diagram Operation Return Type Label Display setting is missing
Next Topic:Can I generate code (Objective-C) using Papyrus?
Goto Forum:
  


Current Time: Sun Oct 26 08:03:51 GMT 2014

Powered by FUDForum. Page generated in 0.02463 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software