Table of Contents
As mentioned earlier, a plugin must provide a "plugin core class" to be treated as a plugin during jEdit's startup routine. Without a core class, the plugin becomes merely a passive library that can be invoked by other plugins or by BeanShell script. The plugin core class must extend either EditPlugin or its convenience subclass, EBPlugin. We now examine these tow classes and their interaction with other jEdit classes and objects in more detail.
This abstract class is the base for every plugin core class. Its methods provide for basic interaction between the plugin and jEdit. The class has four methods which are called by jEdit at various times. None of these methods are required to be implemented, but most plugins will override at least one.
public void start
();
The jEdit startup routine calls this method for each loaded plugin. Plugins typically use this method to register information with the EditBus and perform other initialization.
public void stop
();
When jEdit is exiting, it calls this method on each plugin. If a plugin uses or creates state information or other persistent data that should be stored in a special format, this would be a good place to write the data to storage. If you use jEdit's properties API to hold "key-value" type settings for your plugins, no special processing is needed for them, since jEdit loads application properties automatically at startup and writes them to the properties file in the user's settings directory when the application exits. Most plugins find this approach sufficient for saving settings.
public void createMenuItems
(Vector menuItems);
When a View object is created, it calls this method on each plugin core class to obtain entries to be displayed in the view's Plugins menu. The menuItems parameter is a Vector that accumulates menu items and menus as it is passed from plugin to plugin.
While jEdit does not require a plugin to supply menu items, a plugin's usefulness would be extremely limited without them. The easiest way to provide menu items is to package them as entries in the plugin's property file and implement createMenuItems() with a call to jEdit's GUIUtilities.loadMenu() method. The following code illustrates this approach:
public void createMenuItems(Vector menuItems) { menuItems.addElement(GUIUtilities.loadMenu( "myplugin.menu")); } |
The parameter passed to loadMenu() is the name of a property defined in the plugin's own property file that contains menu data. The form of the property entry is a list of labels that in turn correspond to other property names and ultimately to the actual text for menu items as well as implementation code. We will detail the format of the menu data in the section called "Action Labels and Menu Items"
The GUIUtilities.loadMenuItem() method is also available for plugins that only wish to add a single menu item to the Plugins menu. The parameter names a property that points to label text in the plugin's properties file and implementing code in the plugin's actions.xml file.
public void createOptionPanes
(OptionsDialog dialog);
This method is called for each plugin during the creation of the Global Options dialog box. To show an option pane, the plugin should define an option pane class and implement createOptionPane() as follows:
dialog.addOptionPane(new MyPluginOptionPane()); |
Plugins can also define more than one option pane, grouped in an "option group". We will discuss the design and elements of the option pane API in the section called "Plugin Option Pane Classes".
This class defines two other methods which may be useful to some plugins or for debugging purposes. They are fully implemented in the parent class and used mainly by jEdit's core code.
public String getClassName
();
This shortcut method returns getClass().getName().
public EditPlugin.JAR getJAR
();
This method returns the EditPlugin.JAR data object associated with the plugin.
Every plugin core class class that uses the EditBus for receiving messages must extend this class. This class implements the EBComponent interface, required for any object that wishes to receive EditBus messages.
The EBComponent interface contains a single method that an implementing class (including any class derived from EBPlugin) must provide:
public void handleMessage
(EBMessage message);
The parameter's type, EBMessage, is another abstract class which establishes the core elements of any message that is published to the EditBus. It has two attributes: an EBComponent that is the source of the message (the source will be null in some cases), and a boolean data member, vetoed. This flag indicates whether a prior recipient of the message has determined that the message has been handled and need not be passed on to other subscribers. The flag is set by a call to the veto() method of the EBMessage. Some message classes, however, are configured so that they cannot be vetoed, to ensure they are received by all subscribers.
Message classes extending EBMessage typically add other data members and methods to provide subscribers with whatever is needed to handle the message appropriately. Descriptions of specific message classes can be found in Chapter 21.
The handleMessage() method must specify the type of responses the plugin will have for various subclasses of the EBMessage class. Typically this is done with one or more if blocks that test whether the message is an instance of a derived message class in which the plugin has an interest, as in the following example:
if(msg instanceof BufferUpdate) { // a buffer's state has changed! } else if(msg instanceof ViewUpdate) { // a view's state has changed! } // ... and so on |
Note that any object, whether or not derived from EBComponent, can send a message to the EditBus by calling the static method EditBus.send(). This method takes a single parameter, an EBMessage object that is the message being sent. Most plugins, however, will only concern themselves with receiving, not sending, messages.