As described in the chapter “providing add functionality” the values of the business objects (e.g. the EClass name) are stored in the graphics algorithm of the pictogram elements. But this is done only once. If the business model changes the example diagram does not realize the changes.
For that purpose we need an update feature which is used by the diagram to react on business model changes.
The behavior of the update is straight forward, when the user is changing the domain model directly via the diagram. For example if the user changes a text in the diagram using direct-editing or the property-sheet, then this text should be changed in the diagram immediately.
However, if the domain-model is changed outside the diagram (e.g. in a separate editor or viewer, maybe even by another user), then it is questionable, if the diagram should be updated immediately. Often an immediate update would destroy a previously good layout or hide previously important information. Therefore Graphiti supports two update-strategies:
Figure: Shape marked as outdated (tooltip shows reason)
Figure: Outdated shape can be updated manually
By default the automatic update is inactive, but this can be configured by overwriting the following methods in the IDiagramTypeProvider:
An update feature has to implement the interface IUpdateFeature. Instead of implementing it directly it should extend one of the available base classes. In this example we extend the base class AbstractUpdateFeature
In this case we have to implement/overwrite 3 methods:
Hint: An update feature can and should also be used (called) if any functionality of the editor or viewer (e.g. any custom feature) modifies parts of the domain model. This works just like the model view controller pattern.
In this example we want to update the EClass name. You can see the complete implementation of the update feature here:
package org.eclipse.graphiti.examples.tutorial.features;
public class TutorialUpdateEClassFeature
extends AbstractUpdateFeature {
public TutorialUpdateEClassFeature(IFeatureProvider
fp) {
super(fp);
}
public boolean canUpdate(IUpdateContext context)
{
//
return true, if linked business object is a EClass
Object bo =
getBusinessObjectForPictogramElement(context.getPictogramElement());
return (bo instanceof
EClass);
}
public IReason updateNeeded(IUpdateContext
context) {
// retrieve name from pictogram model
String pictogramName = null;
PictogramElement pictogramElement = context.getPictogramElement();
if (pictogramElement
instanceof ContainerShape) {
ContainerShape cs = (ContainerShape) pictogramElement;
for (Shape shape : cs.getChildren()) {
if (shape.getGraphicsAlgorithm()
instanceof Text) {
Text text = (Text) shape.getGraphicsAlgorithm();
pictogramName = text.getValue();
}
}
}
// retrieve name from business model
String businessName = null;
Object bo = getBusinessObjectForPictogramElement(pictogramElement);
if (bo instanceof
EClass) {
EClass eClass = (EClass) bo;
businessName = eClass.getName();
}
// update needed, if names are different
boolean updateNameNeeded =
((pictogramName == null && businessName !=
null) ||
(pictogramName != null && !pictogramName.equals(businessName)));
if (updateNameNeeded) {
return Reason.createTrueReason("Name
is out of date");
}
else {
return Reason.createFalseReason();
}
}
public boolean update(IUpdateContext context)
{
//
retrieve name from business model
String businessName = null;
PictogramElement pictogramElement = context.getPictogramElement();
Object bo = getBusinessObjectForPictogramElement(pictogramElement);
if (bo instanceof
EClass) {
EClass eClass = (EClass) bo;
businessName = eClass.getName();
}
// Set name in pictogram model
if (pictogramElement instanceof ContainerShape)
{
ContainerShape cs = (ContainerShape) pictogramElement;
for (Shape shape : cs.getChildren()) {
if (shape.getGraphicsAlgorithm()
instanceof Text) {
Text text = (Text) shape.getGraphicsAlgorithm();
text.setValue(businessName);
return true;
}
}
}
return false;
}
}
Additionally the feature provider has to deliver our newly created feature (overwrite the method getUpdateFeature).
This implementation can be seen here:
@Override
public IUpdateFeature
getUpdateFeature(IUpdateContext context) {
PictogramElement
pictogramElement = context.getPictogramElement();
if (pictogramElement
instanceof ContainerShape) {
Object bo = getBusinessObjectForPictogramElement(pictogramElement);
if (bo instanceof
EClass) {
return new TutorialUpdateEClassFeature(this);
}
}
return super.getUpdateFeature(context);
}
Note: if the Graphiti project wizard for a "New Graphiti Sample Project" does not work correctly and you can not test the update feature as described below, please continue with the next chapters and provide custom functionality to rename a EClass. That will allow testing the update feature by changing the same EClass in two different diagrams.
Now start the editor again and test it: