Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » GMF (Graphical Modeling Framework) » Creating a parent element for a child node
icon5.gif  Creating a parent element for a child node [message #640263] Fri, 19 November 2010 19:14 Go to next message
Knut is currently offline KnutFriend
Messages: 4
Registered: November 2010
Junior Member
Hello,

I'm working with GMF and am facing a problem, which I cannot solve on my own. I searched the forum, but could not find anything about my problem. Help is very appreciated!

I'm trying to add a parent element programmably, if the child of the parent is inserted.

This is my situation:

I have the nodes A, B and the diagram root element. The nodes have the following hierarchy:

root <- A <- B

So B is a child of A and A a child of B. I'm trying to add B with its CreationTool in the root and create A programmably. B and A are created ok, but I'm getting an Exception. Another problem is that the nodes are created not where my mouse clicking was.

What I have done so far, is modifying the getCreateCommand-Method in the root element SemanticEditPolicy, to make it possible to add B directly to the root with its CreationTool. Further I wrote a CreateCommand, which is called from out the above Method. In this CreateCommand I have created a doExecuteWithResult-Method, where I do the following.
First I'am creating the node A and am adding it to the root. Than I'am creating and executing a CreateViewRequest for A. Finally I'am adding B to A .

Moreover I have debugged the program. The Method which is causing the Exception is executed three times. The first two times it is running ok, that's why the elements are created ok, I think. The third time it gives a assertion error, because an element is null. This element is null, because the container of the CreateCommand is not appropriate for the element, which should be created. The container is root and element is B, but B cannot be a child of root.

Could somebody tell me, if there is a better way of doing, what I'm intending or could give me a tip?


The exception is (shortened):
org.eclipse.core.commands.ExecutionException: While executing the operation, an exception occurred
at org.eclipse.core.commands.operations.DefaultOperationHistory .execute(DefaultOperationHistory.java:519)
...
Caused by: org.eclipse.core.runtime.AssertionFailedException: null argument:failed to create a view
at org.eclipse.core.runtime.Assert.isNotNull(Assert.java:85)
at org.eclipse.gmf.runtime.diagram.ui.commands.CreateCommand.do ExecuteWithResult(CreateCommand.java:99)
at org.eclipse.gmf.runtime.emf.commands.core.command.AbstractTr ansactionalCommand.doExecute(AbstractTransactionalCommand.ja va:247)
at org.eclipse.emf.workspace.AbstractEMFOperation.execute(Abstr actEMFOperation.java:150)
at org.eclipse.gmf.runtime.common.core.command.CompositeCommand .doExecuteWithResult(CompositeCommand.java:403)
at org.eclipse.gmf.runtime.common.core.command.AbstractCommand. execute(AbstractCommand.java:135)
... 42 more


My code:

RootItemSemanticEditPolicy:

protected Command getCreateCommand(CreateElementRequest req) {
     if (XXXElementTypes.B_2001 == req.getElementType()) {
          EObject root = req.getContainer();
	  if (root instanceof View) {
	       root = ((View) root).getElement();
          }
		
	  A_Node a = XXXFactory.eINSTANCE.createA_Node();
			
	  CreateElementRequest r = new CreateElementRequest(req.getEditingDomain(), a, XXXElementTypes.A_1001);
	  return getGEFWrapper(new A_NodeAndB_NodeCreateCommand(r, this.getHost(), root));
     }
     
     if (XXXElementTypes.A_1001 == req.getElementType()) {
          return getGEFWrapper(new A_NodeCreateCommand(req));
     }
     
     return super.getCreateCommand(req);
}



A_NodeAndB_NodeCreateCommand:

protected CommandResult doExecuteWithResult(IProgressMonitor monitor, IAdaptable info) throws ExecutionException {
		A_Node a = (A_Node) getElementToEdit();
		B_Node b = XXXFactory.eINSTANCE.createB_Node();

		rootEObj.getNodes().add(a);
		doConfigureA(a, monitor, info);
	
		setElementToEdit(a);	
		
		CreateViewRequest.ViewDescriptor viewDescriptor = new CreateViewRequest.ViewDescriptor(
                           new EObjectAdapter(a), Node.class, null, XXXEditorPlugin.DIAGRAM_PREFERENCES_HINT); 
		CreateViewRequest viewRequest = new CreateViewRequest((viewDescriptor));
		Command cmd = rootEditPart.getCommand(viewRequest);
		cmd.execute();
		
		a.setAction(b);
		((CreateElementRequest) getRequest()).setContainer(a);
		doConfigure(b, monitor, info);

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



Hope someone can help, Thanks



[Updated on: Sat, 20 November 2010 01:19]

Report message to a moderator

Re: Creating a parent element for a child node [message #640296 is a reply to message #640263] Sat, 20 November 2010 06:25 Go to previous messageGo to next message
Asiri Rathnayake is currently offline Asiri RathnayakeFriend
Messages: 80
Registered: September 2010
Location: Colombo, Sri Lanka.
Member
Hi,

Did you try something like below:

A_NodeAndB_NodeCreateCommand:

protected CommandResult doExecuteWithResult(IProgressMonitor monitor, IAdaptable info) throws ExecutionException {
	A_Node a = (A_Node) getElementToEdit();
	B_Node b = XXXFactory.eINSTANCE.createB_Node();

	rootEObj.getNodes().add(a);
	doConfigureA(a, monitor, info);
	
	setElementToEdit(a);	
		
	CreateViewRequest.ViewDescriptor viewDescriptor = new CreateViewRequest.ViewDescriptor(
                          new EObjectAdapter(a), Node.class, null, XXXEditorPlugin.DIAGRAM_PREFERENCES_HINT); 
	CreateViewRequest viewRequest = new CreateViewRequest((viewDescriptor));
	Command cmd = rootEditPart.getCommand(viewRequest);
	cmd.execute();

	// At this point an EditPart should be created corresponding to your semantic object 'a'.
	// 1. Locate this newly created edit part.
	// 2. Create a new CreateViewRequest just like before but this time we're creating a view for 'b'.
	// 3. Invoke newlyCreatedEditPart.getCommand(createViewRequestForB)
	// 4. Execute this command.
}

I will try to reproduce your situation with some actual code, it's only guessing otherwise Smile

- Asiri
Re: Creating a parent element for a child node [message #640304 is a reply to message #640263] Sat, 20 November 2010 09:17 Go to previous messageGo to next message
Asiri Rathnayake is currently offline Asiri RathnayakeFriend
Messages: 80
Registered: September 2010
Location: Colombo, Sri Lanka.
Member
Hi,

Ok, I have replied too soon, you have mentioned that both A and B are created. It's the exception and the created place that is a problem for you.

I tried to reproduce your problem but in my case I get the exception and nodes are not created. And when I check cmd.canExecute(), it returns false.

Will digg a little deeper as time permits Smile

- Asiri
Re: Creating a parent element for a child node [message #640305 is a reply to message #640304] Sat, 20 November 2010 09:30 Go to previous messageGo to next message
Knut is currently offline KnutFriend
Messages: 4
Registered: November 2010
Junior Member
Hi,

thanks for your help, so far. The Exception and the wrong place are exactly my problems. I will try your advice from the second post and will post the result later. I have tryed cmd.canExecute() and it gives me true.


I now have made a smaller example of my case, too. You are right. I'm getting the same exception as you and the element is not created. The reason for this is the missing SemanticHint, which is null in my obove exsample. So it should look like this in the corresponding line:
CreateViewRequest.ViewDescriptor viewDescriptor = new CreateViewRequest.ViewDescriptor(
                           new EObjectAdapter(a), Node.class, ((IHintedType)CreationElementTypes.A_1001).getSemanticHint(), CreationDiagramEditorPlugin.DIAGRAM_PREFERENCES_HINT); 


If you want I can send you my little example (model files and the CreateCommend class). Next I will try your advice above.

Greetings

[Updated on: Sat, 20 November 2010 10:52]

Report message to a moderator

Re: Creating a parent element for a child node [message #640336 is a reply to message #640263] Sat, 20 November 2010 19:59 Go to previous messageGo to next message
Asiri Rathnayake is currently offline Asiri RathnayakeFriend
Messages: 80
Registered: September 2010
Location: Colombo, Sri Lanka.
Member
Hi,

After a couple of hours of digging, I think I have come to realize that we're making a fundamental error. I think it's wrong to mess with the notational model from within the semantic edit policy. If I have understood it correct, we should instead try to install a custom CreationEditPolicy on the root edit part and override its getCreateElementAndViewCommand() method. I have fried enough brain cells for today, will try this tomorrow may be Smile

- Asiri
Re: Creating a parent element for a child node [message #640343 is a reply to message #640336] Sat, 20 November 2010 23:09 Go to previous messageGo to next message
Knut is currently offline KnutFriend
Messages: 4
Registered: November 2010
Junior Member
Hi,

thanks again for your time. I had a thought like you, because the elements are created correctly, but the CreateCommand is causing problems, when it is finaly executed. I have had looked for a possibility to create a ViewAndElementCommand directly for the root Elment, but havent found anything. Your idea should point in the right way. I will digg into this tomorow, too. Good luck for us both Smile

Greetings,

Knut

[Updated on: Sat, 20 November 2010 23:09]

Report message to a moderator

Re: Creating a parent element for a child node [message #640369 is a reply to message #640263] Sun, 21 November 2010 05:53 Go to previous messageGo to next message
Asiri Rathnayake is currently offline Asiri RathnayakeFriend
Messages: 80
Registered: September 2010
Location: Colombo, Sri Lanka.
Member
Hi Knut,

Ok I was finally able to crack this with the approach I mentioned above Smile

In my example scenario I have the Farm->Chicken->Egg hierarchy and my package name is 'Bongo'.

FarmEditPart

/**
 * @generated NOT
 */
protected void createDefaultEditPolicies() {
	super.createDefaultEditPolicies();
	installEditPolicy(EditPolicyRoles.SEMANTIC_ROLE, new FarmItemSemanticEditPolicy());
	installEditPolicy(EditPolicyRoles.CANONICAL_ROLE, new FarmCanonicalEditPolicy());
	installEditPolicy(EditPolicyRoles.CREATION_ROLE, new CustomCreationEditPolicy());
	// removeEditPolicy(org.eclipse.gmf.runtime.diagram.ui.editpolicies.EditPolicyRoles.POPUPBAR_ROLE);
}

CustomCreationEditPolicy
package org.rmap.eclipse.gmf.bongo.diagram.edit.policies;

import org.eclipse.emf.ecore.EObject;
import org.eclipse.gef.commands.Command;
import org.eclipse.gef.commands.CompoundCommand;
import org.eclipse.gmf.runtime.diagram.core.edithelpers.CreateElementRequestAdapter;
import org.eclipse.gmf.runtime.diagram.ui.commands.ICommandProxy;
import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart;
import org.eclipse.gmf.runtime.diagram.ui.editpolicies.CreationEditPolicy;
import org.eclipse.gmf.runtime.diagram.ui.requests.CreateViewAndElementRequest;
import org.eclipse.gmf.runtime.diagram.ui.requests.CreateViewAndElementRequest.ViewAndElementDescriptor;
import org.eclipse.gmf.runtime.emf.type.core.IHintedType;
import org.eclipse.gmf.runtime.emf.type.core.requests.CreateElementRequest;
import org.eclipse.gmf.runtime.notation.Node;
import org.eclipse.gmf.runtime.notation.View;
import org.rmap.eclipse.gmf.bongo.diagram.edit.commands.CreateEggAfterChickenCommand;
import org.rmap.eclipse.gmf.bongo.diagram.providers.BongoElementTypes;

public class CustomCreationEditPolicy extends CreationEditPolicy {
	/**
	 * {@inheritDoc}
	 */
	protected Command getCreateElementAndViewCommand(CreateViewAndElementRequest request) {
		ViewAndElementDescriptor descriptor = request.getViewAndElementDescriptor();
		IHintedType eggHintedType = (IHintedType) BongoElementTypes.Egg_3001;
		IHintedType chickenHintedType = (IHintedType) BongoElementTypes.Chicken_2001;
		if (descriptor.getSemanticHint() == eggHintedType.getSemanticHint()) {
			IGraphicalEditPart farmEP = (IGraphicalEditPart) getHost();
			EObject farmSemanticObject = ((View) farmEP.getModel()).getElement();
			
			// First we need to create a chicken.
			CreateElementRequest chickenSemanticRequest = new CreateElementRequest(farmEP
					.getEditingDomain(), farmSemanticObject, chickenHintedType);
			CreateElementRequestAdapter chickenSemanticRequestAdapter = new CreateElementRequestAdapter(chickenSemanticRequest);
			ViewAndElementDescriptor chickenViewAndSemanticDescriptor = new ViewAndElementDescriptor(
					chickenSemanticRequestAdapter, Node.class, chickenHintedType.getSemanticHint(), farmEP
							.getDiagramPreferencesHint());
			CreateViewAndElementRequest createChickenViewAndSemanticRequest = new CreateViewAndElementRequest(chickenViewAndSemanticDescriptor);
			
			// Grab the location & size from the original request.
			createChickenViewAndSemanticRequest.setLocation(request.getLocation());
			createChickenViewAndSemanticRequest.setSize(request.getSize());
			
			Command createChickenViewAndSemanticCommand = farmEP.getCommand(createChickenViewAndSemanticRequest);
			
			// Create an egg afterwards.
			if (createChickenViewAndSemanticCommand.canExecute()) {
				CompoundCommand cc = new CompoundCommand();
				cc.add(createChickenViewAndSemanticCommand);
				cc.add(new ICommandProxy(new CreateEggAfterChickenCommand(farmEP)));				
				return cc;
			}
		} 
		return super.getCreateElementAndViewCommand(request);	
	}	
}

CreateEggAfterChickenCommand
package org.rmap.eclipse.gmf.bongo.diagram.edit.commands;

import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.gef.commands.Command;
import org.eclipse.gmf.runtime.common.core.command.CommandResult;
import org.eclipse.gmf.runtime.diagram.core.edithelpers.CreateElementRequestAdapter;
import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart;
import org.eclipse.gmf.runtime.diagram.ui.requests.CreateViewAndElementRequest;
import org.eclipse.gmf.runtime.diagram.ui.requests.CreateViewAndElementRequest.ViewAndElementDescriptor;
import org.eclipse.gmf.runtime.emf.commands.core.command.AbstractTransactionalCommand;
import org.eclipse.gmf.runtime.emf.type.core.IHintedType;
import org.eclipse.gmf.runtime.emf.type.core.requests.CreateElementRequest;
import org.eclipse.gmf.runtime.notation.Node;
import org.eclipse.gmf.runtime.notation.View;
import org.rmap.eclipse.gmf.bongo.diagram.providers.BongoElementTypes;

public class CreateEggAfterChickenCommand extends AbstractTransactionalCommand {
	
	private IGraphicalEditPart farmEP;
	
	public CreateEggAfterChickenCommand(IGraphicalEditPart farmEP) {
		super(farmEP.getEditingDomain(), "creates-an-egg-after-a-chicken", null);
		this.farmEP = farmEP;		
	}

	/**
	 * {@inheritDoc}
	 */
	protected CommandResult doExecuteWithResult(IProgressMonitor monitor, IAdaptable info) throws ExecutionException {
		// In my case a farm can only contain chickens, so I select the last
		// edit part added to the farm which should correspond to the chicken
		// created from the previous command.
		if (!farmEP.getChildren().isEmpty()) {
			Object lastAddedEP = farmEP.getChildren().get(farmEP.getChildren().size() - 1);
			IGraphicalEditPart chickenEP = (IGraphicalEditPart) lastAddedEP;
			
			// Create a new egg!
			IHintedType eggHintedType = (IHintedType) BongoElementTypes.Egg_3001;
			EObject chickenSemanticObject = ((View) chickenEP.getModel()).getElement();
			CreateElementRequest eggSemanticRequest = new CreateElementRequest(chickenEP
					.getEditingDomain(), chickenSemanticObject, eggHintedType);
			CreateElementRequestAdapter eggSemanticRequestAdapter = new CreateElementRequestAdapter(eggSemanticRequest);
			ViewAndElementDescriptor eggViewAndSemanticDescriptor = new ViewAndElementDescriptor(
					eggSemanticRequestAdapter, Node.class, eggHintedType.getSemanticHint(), chickenEP
							.getDiagramPreferencesHint());
			CreateViewAndElementRequest createEggViewAndSemanticRequest = new CreateViewAndElementRequest(eggViewAndSemanticDescriptor);			
			Command createEggViewAndSemanticCommand = chickenEP.getCommand(createEggViewAndSemanticRequest);
			if (createEggViewAndSemanticCommand.canExecute()) {
				createEggViewAndSemanticCommand.execute();
				return CommandResult.newOKCommandResult();
			}
		}
		
		return CommandResult.newErrorCommandResult("Could not create egg after the chicken.");
	}		
}

Note that I was particularly interested in solving this problem because I knew this problem is going to teach me underlying GMF / GEF concepts really well Smile

Hope this helps!

- Asiri
Re: Creating a parent element for a child node [message #640375 is a reply to message #640369] Sun, 21 November 2010 10:15 Go to previous message
Knut is currently offline KnutFriend
Messages: 4
Registered: November 2010
Junior Member
HI,

i have tried your code on my example too and it is working great. Thank you very much for your help! You were realy fast, i havent any chance to even glimpse on my code Smile By the way, nice example with the eggs Laughing
Previous Topic:Using CreateChildCommand correctly?
Next Topic:Re: How to do a tree inside a node ?
Goto Forum:
  


Current Time: Thu Apr 25 14:08:30 GMT 2024

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

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

Back to the top