Home » Modeling » Graphiti » Image Decorator problem when adding shapes
Image Decorator problem when adding shapes [message #1273629] |
Thu, 20 March 2014 09:36 |
Thomas Thonhofer Messages: 25 Registered: July 2013 |
Junior Member |
|
|
Hello
I have a problem with my Graphiti editor and cannot find a solution for it.
In my editor I can create processes, constisting of so called States, displayed as rectangles:
I have a validation feature, that looks for possible problems in the process. In case there is a problem with a certain State, it puts a warning in form of an image decorator in the upper right corner as seen above. For creating these decorators I use the normal getDecorators method in the ToolBehaviorProvider. It looks like this:
@Override
public IDecorator[] getDecorators(PictogramElement pe) {
if(pe instanceof ContainerShape && pe instanceof Diagram == false){
Validator validator = new Validator(diagramTypeProvider);
Object object = featureProvider.getBusinessObjectForPictogramElement(pe);
if(object instanceof State){
ValidationMessage message = validator.createWarnings((State)object);
if(message != null){
if(pe instanceof ContainerShape && pe instanceof Diagram == false){
IImageDecorator imageRenderingDecorator = null;
if(message.getSeverity().equals(ValidationSeverity.WARNING)){
imageRenderingDecorator = new ImageDecorator(IPlatformImageConstants.IMG_ECLIPSE_WARNING_TSK);
}
else if(message.getSeverity().equals(ValidationSeverity.ERROR)){
imageRenderingDecorator = new ImageDecorator(IPlatformImageConstants.IMG_ECLIPSE_ERROR_TSK);
}
else{
return super.getDecorators(pe);
}
imageRenderingDecorator.setMessage(message.getMessage());
imageRenderingDecorator.setX(pe.getGraphicsAlgorithm().getWidth()-20);
return new IDecorator[] { imageRenderingDecorator };
}
}
}
}
return super.getDecorators(pe);
}
So far it works fine. It should also be possible to add shapes to the containerShape of the State at any time. But when I add a shape to the containerShape (in this case a small dot in the lower left corner), this happens:
For some reason there is a new decorator with the same message as that of the State and it seems to be attached to the diagram at the exact loaction, the other decorator was(in the picture I moved the containerShape, to make the problem visible). This happens every time I add or remove a shape in a containerShape with a warning. The unwanted decorators stay there until I close and reopen the diagram.
This is the code for adding the dot:
Shape newShape = peCreateService.createShape((ContainerShape) pe, false);
Ellipse ellipse = gaService.createEllipse(newShape);
ellipse.setForeground(manageColor(IColorConstant.BLACK));
ellipse.setBackground(manageColor(IColorConstant.BLACK));
ellipse.setLineWidth(1);
gaService.setLocationAndSize(ellipse, xPos, yPos, 7, 7);
I have been trying to solve this problem for I while, but nothing helped so far. Could it be a bug in the framework or am I doing something wrong? I hope someone can help me.
Thanks
|
|
| | | |
Re: Image Decorator problem when adding shapes [message #1277677 is a reply to message #1273629] |
Wed, 26 March 2014 09:55 |
Thomas Thonhofer Messages: 25 Registered: July 2013 |
Junior Member |
|
|
Debugging has brought following insights:
When adding a shape to my containerShape, the getDecorators method is called once for each containerShape in my diagram(not for the digram itself). This seems a bit strange to me, because it would only need to update the containerShape I add to. I also recognised that after adding the shape, the containerShape I added to is no longer selected in the editor for some reason.
I also found out that after adding the shape, the old decorator is not removed with the removeDecorators method, because in this case, the decFigureList, wich should contain the decorators to remove, is null. This could mean, that at this point, the old decorator is not attached to the containerShape anymore. In any other case the removeDecorators method works fine. So the reason, why there are two decorators after adding the shape is, that the old one is not removed. But I still don't know why this happens and it doesn't explain, why the old decorator is attachedto the diagram afterwards.
I hope this information is of use to you.
|
|
| |
Re: Image Decorator problem when adding shapes [message #1286996 is a reply to message #1273629] |
Mon, 07 April 2014 09:23 |
Thomas Thonhofer Messages: 25 Registered: July 2013 |
Junior Member |
|
|
I finally found some time to take a closer look into my problem and after some digging in the framework I found its cause and a workaround:
The problem seems to be in the framework. It happens when the DiagramEditPart is refreshed, specifically in the refreshVisuals() method in the ShapeEditPart class and in the refreshChildren() method in the AbstractEditPart class:
@Override
protected void refreshVisuals() {
super.refreshVisuals();
refreshSourceConnections();
refreshTargetConnections();
delegate.refreshFigureForEditPart();
}
The problem is, that at this point, the newly created shape inside my containerShape has no EditPart yet. The refreshVisuals() method leads to the PictogramElementDelegate which checks and refreshes the figures for all the pictogramElements. Because it cannot find the editPart and figure for the new shape, the editPart of the containerShape is removed.
protected void refreshChildren() {
int i;
EditPart editPart;
Object model;
List children = getChildren();
int size = children.size();
Map modelToEditPart = Collections.EMPTY_MAP;
if (size > 0) {
modelToEditPart = new HashMap(size);
for (i = 0; i < size; i++) {
editPart = (EditPart) children.get(i);
modelToEditPart.put(editPart.getModel(), editPart);
}
}
List modelObjects = getModelChildren();
for (i = 0; i < modelObjects.size(); i++) {
model = modelObjects.get(i);
// Do a quick check to see if editPart[i] == model[i]
if (i < children.size()
&& ((EditPart) children.get(i)).getModel() == model)
continue;
// Look to see if the EditPart is already around but in the
// wrong location
editPart = (EditPart) modelToEditPart.get(model);
if (editPart != null)
reorderChild(editPart, i);
else {
// An EditPart for this model doesn't exist yet. Create and
// insert one.
editPart = createChild(model);
addChild(editPart, i);
}
}
So in the refreshChildren() method there is no editPart for the containerShape in the children List. The editPart is null at the bottom of the method and a new editPart is created for my containerShape (Afterwards the new Shape has an editPart).
So everytime I add a shape to my containerShape, it gets a new editPart and thereby also a new pictogramDelegate. It seems the old pictogramDelegate is not removed properly, which explains why the icon exists twice: One is from the new PictogramDelegate, the other from the old. So the old icon is not attached to the diagram, as I thought at first, there is just an invisible editPart at the location that used to belong to the pictogramElement and this editPart contains the icon.
I didn't find a way to add the editPart for my new shape manually, so I can avoid this problem completly so far. So my current workaround is simply deactivating the old pictogramDelegate before the refresh is done. I would prfer a solution, where the editPart of the containerShape isn't removed in the first place so any ideas for achieving this would be very welcome.
I don't know if this behavior is a bug, if graphiti simply doesn't intend someone to add a shape after creation or if I am simple making some mistake. Would be great if someone could clear that up. If it is indeed a bug I will file a bugzilla, of course.
|
|
| |
Re: Image Decorator problem when adding shapes [message #1289500 is a reply to message #1273629] |
Wed, 09 April 2014 11:27 |
Thomas Thonhofer Messages: 25 Registered: July 2013 |
Junior Member |
|
|
There are two ways of triggering the creation of the shape, one by clicking a button in one of my views, the other is used by my update feature when the number of shapes does not fit to the number of objects they represent.
I tried to use an addShape feature for the creation as well as simply adding it from a normal methode, both with the same result.
Another thing I found out is, that when I create the new shape as active, the problem doesn't occur. When investigating this I found an explanation in the javadoc of the createShape method:
"For those familiar with GEF: only for active shapes a GEF EditPart will be created by the Graphiti framework, not for inactive ones."
So for inactive PictogramElements ther is no EditPart created on purpose. This leads to the problem described in my last post. Seems like it is not intended to add inactive shapes directly. Unfortunatly my shape should not be active. The user should not be able to change them in any way. My new workaround is to set the shapes active but deactivate all features that could change it for this kind of shape. Still not a perfekt solution but at least now there are no invisble, useless editParts attached to my diagram .
Still it would be great, if there was a way of freely adding inactive shapes to a containerShape. If this is really not intended, some restriction or at least a warning of some kind, when trying to add a new shape to an already existing containerShape would be nice, so people do not run into strange problems.
Thomas
|
|
| |
Goto Forum:
Current Time: Thu Apr 25 01:13:39 GMT 2024
Powered by FUDForum. Page generated in 0.04540 seconds
|