JMRI: Plug-in mechanisms
The original goal of the JMRI project was to produce a library upon which people could use to build their own applications. Although some people do that, more use the existing applications such as DecoderPro, PanelPro, LocoTools and JmriDemo. We want to make this more flexible by providing a way to extend those programs without having to rebuild them from scratch. This note describes mechanisms for that which will be included in JMRI version 1.4.0- CLASSPATH
DecoderPro et al are run via a java command which sets the CLASSPATH and various options. How that's actually done varies with the platform: csh scripts on Unix, bat files on Windows, application bundles on MacOS X, etc.
To make it easy to add plug-ins, these include the files "jmriplugins.jar" and "lib/jmriplugins.jar" in their CLASSPATH.
If you use that name for the jar file including your code, it will automatically be found. You can also put your classes in the "classes" directory of the startup directory, which is searched first.
If some other jar file is necessary, you'll have to edit the startup as needed.
Starting with JMRI 2.1.4, the Linux and MacOS X startups will include early in the CLASSPATH any .jar file that's found in the JMRI distribution directory. Files in the lib/ subdirectory are added at the end of the CLASSPATH. For more information, see the page on startup scripts.
- Replacement of existing classes
Note that you can directly replace any of the files in the jmri.jar distribution with your own versions by putting them in a jar file that's searched first. For example, including a modified version of a .properties file in the jmriplugins.jar file would allow you to include customized versions of menu strings. This can also be done with a .class file, for example changing the order of menu items by replacing the DecoderPro class.
- Plugin classes
Replacing a class can cause extra work in the long term, as the replaced class may be modified as JMRI evolves. So we also provide a hook on which to hang new code. After initialization is complete, the programs will attempt to invoke a static member of the form:
package jmri; public class JmriPlugin { public static void start(javax.swing.JFrame mainFrame, javax.swing.JMenuBar menuBar) {} }This method can modify the menubar by inserting, modifying or removing menus or menu items, add buttons to the main panel, etc.As people use this capability, we'll probably want to refactor some existing classes to make them easier to extend. For example, a monolithic formatting class like llnmon should be broken up into smaller pieces to make it easier to add new formats.