JMRI: Patterns and Organization
JMRI has grown and evolved with time, and you can't always see the currently-preferred structure and patterns by looking at the older code.This page attempts to describe the recommended structure and patterns, and point to examples of current best practices.
Code Organization
At the highest level, we separate test code from distributed code by putting them in separate directories within the development directory: "test" and "src". This makes it easy to compile a version without test code, to apply different tools to the two types of code, etc.
Within the source code itself, we separate out several types.
- The jmri package
- contains the basic interfaces for the system. It should contain minimal implementation code, and no non-JMRI references, esp. Swing code.
- The jmri.jmrix package
- contains all the code for connecting to specific layout hardware.
- The jmri.managers and jmri.implementations packages
- These provide default implementations for managers and other classes. This moves code out of the primary jmri package. These should not reply on apps, jmri.jmrix or jmri.jmrit.
- The jmri.util package
- Other common implementations of general use. Should not depend on jmri.jmrit or jmri.jmrix packages. The jmri.util.swing subpackage provides Swing utilities.
- Apps package
- For putting together an application, this can depend on anything.
- configurexml subdirectories
- These contain code for the XML configuration system. top-level packages, esp util & dependencies, apps
- swing subdirectories
- Contain Swing specific tools. Particularly outside the jmri.jmrit package, we are trying to separate Swing code from normal operational code. See the Swing page for more information.
- help files
- The file structure for help files echos the structure of the code. For more information, see the help page on JavaHelp pages.
- ResourceBundles
- We use resource bundles for
internationalization.
The are colocated with the code that references them,
but we are moving to a new naming convention.
To reduce loading burden, we are moving to a
pattern where the jmri.foo.FooBundle.properties
file is addressed via a static element in the
jmri.foo.FooBundle class, separate from the
properties file itself. This reduces loading
time a lot!
Note that there are also a few resource bundles that are used for other purposes, indicated in their header comments.