Writing a Plugin for a Component of the Graphical User Interface

Preliminaries

This document explains how new GUI components can be added to the Gravisto editor using its plugin mechanism. For the following example(s) it is necessary to have Graffiti_Core and Graffiti_Editor in your compile classpath.

Getting Started

Like for every plugin it is assumed that you provide a valid plugin description file first. The next step is creating a new plugin adapter, e.g. GuiComponentsTestPlugin. For a GUI plugin which is member of the package de.chris.plugins.guis.test it looks similar to the following:

package de.chris.plugins.guis.test;

import org.graffiti.plugin.EditorPluginAdapter;
import org.graffiti.plugin.gui.GraffitiComponent;

/**
 * This is a simple example for a GUI component plugin for Graffiti.
 *
 * @author chris
 */
public class GuiComponentsTestPlugin
    extends EditorPluginAdapter
{
    public GuiComponentsTestPlugin()
    {
        this.guiComponents = new GraffitiComponent[4];

        // menu example
        this.guiComponents[0] = new TestMenu();
        this.guiComponents[1] = new TestItem();

        // toolbar example
        this.guiComponents[2] = new TestToolbar();
        this.guiComponents[3] = new TestButton();
    }
}
      

Because a single GUI plugin can contain more than GUI elements, the inherited member array guiComponents can be filled with an arbitrary number of GUI components objects. The above example adds a new menu containing a menu item and a new toolbar containing a button to the editor. For this every GUI object must implement the interfaces org.graffiti.plugin.gui.GraffitiComponent. If it is also implements the interface org.graffiti.plugin.gui.GraffitiContainer it is possible to add some "sub items" afterwards because then it has an unique id to which other components can refer to.

Adding Menus and Menu Entries

In the following the code of the TestMenu is added to GuiComponentsTestPlugin::guiComponents[0].

package de.chris.plugins.guis.test;

import org.graffiti.plugin.gui.GraffitiContainer;
import org.graffiti.plugin.gui.GraffitiMenu;

public class TestMenu
    extends GraffitiMenu
    implements GraffitiContainer
{
    // to avoid collisions let ID be package name + ".menus." + name of the menu
    public static final String ID = "de.chris.plugins.guis.test.menus.Test";

    public TestMenu()
    {
        super();
        setName("Test");
        setText("Test");
        setMnemonic('T');
        setEnabled(true);
    }

    public String getId()
    {
        return ID;
    }
}
      

The class TestMenu is derived from GraffitiMenu which is an implementation of GraffitiComponent. In the constructor the name of the menu and the text which appears in the menu bar of Gravisto is set. Further a keyboard shortcut ALT + t is defined to open the menu Test and it is enabled which means it is available at the moment ant not grayed out.
For fulfilling the interface GraffitiContainer each menu needs a unique ID. To achieve this, it is suggested to take a combination in this order of the package name + ".menus." + name of the menu.

Now we need some menu item which is an entry of our Test menu. Therefore we use the following code which is therefore added to GuiComponentsTestPlugin::guiComponents[1]:

package de.chris.plugins.guis.test;

import javax.swing.ImageIcon;

import org.graffiti.plugin.actions.GraffitiAction;
import org.graffiti.plugin.gui.GraffitiContainer;
import org.graffiti.plugin.gui.GraffitiMenuItem;

public class TestItem
    extends GraffitiMenuItem
{
    public TestItem()
    {
        super(TestMenu.ID, new TestMenuItemAction("Test Action"));

        setText(((GraffitiAction) getAction()).getName()); // default
        setMnemonic('T');
        setIcon(new ImageIcon(getClass().getResource("smiley.gif")));
        setToolTipText("This is a test tooltip for the test menu item.");
    }
}
      

In the constructor the super constructor in GraffitiMenuItem is called which adds this menu item to the menu with the given ID (here to the Test menu of above with ID TestMenu::ID so that we obtain Test > Test Action) and defines the action which should be performed when clicking on it. The method setText sets the text which appears in the menu and setMnemonic defines t as a keyboard shortcut for choosing this item. The following two methods are two gimmicks which set an icon in front of the menu items text and define a tooltip which appears when the mouse cursor stays over the item.
Of course it is also possible to add menu items to the existing standard menus. The procedure is the same as described above, only the right identifier for the standard menu must be chosen. Here we have a list of them:

It remains to show what is the action TestAction.

package de.chris.plugins.guis.test;

import java.awt.event.ActionEvent;

import org.graffiti.help.HelpContext;
import org.graffiti.plugin.actions.GraffitiAction;

public class TestMenuItemAction
    extends GraffitiAction
{
    public TestMenuItemAction(String name)
    {
        super(name, null);
    }

    public boolean isEnabled()
    {
        return super.enabled;
    }

    public HelpContext getHelpContext()
    {
        return null;
    }

    public void actionPerformed(ActionEvent e)
    {
        System.out.println("clicked on test menu item");
    }
}
      

This action is a GraffitiAction which simply prints out "clicked on test menu item" when its actionPerformed method is called by clicking on Test > Test Action. This would be the place where the normal action to perform should be called, e.g. calling an algorithm.

Adding Toolbars and Toolbar Buttons

In the following there is the code of the TestToolbar added to GuiComponentsTestPlugin::guiComponents[2].

package de.chris.plugins.guis.test;

import org.graffiti.plugin.gui.GraffitiContainer;
import org.graffiti.plugin.gui.GraffitiToolbar;

public class TestToolbar
    extends GraffitiToolbar
    implements GraffitiContainer
{
    // to avoid collisions let ID be package name + ".toolbars." + name of toolbar
    public static final String ID = "de.chris.plugins.guis.test.toolbars.Testtoolbar";

    public TestToolbar()
    {
        super(ID);
    }

    public String getId()
    {
        return ID;
    }
}
      

The class TestToolbar is derived from GraffitiToolbar which is an implementation of GraffitiComponent. For fulfilling the interface GraffitiContainer each toolbar needs a unique ID. To achieve this, it is suggested to take a combination in this order of the package name + ".toolbars." + name of the toolbar.
In the constructor the toolbar is created by calling the super constructor with the ID.

Now we need some button which is an entry of our test toolbar. Therefore we use the following code which is therefore added to GuiComponentsTestPlugin::guiComponents[3]:

package de.chris.plugins.guis.test;

import javax.swing.ImageIcon;

import org.graffiti.plugin.gui.GraffitiButton;
import org.graffiti.plugin.gui.GraffitiContainer;

public class TestButton
    extends GraffitiButton
{
    public TestButton()
    {
        super(TestToolbar.ID, new TestToolbarButtonAction());
        setToolTipText("This is a test tooltip for the test button.");
        setIcon(new ImageIcon(TestButton.class.getResource("smiley.gif")));
    }

    public String getId()
    {
        return ID;
    }
}
      

In the constructor the super constructor in GraffitiButton is called which adds this button to a toolbar with the given ID (here to the test toolbar of above with ID TestToolbar::ID) and defines the action which should be performed when clicking on it. The method setIcon sets the icon of the button. setToolTipText defines a tooltip which appears when the mouse cursor stays over the button.

It remains to show what is the action TestToolbarButtonAction.

package de.chris.plugins.guis.test;

import java.awt.event.ActionEvent;

import org.graffiti.help.HelpContext;

import org.graffiti.plugin.actions.GraffitiAction;

public class TestToolbarButtonAction
    extends GraffitiAction
{
    public TestToolbarButtonAction()
    {
        super(null, null);
    }

    public boolean isEnabled()
    {
        return super.enabled;
    }

    public HelpContext getHelpContext()
    {
        return null;
    }

    public void actionPerformed(ActionEvent e)
    {
        System.out.println("clicked on test toolbar button");
    }
}
      

This action is a GraffitiAction which simply prints out "clicked on test toolbar button" when its actionPerformed method is called by clicking on the button. This would be the place where the normal action to perform should be called, e.g. calling an algorithm.