[an error occurred while processing this directive]
USERS
DEVELOPERS


see also:
BACK-END
CREATEPROJECT
EXPORT
PROJECT
TAB WIDGET
 how to write a slot widget plug-in

A slot widget plug-in is more difficult to write than a tab widget plug-in. If you've never written a plug-in before, we suggest that you first write a simple tab widget plug-in to see how the process goes. Then you'll be able to tackle a slot widget plug-in with more confidence.

There are a number of things that need to be done to implement a slot widget plug-in:
  1. Subclass AbstractSlotWidget.
  2. Implement the initialize() method. This method is called by the system when the widget should construct itself. This will generally involve the construction and layout of one or more Swing GUI components.
  3. Call the setPreferredColumns() and setPreferredRows() methods. These methods should be called from the initialize() method. These methods tell the system how large your widget would like to be in terms of "columns" and "rows" on the laid-out form. For reference, the standard IntegerFieldWidget is 1 column by 1 row, the TextFieldWidget is 2 columns by 1 row, and the TextArea widget is 2 columns by 2 rows.
  4. Implement the getValues() method. This method is called by the system when the system wishes to retrieve the slot value that the widget is displaying. It is usually called as a result of the valueChanged() method (described below), but may be called at other times as well.
  5. Implement the setValues() method. This method is called by the system when it wishes the value displayed in the widget to be set to a new value. If this method is called, then any existing value in the widget should be discarded. The widget should not "listen" to the underlying knowledge base for a "slot value changed" message in order to know when to update its values. The system does this "listening" and notifies the widget through the setValues() call.
  6. Implement the isSuitable() method. This static method is called by the system to determine if the slot widget is able to handle the browsing and acquisition of the class/slot pair which are passed in as arguments. This call is usually the result of the user selecting a widget on the Forms tab. A selection on this tab results in the drop-down list of alternate widgets being updated.
  7. Implement the setEditable() method. This method is called by the system to allow the widget to configure itself so that the user may or may not be able to edit the displayed value. For example, setEditable(false) is called if the value displayed is from an included project. The widget's implementation of this method often just enables or disables one or more of the underlying Swing GUI components.
  8. Call the valueChanged() method. The widget calls this method when the user has changed the value. Often the system calls getValues() as a result of this call so that the system may retrieve the new values. The widget does not directly change the slot value in the underlying knowledge base. This latter operation is handled by the system. Note that the system ignores calls to valueChanged() from inside of the implementation of setValues(). It does so to handle the very common problem of recursive notification which happens when setting the values in the widget cause events to fire which are indistinguishable from the events which fire because the user has made a change.
We've provided example code for a slot widget plug-in that allows the user to type in a string and press a button to invert the characters of the string. The example also shows how to create the standard look of a label, series of buttons, and main component that many of Protégé's widgets use, as well as code that shows how to load an icon image in a way a that will work both during development and when the widget is packaged as a JAR.

Follow these steps to compile and run the "String Inverter" example:
  1. Download the source code. (Please make sure to preserve the path information in the ZIP file).
  2. Set up your Java development environment:
    • Use JDK 1.4 or higher for your compiler.
    • Configure the compiler to write output classes to <protege_install_dir>/plugins (replacing protege_install_dir with your Protégé installation directory).
    • Add the following JAR files to your classpath: protege.jar, looks.jar, unicode_panel.jar.
    • Pass the JVM the following parameter -Dprotege.dir=<protege_install_dir>.
  3. Compile the source code. Check that your compiler has indeed put the StringInverter class files into the "plugins/examples/slotwidget" directory. Also, please make sure that your development environment copies the meta-inf directory with the manifest file and the invert.gif image file to your output directory. Some development environments do this by default, others require you to specify that GIF and MF files should be copied to the output directory. The following is an example of what your directory structure should look like after properly downloading and compiling the example code:
    
    <protege_install_dir>
        plugins
            examples
                backend
                createprojectplugin
                exportplugin
                projectplugin
                slotwidget
                tabwidget
            meta-inf
    
  4. Run the example from your development environment, specifying edu.stanford.smi.protege.Application as the main class. Any "Duplicate plugin" warnings are benign and can be ignored.
  5. Once Protégé launches, open the newspaper example. Go to the Forms tab, select the Editor class, and select the "Name" slot widget. Drop down the "Selected Widget Type" combo box to see the list of alternate widgets. Select the StringInverter widget and an instance of the widget will appear on the form. Go to the Instances tab, select an instance of the Editor class, and try out the widget.



[an error occurred while processing this directive] [an error occurred while processing this directive] [an error occurred while processing this directive]