# Providing Custom Functionality

If the tool developer wants to add some tool specific functionality (e.g. context menu actions which can change the business and/or the pictogram model) the predefined features are not enough. In this case we need a more general feature. For that purpose the framework provides a custom feature. Examples for a custom feature are rename, change color, check out, etc.

## Create a Custom Feature

A custom feature has to implement the interface ICustomFeature. Instead of implementing it directly it should extend one of the available base classes. In this example we extend the base class AbstractCustomFeature.

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

- The method canExecute has to check whether the custom feature can be executed on the current pictogram element of the given context.
- The method execute has to perform the custom specific stuff.
- These two methods receive a custom context as parameter. Interface ICostomContext provides the inner pictogram element and the inner graphics algorithm additionally to the (selected) pictogram element. These are the inner elements the mouse pointer is placed / clicked on.
- Currently only custom features receive the information on the inner elements additionally to the selected/selectable ones.

The methods getName / getDescription have to return the information for the UI representation.

In this example we want to implement a custom feature which opens a popup-dialog to change the EClass name. This custom feature should be available and enabled in the context menu if exactly one EClass is selected.

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

package org.eclipse.graphiti.examples.tutorial.features;
public class TutorialRenameEClassFeature extends AbstractCustomFeature {
private boolean hasDoneChanges = false;
public TutorialRenameEClassFeature(IFeatureProvider fp) {
super(fp);
}
@Override
public String getName() {
return "Rename EClass";
}
@Override
public String getDescription() {
return "Change the name of the EClass";
}
@Override
public boolean canExecute(ICustomContext context) {
// allow rename if exactly one pictogram element
// representing a EClass is selected
boolean ret = false;
PictogramElement[] pes = context.getPictogramElements();
if (pes != null && pes.length == 1) {
Object bo = getBusinessObjectForPictogramElement(pes[0]);
if (bo instanceof EClass) {
ret = true;
}
}
return ret;
}
@Override
public void execute(ICustomContext context) {
PictogramElement[] pes = context.getPictogramElements();
if (pes != null && pes.length == 1) {
Object bo = getBusinessObjectForPictogramElement(pes[0]);
if (bo instanceof EClass) {
EClass eClass = (EClass) bo;
String currentName = eClass.getName();
// ask user for a new class name
String newName = ExampleUtil.askString(getName(), getDescription(),
currentName);
if (newName != null && !newName.equals(currentName)) {
this.hasDoneChanges = true;
eClass.setName(newName);
updatePictogramElement(pes[0]);
}
}
}
}
@Override
public boolean hasDoneChanges() {
return this.hasDoneChanges;
}
}

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

This implementation can be seen here:

@Override
public ICustomFeature[] getCustomFeatures(ICustomContext context) {
return new ICustomFeature[] { new TutorialRenameEClassFeature(this) };
}

## Test: Rename a EClass with a Custom Popup-Dialog

Now start the editor and test this new custom feature:

1. create or open a diagram
2. create a new EClass "A"
3. open the context menu on this newly created EClass; choose "Rename EClass"
4. rename this EClass to "B"
5. the diagram will be updated automatically with new class name