Child pages
  • Graphical Modeling with Graphiti

Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

  1. Add the following feature class to your plugin, adapting references to meta model elements to your Turing Machine definition and implementing the TODO part:

    Code Block
    themeEclipse
    languagejava
    import org.eclipse.graphiti.features.IFeatureProvider;
    import org.eclipse.graphiti.features.context.ICreateConnectionContext;
    import org.eclipse.graphiti.features.context.impl.AddConnectionContext;
    import org.eclipse.graphiti.features.impl.AbstractCreateConnectionFeature;
    import org.eclipse.graphiti.mm.pictograms.Anchor;
    import org.eclipse.graphiti.mm.pictograms.Connection;
    
    import de.cau.cs.rtprak.login.turingmodel.State;
    import de.cau.cs.rtprak.login.turingmodel.Transition;
    import de.cau.cs.rtprak.login.turingmodel.TuringFactory;
    
    /**
     * A create feature for Turing Machine transitions.
     * 
     * @author msp
     */
    public class TransitionCreateFeature extends AbstractCreateConnectionFeature {
    
        /**
         * Constructor for a transition create feature.
         * 
         * @param fp the feature provider for which the feature is created
         */
        public TransitionCreateFeature(IFeatureProvider fp) {
            super(fp, "Transition", "Create a Transition");
        }
    
        /**
         * Retrieve the state linked with the given anchor's parent.
         * 
         * @param anchor an anchor for the source or target of the new connection
         * @return the corresponding state, or {@code null} if there is none
         */
        private State getState(Anchor anchor) {
            if (anchor != null) {
                Object object = getBusinessObjectForPictogramElement(anchor.getParent());
                if (object instanceof State) {
                    return (State) object;
                }
            }
            return null;
        }
    
        /**
         * {@inheritDoc}
         */
        public boolean canStartConnection(ICreateConnectionContext context) {
            return getState(context.getSourceAnchor()) != null;
        }
    
        /**
         * {@inheritDoc}
         */
        public boolean canCreate(ICreateConnectionContext context) {
            return getState(context.getSourceAnchor()) != null
                    && getState(context.getTargetAnchor()) != null;
        }
    
        /**
         * {@inheritDoc}
         */
        public Connection create(ICreateConnectionContext context) {
            State source = getState(context.getSourceAnchor());
            State target = getState(context.getTargetAnchor());
            if (source == null || target == null) {
                throw new IllegalStateException("Cannot retrieve the source or target.");
            }
    
            // TODO create new transition with the specified source and target state
    
            AddConnectionContext addContext = new AddConnectionContext(context.getSourceAnchor(),
                    context.getTargetAnchor());
            addContext.setNewObject(transition);
            return (Connection) getFeatureProvider().addIfPossible(addContext);
        }
    
    }
  2. Add the following method to TuringFeatureProvider, adding more content to the diagram editor's palette:

    Code Block
    themeEclipse
    languagejava
    /**
     * {@inheritDoc}
     */
    @Override
    public ICreateConnectionFeature[] getCreateConnectionFeatures() {
        return new ICreateConnectionFeature[] { new TransitionCreateFeature(this) };
    }
  3. Add the following feature class to your plugin and implement the add method at the TODO note:

    Code Block
    themeEclipse
    languagejava
    import org.eclipse.graphiti.features.IFeatureProvider;
    import org.eclipse.graphiti.features.context.IAddConnectionContext;
    import org.eclipse.graphiti.features.context.IAddContext;
    import org.eclipse.graphiti.features.impl.AbstractAddFeature;
    import org.eclipse.graphiti.mm.pictograms.Connection;
    import org.eclipse.graphiti.mm.pictograms.PictogramElement;
    import org.eclipse.graphiti.services.Graphiti;
    import org.eclipse.graphiti.services.IGaService;
    
    import de.cau.cs.rtprak.login.turingmodel.Transition;
    
    /**
     * An add feature for Turing Machine transitions.
     * 
     * @author msp
     */
    public class TransitionAddFeature extends AbstractAddFeature {
    
        /**
         * Constructor for a transition add feature.
         * 
         * @param fp the feature provider for which the feature is created
         */
        public TransitionAddFeature(IFeatureProvider fp) {
            super(fp);
        }
    
        /**
         * {@inheritDoc}
         */
        public boolean canAdd(IAddContext context) {
            return context instanceof IAddConnectionContext
                    && context.getNewObject() instanceof Transition;
        }
    
        /**
         * {@inheritDoc}
         */
        public PictogramElement add(IAddContext context) {
            IAddConnectionContext addConnContext = (IAddConnectionContext) context;
            Connection connection = Graphiti.getPeCreateService().createFreeFormConnection(getDiagram());
            connection.setStart(addConnContext.getSourceAnchor());
            connection.setEnd(addConnContext.getTargetAnchor());
    
            // TODO specify the concrete representation by adding at least one graphics algorithm to the connection
            
            link(connection, context.getNewObject());
            return connection;
        }
    
    }

    Use Graphiti.getGaService() to get a service class for creating graphics algorithms and modifying their properties. You are free to design your model elements as you like. Find more information on how to solve this task in the official Graphiti Tutorial.

  4. Register the TransitionAddFeature in the getAddFeature method of the TuringFeatureProvider in the same way as done before for the StateAddFeature.
  5. Test the features in the diagram editor. The palette should now contain an entry for creating transitions.

Handling Text Labels

The last section of this tutorial is about text labels in the graphical editor. We will use such labels for state names and transition specifications. The steps required for these tasks are given only coarsely here, since you should now be able to find out yourself about the details using the Graphiti documentation.

  1. Add a Text element to states in the  StateAddFeature in order to display the name of each state.
  2. Create a new class StateDirectEditingFeature extending AbstractDirectEditingFeature and register it by overriding getDirectEditingFeature in the TuringFeatureProvider. This new feature is responsible for connecting the edited text with the name attribute of states.