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:
- Subclass
AbstractSlotWidget
.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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:
- Download the source code. (Please make sure to preserve the path information in the ZIP file).
- 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>
.
- 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
- 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.
- 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.