Providing Create Connection Functionality

  

Creating a Create Connection Feature

 

Usually a new connection object is created graphically by using the corresponding connection tool from the editor’s tool palette. When using Graphiti you only have to provide a so called create connection feature. The integration into the platform’s UI is done by the framework.

A create connection feature has to implement the interface ICreateConnectionFeature. Instead of implementing it directly it should extend one of the available base classes. In this example we extend the base class AbstractCreateConnectionFeature.

 

We have to implement/overwrite 3 methods:

The method canCreate has to check whether the connection can be created for the given context. It has to check the business objects which are behind the source and the target anchors.

The method canStartConnection has to check whether the connection can be started at the given source anchor.

The method create has to create the business object for the connection and also has to add the graphical representation of the newly created business object to the diagram. The creation of the business object must be implemented here. To add the graphical representation, an add connection feature should be used.

 

In this example we want create an EReference between EClasses via the connection tool from the palette.

 

 

You can see the complete implementation of the create connection feature here:

 

 

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

 

public class TutorialCreateEReferenceFeature extends
      
AbstractCreateConnectionFeature {

 

    public TutorialCreateEReferenceFeature (IFeatureProvider fp) {

        // provide name and description for the UI, e.g. the palette

        super(fp, "EReference", "Create EReference");

    }

 

    public boolean canCreate(ICreateConnectionContext context) {

        // return true if both anchors belong to an EClass

        // and those EClasses are not identical

        EClass source = getEClass(context.getSourceAnchor());

        EClass target = getEClass(context.getTargetAnchor());

        if (source != null && target != null && source != target) {

            return true;

        }

        return false;

    }

 

    public boolean canStartConnection(ICreateConnectionContext context) {

        // return true if start anchor belongs to a EClass

        if (getEClass(context.getSourceAnchor()) != null) {

            return true;

        }

        return false;

    }

 

    public Connection create(ICreateConnectionContext context) {

        Connection newConnection = null;

 

        // get EClasses which should be connected

        EClass source = getEClass(context.getSourceAnchor());

        EClass target = getEClass(context.getTargetAnchor());

 

        if (source != null && target != null) {

            // create new business object

            EReference eReference = createEReference(source, target);

            // add connection for business object

            AddConnectionContext addContext =

                new AddConnectionContext(context.getSourceAnchor(), context

                    .getTargetAnchor());

            addContext.setNewObject(eReference);

            newConnection =

                (Connection) getFeatureProvider().addIfPossible(addContext);

        }

       

        return newConnection;

    }

 

    /**

     * Returns the EClass belonging to the anchor, or null if not available.

     */

    private EClass getEClass(Anchor anchor) {

        if (anchor != null) {

            Object object =

                getBusinessObjectForPictogramElement(anchor.getParent());

            if (object instanceof EClass) {

                return (EClass) object;

            }

        }

        return null;

    }

 

    /**

    * Creates a EReference between two EClasses.

    */

    private EReference createEReference(EClass source, EClass target) {

        EReference eReference = EcoreFactory.eINSTANCE.createEReference();

        eReference.setName("new EReference");

        eReference.setEType(target);

        eReference.setLowerBound(0);

        eReference.setUpperBound(1);

        source.getEStructuralFeatures().add(eReference);

        return eReference;

   }

}

 

 

Additionally the feature provider has to deliver our newly created feature (overwrite the method getCreateConnectionFeatures).

This implementation can be seen here:

 

   

    @Override

    public ICreateConnectionFeature[] getCreateConnectionFeatures() {

        return new ICreateConnectionFeature[] {

            new TutorialCreateEReferenceFeature (this) };

    }

 

 

Before we can run the editor we have to add anchors to the container shapes of the EClasses. Anchors are explained later in detail.  

For now simply create an anchor at end of the add method of the TutorialAddEClassFeature, as shown in the following code snippet:

 

 

    public PictogramElement add(IAddContext context) {

 

       

        // ... EXiSTING CODING ...

       

        // add a chopbox anchor to the shape

        peCreateService.createChopboxAnchor(containerShape);

  

        // call the layout feature

        layoutPictogramElement(containerShape);

 

        return containerShape;

    } 

 

 

 

Test: Create a Connection

 

 Now start the editor and test the create connection feature:

  1. create or open a  diagram
  2. create two new EClasses (existing EClasses don’t work because they have no anchor)
  3. click on “EReference” which should be now available as connection tool in the palette
  4. move the mouse over the EClasses; you can see that it is allowed to start the connection
  5. click on one EClass
  6. move mouse over the start EClass; you can see that it is not allowed to end the connection on the same EClass
  7. move the mouse over the other EClass and click
  8. the new connection should be created

 

 


Copyright (c) SAP AG 2005, 2010.