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 diagrams’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:

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

 

Figure: EReference between EClasses

 

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