### Navigation

- index
- previous |
- Astah Plug-in Tutorial v1.0 documentation »

# Astah Plug-in snippets

## Astah API utilities

Some methods easing your Astah model operation

      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
     14
     15
     16
     17
     18
     19
     20
     21
     22
     23
     24
     25
     26
     27
     28
     29
     30
     31
     32
     33
     34
     35
     36
     37
     38
     39
     40
     41
     42
     43
     44
     45
     46
     47
     48
     49
     50
     51
     52
     53
     54
     55
     56
     57
     58
     59
     60
     61
     62
     63
     64
     65
     66
     67
     68
     69
     70
     71
     72
     73
     74
     75
     76
     77
     78
     79
     80
     81
     82
     83
     84
     85
     86
     87
     88
     89
     90
     91
     92
     93
     94
     95
     96
     97
     98
     99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    /*
     * Please change this class's package to your genearated Plug-in's package.
     * Plug-in's package namespace => com.example
     *   com.change_vision.astah.extension.plugin => X
     *   com.example                              => O
     *   com.example.internal                     => O
     *   learning                                 => X
     */
    package com.example.internal;

    import java.util.ArrayList;
    import java.util.List;

    import com.change_vision.jude.api.inf.exception.InvalidEditingException;
    import com.change_vision.jude.api.inf.model.IAttribute;
    import com.change_vision.jude.api.inf.model.IClass;
    import com.change_vision.jude.api.inf.model.IClassifierTemplateParameter;
    import com.change_vision.jude.api.inf.model.IElement;
    import com.change_vision.jude.api.inf.model.IGeneralization;
    import com.change_vision.jude.api.inf.model.INamedElement;
    import com.change_vision.jude.api.inf.model.IOperation;
    import com.change_vision.jude.api.inf.model.IPackage;
    import com.change_vision.jude.api.inf.model.IParameter;
    import com.change_vision.jude.api.inf.model.IRealization;

    public class AstahUtils {

      /**
       * Get classes owned by the owner
       *
       * @param  owner   Class or Package
       * @return Classes nesting in the owner
       */
      public static IClass[] getOwnedClasses(Object owner) {
        if (owner instanceof IClass) {
          return ((IClass) owner).getNestedClasses();
        } else if (owner instanceof IPackage) {
          List<IClass> classes = new ArrayList<IClass>();
          for (INamedElement element : ((IPackage) owner).getOwnedElements()) {
            if (element instanceof IClass) {
              classes.add((IClass) element);
            }
          }
          return classes.toArray(new IClass[classes.size()]);
        } else {
          return new IClass[0];
        }
      }

      /**
       * Get a owner's class whose name is specified
       *
       * @param owner Class or Package
       * @param name  Owner name
       * @return An owner's class whose name is specified
       */
      public static IClass getOwnedClass(Object owner, String name) {
        if (owner instanceof IClass) {
          return getNestedClass((IClass) owner, name);
        } else if (owner instanceof IPackage) {
          return getOwnedElement((IPackage) owner, name, IClass.class);
        } else {
          return null;
        }
      }

      /**
       * Get an INamedElement whose name is specified in the target package
       *
       * @param owner Target package
       * @param name  Name
       * @return a namedElement whose name is specified in the target package
       */
      public static INamedElement getOwnedElement(IPackage owner, String name) {
        return getOwnedElement(owner, name, INamedElement.class);
      }

      /**
       * Get an Object whose name and type are specified in the target package
       *
       * @param owner       Target package
       * @param name        Name
       * @param elementType The child class type of INamedElement
       * @return  the child class type of INamedElement whose name and type are specified in the target package
       */
      public static <T extends INamedElement> T getOwnedElement(IPackage owner,
          String name, Class<T> elementType) {
        for (INamedElement element : owner.getOwnedElements()) {
          if (name.equals(element.getName())) {
            if (elementType.isInstance(element)) {
              return elementType.cast(element);
            }
          }
        }
        return null;
      }

      /**
       * Get a class whose name is specified in the target class
       *
       * @param owner Target class
       * @param name  Name
       * @return a class whose name is specified in the target class
       */
      public static IClass getNestedClass(IClass owner, String name) {
        for (IClass element : owner.getNestedClasses()) {
          if (name.equals(element.getName())) {
            return element;
          }
        }
        return null;
      }

      /**
       * Get a generalization whose parent class is specified
       *
       * @param owner     Target class
       * @param superType Parent class
       * @return Generalization
       *         Null if the superType isn't generalized by the owner
       */
      public static IGeneralization getGeneralization(IClass owner,
          IClass superType) {
        for (IGeneralization generalization : owner.getGeneralizations()) {
          if (superType.equals(generalization.getSuperType())) {
            return generalization;
          }
        }
        return null;
      }

      /**
       * Get a generalization whose child class is specified
       *
       * @param owner   Target class
       * @param subType Child class
       * @return Generalization
       *         Null if the owner isn't generalized by the subType
       */
      public static IGeneralization getSpecialization(IClass owner, IClass subType) {
        for (IGeneralization generalization : owner.getSpecializations()) {
          if (subType.equals(generalization.getSubType())) {
            return generalization;
          }
        }
        return null;
      }

      /**
       * Get a realization whose supplier class is specified
       *
       * @param owner    Target class
       * @param supplier Supplier Class
       *
       * @return Realization
       *         Null if the owner isn't realized by the supplier
       */
      public static IRealization getClientRealization(IClass owner,
          IClass supplier) {
        for (IRealization realization : owner.getClientRealizations()) {
          if (supplier.equals(realization.getSupplier())) {
            return realization;
          }
        }
        return null;
      }

      /**
       * Get a realization whose client class is specified
       *
       * @param owner    Target class
       * @param client   Client Class
       *
       * @return Realization
       *         Null if the client isn't realized by the owner
       */
      public static IRealization getSupplierRealization(IClass owner,
          IClass client) {
        for (IRealization realization : owner.getSupplierRealizations()) {
          if (client.equals(realization.getClient())) {
            return realization;
          }
        }
        return null;
      }

      /**
       * Get a owner's template parameter whose name is specified
       *
       * @param owner  Target class
       * @param name   Parameter Name
       * @return  Template Parameter
       *          Null if the template parameter dosn't exist
       */
      public static IClassifierTemplateParameter getTemplateParameter(
          IClass owner, String name) {
        for (IClassifierTemplateParameter templateParameter : owner
            .getTemplateParameters()) {
          if (name.equals(templateParameter.getName())) {
            return templateParameter;
          }
        }
        return null;
      }

      /**
       * Get a owner's attribute whose name is specified
       *
       * @param owner Target class
       * @param name  Attribute name
       * @return Attribute
       *         Null if the attribute dosn't exist
       */
      public static IAttribute getAttribute(IClass owner, String name) {
        for (IAttribute attribute : owner.getAttributes()) {
          if (name.equals(attribute.getName())) {
            return attribute;
          }
        }
        return null;
      }

      /**
       * Get a owner's operation whose name is specified。
       *
       * @param owner Target class
       * @param name  Operation name
       * @return Operation
       *         Null if the operation dosn't exist
       */
      public static IOperation getOperation(IClass owner, String name,
          Object[] parameterTypes) {
        for (IOperation operation : owner.getOperations()) {
          if (name.equals(operation.getName())) {
            IParameter[] parameters = operation.getParameters();
            if (matches(parameters, parameterTypes)) {
              return operation;
            }
          }
        }
        return null;
      }

      /**
       * set a class as an interface
       *
       * @param type        Target class
       * @param isInterfase True if the class is an interface
       *                    False if the class isn't an interface
       */
      public static void setInterface(IClass type, boolean isInterface)
          throws InvalidEditingException {
        if (isInterface) {
          addStereotype(type, "interface");
        } else {
          type.removeStereotype("interface");
        }
      }

      /**
       * Add a stereotype to an element
       * @param element Target element
       * @param stereotype Added stereotype
       * @return True if the stereotype is added
       *         False if the stereotype has been owned by the element
       */
      public static boolean addStereotype(IElement element, String stereotype)
          throws InvalidEditingException {
        for (String exists : element.getStereotypes()) {
          if (stereotype.equals(exists)) {
            return false;
          }
        }
        element.addStereotype(stereotype);
        return true;
      }

      static boolean matches(IParameter[] parameters, Object[] parameterTypes) {
        if (parameterTypes.length != parameters.length) {
          return false;
        }
        for (int i = 0; i < parameterTypes.length; i++) {
          Object type = parameterTypes[i];
          if (type instanceof IClass) {
            if (!type.equals(parameters[i].getType())) {
              return false;
            }
          } else {
            if (!type.equals(parameters[i].getTypeExpression())) {
              return false;
            }
          }
        }
        return true;
      }

    }

Methods for handling Astah API

      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
     14
     15
     16
     17
     18
     19
     20
     21
     22
     23
     24
     25
     26
     27
     28
     29
     30
     31
     32
     33
     34
     35
     36
     37
     38
     39
     40
     41
     42
     43
     44
     45
     46
     47
     48
     49
     50
     51
     52
     53
     54
     55
     56
     57
     58
     59
     60
     61
     62
     63
     64
     65
     66
     67
     68
     69
     70
     71
     72
     73
     74
     75
     76
     77
     78
     79
     80
     81
     82
     83
     84
     85
     86
     87
     88
     89
     90
     91
     92
     93
     94
     95
     96
     97
     98
     99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    /*
     * Please change this class's package to your genearated Plug-in's package.
     * Plug-in's package namespace => com.example
     *   com.change_vision.astah.extension.plugin => X
     *   com.example                              => O
     *   com.example.internal                     => O
     *   learning                                 => X
     */
    package com.example.internal;

    import javax.swing.JFrame;

    import com.change_vision.astah.extension.plugin.util.exception.APIException;
    import com.change_vision.jude.api.inf.editor.BasicModelEditor;
    import com.change_vision.jude.api.inf.editor.ClassDiagramEditor;
    import com.change_vision.jude.api.inf.editor.IDiagramEditorFactory;
    import com.change_vision.jude.api.inf.editor.IModelEditorFactory;
    import com.change_vision.jude.api.inf.exception.InvalidEditingException;
    import com.change_vision.jude.api.inf.exception.InvalidUsingException;
    import com.change_vision.jude.api.inf.model.IClassDiagram;
    import com.change_vision.jude.api.inf.project.ProjectAccessor;
    import com.change_vision.jude.api.inf.project.ProjectAccessorFactory;
    import com.change_vision.jude.api.inf.view.IDiagramViewManager;
    import com.change_vision.jude.api.inf.view.IViewManager;

    /**
     * A class containing utilities easing astah* API operation
     * Instance must be created before this class is used.
     */
    public class AstahAPIUtils {

      /**
       * Get diagramViewManager
       */
      public IDiagramViewManager getDiagramViewManager() {
        IViewManager viewManager = getViewManager();
          IDiagramViewManager diagramViewManager = viewManager.getDiagramViewManager();
        return diagramViewManager;
      }

      /**
       * Get ClassDiagramEditor by which models on class diagrams can be modified
       */
      public ClassDiagramEditor getClassDiagramEditor() {
        try {
          return getDiagramEditorFactory().getClassDiagramEditor();
        } catch (InvalidUsingException e) {
          throw new APIException(e);
        }
      }

      /**
       * Get BasicModelEditor by which basic models can be modified
       *
       * @return BasicModelEditor
       */
      public BasicModelEditor getBasicModelEditor() {
        try {
          return getModelEditorFactory().getBasicModelEditor();
        } catch (InvalidEditingException e) {
          throw new APIException(e);
        }
      }

      /**
       * Get ProjectAccessor by which astah* project can be operated
       */
      public ProjectAccessor getProjectAccessor() {
        ProjectAccessor projectAccessor = null;
        try {
          projectAccessor = ProjectAccessorFactory.getProjectAccessor();
        } catch (ClassNotFoundException e) {
              throw new IllegalStateException(e);
        }
        if(projectAccessor == null) throw new IllegalStateException("projectAccessor is null.");
        return projectAccessor;
      }

      /**
       * Get JFrame representing the main window of astah*
       *
       * @return JFrame
       */
      public JFrame getMainFrame() {
        return getProjectAccessor().getViewManager().getMainFrame();
      }

      /**
       * Get the edition of running astah*
       */
      public String getEdition() {
        return getProjectAccessor().getAstahEdition();
      }

      private IViewManager getViewManager() {
        ProjectAccessor projectAccessor = getProjectAccessor();
        IViewManager viewManager = projectAccessor.getViewManager();
        if(viewManager == null) throw new IllegalStateException("ViewManager is null.");
        return viewManager;
      }

      private IModelEditorFactory getModelEditorFactory() {
        ProjectAccessor projectAccessor = getProjectAccessor();
        IModelEditorFactory modelEditorFactory = projectAccessor.getModelEditorFactory();
        if(modelEditorFactory == null) throw new IllegalStateException("modelEditorFactory is null.");
        return modelEditorFactory;
      }

      private IDiagramEditorFactory getDiagramEditorFactory() {
        ProjectAccessor projectAccessor = getProjectAccessor();
        IDiagramEditorFactory diagramEditorFactory = projectAccessor.getDiagramEditorFactory();
        if(diagramEditorFactory == null) throw new IllegalStateException("diagramEditorFactory is null.");
        return diagramEditorFactory;
      }

    }

## How to create a menu

Please get detailed snippets by reading the tutorial or analyzing the tutorialexample project.

An example of plugin.xml

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    <?xml version="1.0" encoding="UTF-8"?>
    <plugin>
       <extension point="com.change_vision.astah.ui.actionSets">
          <actionSet
                label="%action_set_label"
                visible="true"
                id="com.example.helloworld.actionSet">
             <menu
                   id="helloworld"
                   label="%menu_group"
                   path="tool/helloworld">
             </menu>
             <action
    			   label="%menu_label"
                   icon="icons/sample.gif"
                   class="com.example.TemplateAction"
                   tooltip="%menu_tooltip"
                   menubarPath="tool/helloworld/"
                   id="com.example.actions.HelloWorldAction">
             </action>
         </actionSet>
       </extension>
    </plugin>

An example of action

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    /*
     * Please change this class's package to your genearated Plug-in's package.
     * Plug-in's package namespace => com.example
     *   com.change_vision.astah.extension.plugin => X
     *   com.example                              => O
     *   com.example.internal                     => O
     *   learning                                 => X
     */
    package com.example.actions;

    import javax.swing.JOptionPane;
    import com.change_vision.jude.api.inf.ui.IPluginActionDelegate;
    import com.change_vision.jude.api.inf.ui.IWindow;

    public class HelloWorldAction implements IPluginActionDelegate {

      public Object run(IWindow window) throws UnExpectedException {
          try {
              JOptionPane.showMessageDialog(window.getParent(), "Hello World");

          } catch (Exception e) {
            JOptionPane.showMessageDialog(window.getParent(), "Exception occured", "Alert", JOptionPane.ERROR_MESSAGE);
              throw new UnExpectedException();
          }
          return null;
      }
    }

## How to create an extention view

Please get detailed snippets by reading the tutorial or analyzing the tutorialexample project.

An example of plugin.xml

    1
    2
    3
    4
    5
    6
    7
    8
    9
    <?xml version="1.0" encoding="UTF-8"?>
    <plugin>
       <extension point="com.change_vision.astah.ui.view">
            <view
                id="com.example.internal.HelloWorldView"
                type="extraTab"
                class="com.example.internal.HelloWorldView" />
       </extension>
    </plugin>

An example of view

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    /*
     * Please change this class's package to your genearated Plug-in's package.
     * Plug-in's package namespace => com.example
     *   com.change_vision.astah.extension.plugin => X
     *   com.example                              => O
     *   com.example.internal                     => O
     *   learning                                 => X
     */
    package com.example.internal;

    import java.awt.BorderLayout;
    import java.awt.Component;
    import java.awt.Container;

    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.JScrollPane;

    import com.change_vision.jude.api.inf.project.ProjectAccessor;
    import com.change_vision.jude.api.inf.project.ProjectAccessorFactory;
    import com.change_vision.jude.api.inf.project.ProjectEvent;
    import com.change_vision.jude.api.inf.project.ProjectEventListener;
    import com.change_vision.jude.api.inf.ui.IPluginExtraTabView;
    import com.change_vision.jude.api.inf.ui.ISelectionListener;

    public class HelloWorldView extends JPanel implements IPluginExtraTabView, ProjectEventListener {

        public HelloWorldView() {
            initComponents();
        }

        private void initComponents() {
            setLayout(new BorderLayout());
            add(createLabelPane(), BorderLayout.CENTER);
            addProjectEventListener();
        }

      private void addProjectEventListener() {
        try {
          ProjectAccessor projectAccessor = ProjectAccessorFactory.getProjectAccessor();
          projectAccessor.addProjectEventListener(this);
        } catch (ClassNotFoundException e) {
          e.getMessage();
        }
      }

      private Container createLabelPane() {
          JLabel label = new JLabel("hello world");
            JScrollPane pane = new JScrollPane(label);
            return pane;
        }

        @Override
        public void projectChanged(ProjectEvent e) {
        }

        @Override
        public void projectClosed(ProjectEvent e) {
        }

         @Override
        public void projectOpened(ProjectEvent e) {
        }

      @Override
      public void addSelectionListener(ISelectionListener listener) {
      }

      @Override
      public Component getComponent() {
        return this;
      }

      @Override
      public String getDescription() {
        return "Show Hello World here";
      }

      @Override
      public String getTitle() {
        return "Hello World View";
      }

      public void activated() {

      }

      public void deactivated() {

      }
    }

## How to extend Drag and Drop

Please get detailed snippets by analyzing the com.change_vision.astah.extension.plugin.drag_and_drop_example project. To add DropTargetListener during the initialization of a plugin, Activator#start(BundleContext context) should be implemented.

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    package com.example;

    import org.osgi.framework.BundleActivator;
    import org.osgi.framework.BundleContext;

    import com.example.internal.ClassDiagramDropExtension;
    import com.example.internal.util.AstahAPIUtils;
    import com.change_vision.jude.api.inf.view.IDiagramViewManager;

    public class Activator implements BundleActivator {

      private AstahAPIUtils utils = new AstahAPIUtils();

      public void start(BundleContext context) {
        ClassDiagramDropExtension diagramDropTargetListener = new ClassDiagramDropExtension();
        IDiagramViewManager diagramViewManager = utils.getDiagramViewManager();
        diagramViewManager.addDropTargetListener(diagramDropTargetListener);

      }

      public void stop(BundleContext context) {
      }

    }

An example showing how to implement DropTargetListener

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    /*
     * Please change this class's package to your genearated Plug-in's package.
     * Plug-in's package namespace => com.example
     *   com.change_vision.astah.extension.plugin => X
     *   com.example                              => O
     *   com.example.internal                     => O
     *   learning                                 => X
     */
    package com.example.internal;

    import java.awt.datatransfer.DataFlavor;
    import java.awt.datatransfer.Transferable;
    import java.awt.dnd.DnDConstants;
    import java.awt.dnd.DropTargetDragEvent;
    import java.awt.dnd.DropTargetDropEvent;
    import java.awt.dnd.DropTargetEvent;
    import java.io.File;
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Set;

    import com.change_vision.jude.api.inf.model.IClassDiagram;
    import com.change_vision.jude.api.inf.view.DiagramDropTargetListener;

    public final class ClassDiagramDropExtension extends DiagramDropTargetListener {

      public ClassDiagramDropExtension() {
        super(IClassDiagram.class);
      }

      @Override
      public void dropExternalData(DropTargetDropEvent dtde) {
        if(dtde.isLocalTransfer()) return;

        if(dtde.isDataFlavorSupported(DataFlavor.stringFlavor)) {
          System.out.println("ClassDiagramDropExtension.stringFlavor" + getURLStringFromDropContent(dtde));
          dtde.dropComplete(true);
        } else if (dtde.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) {
          List<File> files = getFilesFromDropContent(dtde);
          System.out.println("javaFileListFravor" + files);
          dtde.dropComplete(true);
        }
      }

      private String getURLStringFromDropContent(DropTargetDropEvent dtde) {
        dtde.acceptDrop(DnDConstants.ACTION_LINK);
        Transferable target = dtde.getTransferable();

        String urlString;
        try {
          urlString = (String)target.getTransferData(DataFlavor.stringFlavor);
        } catch (Exception e) {
          urlString = "";
        }
        return urlString;
      }

      @SuppressWarnings("unchecked")
      private List<File> getFilesFromDropContent(DropTargetDropEvent dtde) {
        dtde.acceptDrop(DnDConstants.ACTION_COPY);
        List<File> list;
        try {
          list = (List<File>) dtde.getTransferable().getTransferData(DataFlavor.javaFileListFlavor);
        } catch (Exception e) {
          list = new ArrayList<File>();
        }
        return list;
      }

      @Override
      public void dropModels(DropTargetDropEvent dtde, Set<?> models) {
      }

      @Override
      public void dragEnter(DropTargetDragEvent dtde) {
      }

      @Override
      public void dragExit(DropTargetEvent dte) {
      }

      @Override
      public void dragOver(DropTargetDragEvent dtde) {
      }

      @Override
      public void dropActionChanged(DropTargetDragEvent dtde) {
      }
    }

### Navigation

- index
- previous |
- Astah Plug-in Tutorial v1.0 documentation »