Providing Add Functionality

 

Architecture: Pictogram Model Linked With Domain Model

 

In the terms of  Graphiti “add” means to add a graphical representation of an existing domain model object (= business object) to the diagram. What kinds of business objects can be added to a diagram of a specific type is decided by the add features delivered by the feature provider.

For our example the graphical representation of a EClass is illustrated in the Figure. We want to see a rounded rectangle containing a separator like horizontal line and above that line the name of the corresponding EClass.

 

Figure: Graphical representation of a EClass

Graphiti supports a kind of linkage between elements of the domain model and elements of the model defining the graphical representation – the so called Pictograms Model. These links are called pictogram links. Each diagram contains one container for all pictogram links – called diagram link.

You can see the linkage structure of the example in the Figure: Column one shows the entity model of the graphical representation of exactly one EClass. A container shape aggregates two child shapes (a container shape itself can be aggregated in another container shape or in a diagram). All three shapes themselves aggregate specific graphics algorithms, providing the complete information to allow the rendering on a screen. Examples for this information are background color, foreground color, size, position, visibility and line width. In our example we have a rounded rectangle providing an additional corner radius, a polyline having defined end- and bendpoints and a text label containing a text value.

 

Figure: Linkage structure example

The container shape and likewise the shape containing the text label are related to a corresponding EClass. This relationship is realized through special link objects (pictogram link) holding references to both sides: to the pictograms side and to the business side.

 

Creating an add feature

 

In this example we want to enable the editor’s users to add EClasses to the diagram. As a result it should be possible to drag an EClass from the tree and drop it on the diagram. Therefore we have to create an add feature and make it available in the feature provider.

An add feature has to implement the interface IAddFeature. Instead of implementing it directly it should extend one of the available base classes. In this example we extend the base class AbstractAddShapeFeature.

 

In this case we have to implement/overwrite two methods:

The method canAdd has to check the given context and therefore it decides if a business object can be added.

The method add finally has to create the pictogram structure described above and has to establish the linkage to the business object. Additionally we have to create graphics algorithms and place them at the appropriate location (get location from given context). Additionally, the name of the EClass has to be set as the text label’s value.

 

You can see the complete implementation of the add feature here:

 

 

package org.eclipse.graphiti.examples.tutorial.features;

 

public class TutorialAddEClassFeature extends AbstractAddShapeFeature {

 

    private static final IColorConstant CLASS_TEXT_FOREGROUND =

        new ColorConstant(51, 51, 153);

 

    private static final IColorConstant CLASS_FOREGROUND =

        new ColorConstant(255, 102, 0);

 

    private static final IColorConstant CLASS_BACKGROUND =

        new ColorConstant(255, 204, 153);

 

    public TutorialAddEClassFeature(IFeatureProvider fp) {

        super(fp);

    }

 

    public boolean canAdd(IAddContext context) {

        // check if user wants to add a EClass

        if (context.getNewObject() instanceof EClass) {

            // check if user wants to add to a diagram

            if (context.getTargetContainer() instanceof Diagram) {

                return true;

            }

        }

        return false;

    }

 

    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);

 

        // define a default size for the shape

        int width = 100;

        int height = 50;

        IGaService gaService = Graphiti.getGaService();

 

        {

            // create and set graphics algorithm

            RoundedRectangle roundedRectangle =

                gaService.createRoundedRectangle(containerShape, 5, 5);

            roundedRectangle.setForeground(manageColor(CLASS_FOREGROUND));

            roundedRectangle.setBackground(manageColor(CLASS_BACKGROUND));

            roundedRectangle.setLineWidth(2);

            gaService.setLocationAndSize(roundedRectangle,

                context.getX(), context.getY(), width, height);

 

            // if added Class has no resource we add it to the resource
            // of the diagram

            // in a real scenario the business model would have its own resource

            if (addedClass.eResource() == null) {

                     getDiagram().eResource().getContents().add(addedClass);

            }

            // create link and wire it

            link(containerShape, addedClass);

        }

 

        // SHAPE WITH LINE

        {

            // create shape for line

            Shape shape = peCreateService.createShape(containerShape, false);

 

            // create and set graphics algorithm

            Polyline polyline =

                gaService.createPolyline(shape, new int[] { 0, 20, width, 20 });

            polyline.setForeground(manageColor(CLASS_FOREGROUND));

            polyline.setLineWidth(2);

        }

 

        // SHAPE WITH TEXT

        {

            // create shape for text

            Shape shape = peCreateService.createShape(containerShape, false);

 

            // create and set text graphics algorithm

            Text text = gaService.createDefaultText(getDiagram(), shape,
                        addedClass.getName());

            text.setForeground(manageColor(CLASS_TEXT_FOREGROUND));

            text.setHorizontalAlignment(Orientation.ALIGNMENT_CENTER);

            text.setVerticalAlignment(Orientation.ALIGNMENT_CENTER);

            text.getFont().setBold(true);

            gaService.setLocationAndSize(text, 0, 0, width, 20);

 

            // create link and wire it

            link(shape, addedClass);

        }

 

        return containerShape;

    }

}

 

 

 

The feature provider has to deliver our newly created feature (overwrite the method getAddFeature).

This implementation can be seen here:

 

 

    @Override

    public IAddFeature getAddFeature(IAddContext context) {

        // is object for add request a EClass?

        if (context.getNewObject() instanceof EClass) {

            return new TutorialAddEClassFeature(this);

        }

        return super.getAddFeature(context);

    }

 

 

 

Test: Add a EClass

 

Note: if the project wizard for a "New Graphiti Sample Project" does not work correctly and you can not test the add feature as described below, please continue with the next chapter and provide create functionality. That will allow to test the add feature directly in the diagram.

 

Now we can start the editor again. It should be possible to drop an EClass from the tree of the Graphiti "Test" project into the diagram Test-1.

 

 

Figure: Add PredefinedEClass to the editor

Without any further implementations it should be possible to move the EClass shapes around, resize them, remove them (context menu) and even delete them.

 


Copyright (c) SAP AG 2005, 2010.