Using User-Defined Properties

You may have already noticed that in Graphiti it is sometimes difficult to unambiguously identify a pictogram element.

For example many features of this tutorial work on the shapes depicting EClasses. In the canExecute() methods of those features we always received the current pictogram element and checked, if the associated business object is a EClass. In that case we assumed that this is the container shape, which was created in the add feature.

But what happens, if there are several pictogram elements which have a EClass as associated business object? This might happen, because there are several graphical representations for a EClass. In that case we need a means to distinguish the shapes independent from the associated business object.

All pictogram elements provide the possibility to attach user-defined properties to them (key-value pairs).

In our example we want to use this, to attach an identifier to the shapes we create, e.g. "shape-id = e-class". Using this identifier the shapes can later be clearly identified.

You can imagine another example if we would enhance the tutorial and show the attributes of a EClass in the shape below the class name. Each attribute might be displayed as an own shape, but all attribute shapes would associate the same business object: the EClass. So to differentiate the attribute shapes, it would be useful to add the attribute name as a property, e.g. "attribute-name = city".

Creating a Property Utility Class

In this example we want to set a user-defined property to the shape of a EClass, which we create in our add feature. Later in the layout feature we check this user-defined property to find out, if this is the shape the layout feature expects to (remember, that the layout feature very strongly depends on the shape structure created in the add feature. For simplicity reasons we only change the layout feature and not all the other features.

Note, that sometimes it is still correct to only check the business object. For example in our TutorialRenameEClassFeature the shape doesn’t really matter, only the associated EClass.

We start by implementing a utility class for the handling of the user-defined properties of our tool.

Note the helper-methods setPropertyValue and getPropertyValue, which allow to easily access the property values.

You can see the complete implementation of the user-defined property utility class here:

 

package org.eclipse.graphiti.examples.tutorial;
 
public class PropertyUtil {
 
    public static final String SHAPE_KEY = "shape-id";
 
    public static final String SHAPE_VALUE_E_CLASS = "e-class";
 
    public static final void setEClassShape(PictogramElement pe) {
        Graphiti.getPeService().setPropertyValue(pe, SHAPE_KEY,
            SHAPE_VALUE_E_CLASS);
    }
 
    public static boolean isEClassShape(PictogramElement pe) {
        return SHAPE_VALUE_E_CLASS.equals(Graphiti.getPeService()
           .getPropertyValue(pe, SHAPE_KEY));
    }
}

 

Next we have to set the user-defined property to the shape of the EClass in the add method of theTutorialAddEClassFeature.

You can seeadd method in the following code snippet:

 

public PictogramElement add(IAddContext context) {
    EClass addedClass = (EClass) context.getNewObject();
    Diagram targetDiagram = (Diagram) context.getTargetContainer();
 
    // CONTAINER SHAPE WITH ROUNDED RECTANGLE
    IPeCreateService peCreateService = Graphiti.getPeCreateService();
    ContainerShape containerShape =
        peCreateService.createContainerShape(targetDiagram, true);
    PropertyUtil.setEClassShape(containerShape);
 
    // ... EXISTING CODING ...
      
    return containerShape;
}

 

Finally we change the canLayout method of the TutorialLayoutEClassFeature, so that it now compares the user-defined property of the shape and no longer the business object associated with the shape.

This implementation can be seen here:

 

public boolean canLayout(ILayoutContext context) {
    // return true, if pictogram element is a EClass shape
    PictogramElement pe = context.getPictogramElement();
    return PropertyUtil.isEClassShape(pe);
}

 

Test: Verify Layout of EClass

Now start the editor and test that the layout feature still works correctly:

  1. create or open a new diagram
  2. create a new EClass
  3. resize the EClass, and verify that the layout still works correctly (size of all graphics algorithms changes)