Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » Graphiti » Diagram does not update after model is changed
Diagram does not update after model is changed [message #1694513] Tue, 05 May 2015 20:09 Go to next message
Alex Kravets is currently offline Alex KravetsFriend
Messages: 528
Registered: November 2009
Senior Member
Hello,

I have two a multipage editor with a TreeViewer on one page and Graphiti editor in another. There is another thread about this , but I decided to start this one so things don't get messy.

I am trying to follow Graphiti's API to to update diagram when model changes. This seems to work as when I add element in TreeViewer, FeatureProvider sees this and calls getUpdateFeature() method that return UpdateFeature. This is where I am a bit confused. In all example I've seen I see that Graphiti's diagram is being updated for the elements that are already in the model. In my situation model is being updated with new element being added, as a result in UpdateFeature I call IAddFeature to add the new element to the model like this:

public boolean update(IUpdateContext context) {
		String changedType = dm.getChangedType();
		if(changedType.equals(DiagramModel.INLET)){
			Shape shape = dm.getInlets().get(dm.getInlets().size()-1);

			InlineChannel channelBusinessObject = (InlineChannel) getBusinessObjectForPictogramElement(context.getPictogramElement());

			final AddContext inletContext = new AddContext();
			InlineInlet inlineInlet = channelBusinessObject.getInlet().get(channelBusinessObject.getInlet().size() - 1);
			inletContext.setNewObject(inlineInlet);
			inletContext.setTargetContainer(shape.getContainer());

			IFeatureProvider featureProvider = getFeatureProvider();
			final IAddFeature addFeature = featureProvider.getAddFeature(inletContext);
			
			TransactionalEditingDomain editingDomain = TransactionUtil.getEditingDomain(inlineInlet);
			
			editingDomain.getCommandStack().execute(new RecordingCommand(editingDomain) {
				
				@Override
				protected void doExecute() {
					// TODO Auto-generated method stub
					//addFeature.add(inletContext);
					addFeature.execute(inletContext);
				}
			});
			return true;
		}
                .....
                .....


I am not sure if this is the correct way to do it, but diagram model is updated. However, when I switch to diagram editor I don't see any changes - no red border alerting that model has changed. However, when I bring up context menu on the editor I see action "Undo Update" enabled, which I think means update happened.
Re: Diagram does not update after model is changed [message #1694553 is a reply to message #1694513] Wed, 06 May 2015 09:14 Go to previous messageGo to next message
Michael Wenz is currently offline Michael WenzFriend
Messages: 1898
Registered: July 2009
Location: Walldorf, Germany
Senior Member
Alex,

when you call a feature from inside the execution of another feature (add
feature being called from update method of update feature in your case) you
do not need to wrap around a new command. Instead you can simply create the
feature and call execute (or add in your case), this will work because you
are already in an open transaction.

Not sure what happens to that second command in your case without having a
deeper loop, but I guess that the second command reuses the same transaction
and will not reach the command stack.

There's also a shortcut for this: AbstractFeature offers the method
addGraphicalRepresentation(IAreaContext context, Object newObject).

Michael
Re: Diagram does not update after model is changed [message #1694626 is a reply to message #1694553] Wed, 06 May 2015 17:52 Go to previous messageGo to next message
Alex Kravets is currently offline Alex KravetsFriend
Messages: 528
Registered: November 2009
Senior Member
Michael,

That's what I thought when I was reading the documentation, however I am running into issues where I cannot even create shapes or get fonts unless I perform these functions in context of a Command.

For example:
IGaService gaService = Graphiti.getGaService();
channelFont = gaService.manageFont(getDiagram(), "Tahoma" , 15, false, true);
channelContainerFont = gaService.manageFont(getDiagram(), "Tahoma" , 10, false, false);
channelContainer = createService.createContainerShape(getDiagram(), true);


All throw java.lang.IllegalStateException: Cannot modify resource set without a write transaction exception. I am not sure if this is because of how I am setting editingDomain by reusing Graphiti's domain, this is how I set it:

public void init(IEditorSite site, IEditorInput editorInput) {
			// TODO Auto-generated method stub
			diagramEditor = new ChannelDiagramEditor();
			
			
			IFile inputFile = ((FileEditorInput)editorInput).getFile();
			IFile file = inputFile.getParent().getFile(new Path(inputFile.getName().substring(0,inputFile.getName().lastIndexOf(".")) + "." + WorkspaceUtil.inline_channel_diagram_extension));
			diagramEditor.setInputFile(file);
			input = new FileEditorInput(file);
			try {
				diagramEditor.init(site, input);
				editingDomain = diagramEditor.getDiagramBehavior().getEditingDomain(); <--- used by TreeViewer
			} catch (PartInitException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		super.init(site, editorInput);
}


I've done some debugging in this area and see that when for example, in the following code
 gaService.manageFont(getDiagram(), "Tahoma" , 15, false, true);

Exception is thrown at line
fonts.add(newFont);

in manageFont(...). Further down it looks like in TransactionalChangeRecorder.assertWriting() the InternalTransaction does not resolve to anything in
InternalTransaction tx = domain.getActiveTransaction();

and hence the exception.

I also checked IDs for editing domains that I am using in TreeViewer editor and Graphiti editor and they are the same.

Thanks,
Alex

[Updated on: Thu, 07 May 2015 18:05]

Report message to a moderator

Re: Diagram does not update after model is changed [message #1694811 is a reply to message #1694626] Fri, 08 May 2015 07:24 Go to previous messageGo to next message
Michael Wenz is currently offline Michael WenzFriend
Messages: 1898
Registered: July 2009
Location: Walldorf, Germany
Senior Member
Alex,

I'm not sure, but that usually indicates that you actually use a different
editing domain. Can you debug that and ensure it really uses the same
instance?

Michael
Re: Diagram does not update after model is changed [message #1694876 is a reply to message #1694811] Fri, 08 May 2015 15:49 Go to previous messageGo to next message
Alex Kravets is currently offline Alex KravetsFriend
Messages: 528
Registered: November 2009
Senior Member
Yes you are right, I am indeed still using different TEDs. I guess too much debugging took its toll Smile

Here is my issue, in my wizard I create model and diagram model:

...
URI modelURI = URI.createPlatformResourceURI(modelFile.getFullPath().toString(), true);		
Diagram diagram = Graphiti.getPeCreateService().createDiagram("ChannelDiagramType", diagramName, true);
IFile diagramFile = ((IFolder)iwresourceFolder).getFile(diagramName + "." + WorkspaceUtil.inline_channel_diagram_extension); //$NON-NLS-1$
URI diagramURI = URI.createPlatformResourceURI(diagramFile.getFullPath().toString(), true);

final TransactionalEditingDomain editingDomain = GraphitiUiInternal.getEmfService().createResourceSetAndEditingDomain();
final ResourceSet resourceSet = editingDomain.getResourceSet();
final Resource modelResource = resourceSet.createResource(modelResourceUri);
final Resource diagramResource = resourceSet.createResource(diagramResourceUri);
final CommandStack commandStack = editingDomain.getCommandStack();
commandStack.execute(new RecordingCommand(editingDomain) {
		@Override
		protected void doExecute() {
	                  modelResource.setTrackingModification(true);
	                  diagramResource.setTrackingModification(true);
	                  for(EObject modelRoot : modelRoots) {
			         modelResource.getContents().add(modelRoot);
		          }
		         diagramResource.getContents().add(diagram);
		         try {
				modelResource.save(Collections.EMPTY_MAP);
		    	       diagramResource.save(Collections.EMPTY_MAP);
		         } catch(IOException ioe) {
			               ioe.printStackTrace();
		         }
		}
});
....


This works, however when my editor class that extends DiagramEditor opens it calls DiagramEditor's init(IEditorSite site, IEditorInput input) method which in turn creates TED again:

diagramBehavior.getUpdateBehavior().createEditingDomain(diagramEditorInput);


This is why I think in the end I have two different TEDs. I can't really change behavior of init() method because diagramBehavior is private. Any suggestions on how to keep TEDs in sync here?

I created a Singleton that mimic EmfService.createResourceSetAndEditingDomain() method which allows me to set TED in wizard during model creation. I implemented my own DIagramBehavior and DefaultUpdateBehavior to use this Singelton to get, and as in case of DefaultUpdateBehavior create TED. Doesn't fully work yes as side effects of this change is sudden appearance of DocumentRoot in my TreeViewer, creation of which I suppress in ResourceFactoryImpl, so I am not too sure what happened there. Regardless, does this sound like an acceptable approach to keep TED same through out my transactions, or am I missing some simple solution?

Edit: My Singleton was giving all sorts of weird issues, so I went with implementing org.eclipse.emf.transaction.editingDomains extension point which seems to work better.

Alex

[Updated on: Mon, 11 May 2015 18:09]

Report message to a moderator

Re: Diagram does not update after model is changed [message #1695381 is a reply to message #1694876] Wed, 13 May 2015 21:17 Go to previous message
Alex Kravets is currently offline Alex KravetsFriend
Messages: 528
Registered: November 2009
Senior Member
After trying to use editing domain extension point it also turned out to be fruitless. So I tried to go a different route and create model resource in wizard and set up diagram model in the editor. In order to share editing domain created by Graphiti I have the following code:

@Override
	public void init(IEditorSite site, IEditorInput editorInput) {
			// TODO Auto-generated method stub
			diagramEditor = new ChannelDiagramEditor();
			
			
			IFile inputFile = ((FileEditorInput)editorInput).getFile();
			IFile file = inputFile.getParent().getFile(new Path(inputFile.getName().substring(0,inputFile.getName().lastIndexOf(".")) + "." + WorkspaceUtil.inline_channel_diagram_extension));
			diagramEditor.setInputFile(file);
			input = new FileEditorInput(file);
			try {
				diagramEditor.init(site, input);
				editingDomain = diagramEditor.getEditingDomain();
			} catch (PartInitException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		super.init(site, editorInput);
	}

	@Override
	protected void addPages() {
		try {
			if (getEditorInput() instanceof MigrateChannelEditorInput) {
				addPage(new ChannelMigrationPage(this));
				setActivePage(0);
			} else {
				initializeDescriptors();
				validator = new ChannelValidator(this);
				//decorator = new ChannelTreeViewerDecorator2(validator);
				masterDetailsPage = new ChannelMasterDetailsPage(this);
				addPage(masterDetailsPage);
				setActivePage(0);
			}
			
			/*diagramEditor = new ChannelDiagramEditor();
			
			
			IFile inputFile = getInputFile();
			IFile file = inputFile.getParent().getFile(new Path(inputFile.getName().substring(0,inputFile.getName().lastIndexOf(".")) + "." + WorkspaceUtil.inline_channel_diagram_extension));
			diagramEditor.setInputFile(file);
			FileEditorInput input = new FileEditorInput(file);*/
			
			addPage(1, diagramEditor, input);
			setPageText(1, "Design");
		} catch (PartInitException e) {
			ChannelEditorPlugin.getDefault().logError(e.getLocalizedMessage(), e);
		}
	}


The idea here is that during call to init() I created DiagramEditor which in turn sets up editingDomain (protected variable in base class) and then that editing domain is set in base class of my editor (TreeViewer). This works, however addPages() method initialized DiagramEditor again and thus another editingDomain is created and earlier created files are attempted to be written again. I am not sure what to do here. In my MultiEditor I must have TreeViewer tab first and Diagram tab second, so I must pre-create editing domain. I know about FIleService class with method createEmfFileForDiagram(), but this method does not preset UpdateBehavior with editingDomain that it creates. I of course can create my own UpdateBehavior, but it still leaves me with init() method being called twice.
Previous Topic:Programmatically avoid Activities during Connection Creation
Next Topic:DiagramComposite workbench part
Goto Forum:
  


Current Time: Sun Sep 23 20:42:49 GMT 2018

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

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

Back to the top