JMRI is the Java Model Railroad Interface. This is a collection of software tools for controlling a model railroad. Originally DCC-specific, it has since been extended to support other types of control environments. JMRI consists of several tools that operate independently, the two most commonly used are DecoderPro, which programs DCC decoders through a simple form-based interface and keeps a database of your locomotives and their decoder settings, and PanelPro, which allows control panels to be created for accessory decoders and similar systems. JMRI is available for Windows, OS X (Mac) and Linux computers, and it is free.

JMRI also provides support for using Internet-connected devices as throttles (“cabs”) for a DCC layout. This is mainly applicable to Smart Phone use, and requires an app for the specific smartphone. See the page linked above for additional details.

This page is about using JMRI for layout control, and this is specific to PanelPro, although it does touch on some other aspects.

Installing JMRI

This is pretty straightforward, usually: download the program and put the programs where you usually put applications (on Windows, run an installer, on the Mac just open the .dmg you downloaded and drag the JMRI folder to Applications). It’s a good idea to read the release notes for the specific version, particularly if you are upgrading to a new version, as changes could be incompatible with older versions and require some work. And backup your old version first, just in case.

For OS X users, as of OS X 10.11 (known as “El Capitan”) signed drivers are required by the operating system (and older drivers were not “signed”), so you need to get a new driver for your USB interface from the company that made that hardware.

One of the recent trends has been the use of JMRI on Raspberry Pi computers, particularly as a Wi-Fi interface for smartphones. Older versions of the Raspbian operating system had some issues with this, although this seems to have been improved in later versions: the “rxtx” serial library for using the Pi’s GPIO pins was a problem in older versions, and there was some requirement around updating JAVA, but both seem to have been fixed as of the “Jessie” release in late 2015, if not earlier.

There’s a script for installing JMRI on a Pi, although I think it’s specific to an older release at present. It’s also designed to operate the “screen” of the JMRI system on another computer, so it installs a version of VNC for remote access. If you want the Pi to use an attached screen, this is unnecessary and may require you to undo some things to use a local screen. I haven’t used this script myself, although I have read it and used the information there to figure out my own approach to installing JMRI on a Pi.

This is complex enough that I’ve created my own page on installing JMRI on a Pi. That’s just my way of doing things, and not the only way, but is does describe the basic things needed under the current version of Raspbian (Jessie).

Once installed, JMRI keeps files it creates in an assigned per-user directory. On the Mac, this is ~/Library/Preferences/JMRI (the Library folder is the one in your home directory, but it’s invisible by default on recent versions of OS X; to reveal it, open a window and go to your home directory, select menu View / Show View Options, and then click the Show Library Folder checkbox at the bottom of the list). With Windows a JMRI folder in your home directory is used. On Linux systems, ~/.jmri is used (that’s a normally-invisible file with a name starting with a period in your home directory). This is where you can find the XML files it creates to record panel definitions, among other things.

XML files are human-readable text files with a very specific structure that is easy for computers to process. However to edit them, you need to use an editor that won’t try to reformat the file (and it’s really a good idea to make a copy and save it before trying anything). You can find a number of free editors designed to work on XML if you look around, or just use a simple text editor. On the Mac, TextEdit in “simple text” mode will work, except that it always sticks .txt on the end of the file name, so you’ll need to fix that filename after editing (XML files end with .xml). I use the freeware TextWrangler myself.


The PanelPro application is for creating control panels to manage a model railroad. It uses the same control bus (or busses) also used by DecoderPro, so if you’ve already set up a connection for DecoderPro, you won’t need to do that again.

JMRI stores everything under a Profile, and you can have more than one. That’s mostly needed if you use a computer to manage more than one layout, so I’ll assume you have one and otherwise ignore it.

Within a profile, PanelPro can do two things: create a Layout Control Panel (using New Panel / Layout Editor) or create any number of local control Panels (using either New Panel / Panel Editor) or New Panel / Control Panel Editor). You don’t need an overall Layout Panel to create smaller control Panels. And the same object (turnout or similar) can be controlled from more than one Panel, although the actual object only exists once and has the same name and definition for all panels. The two types of local control panels exist to support slightly different needs, and I’ll cover that aspect in more detail shortly.

One of my great frustrations with PanelPro is that it doesn’t automatically save changes to things, or even prompt you to save them reliably (sometimes it reminds you, but not always). That’s probably good once a panel is defined and being used by operators, who might change something by accident. But it means you can spend a whole evening creating a control panel, only to forget to save it and lose all that work. And this also extends to supporting objects. If you add an object (like a turnout) and then forget to save that table of objects, the next time you start JMRI the panel will be referencing an undefined object and won’t work. I’ve done this too many times. So, figure out how to save things and save often.

The interface is also a bit “quirky” on the Mac. It really wants to have per-window menu bars like Windows, but it doesn’t actually do this. Instead the main menu bar at the top of the screen changes depending on which window is selected. If you are working on a panel, and need to open the turnouts table to add one, you need to select the main PanelPro window to get the “Tools” menu so you can use it to open the Turnout Table. DecoderPro works the same way, so I’m used to this, but it was really hard to figure out the first time I used JMRI.

JMRI Objects

JMRI is based on an internal model that uses “sensors” and “turnouts”. A sensor is anything that reports information to JMRI, while a turnout is anything that can be controlled from JMRI. Tha’s not limited to just turnouts. Both of these are simple on/off devices (sensors can’t report anything more complex than “on” or “off”). With a turnout, “off” is assumed to mean “lined for the through route” and “on” to mean “lined for the diverging route”. More complex objects (like blocks) can be built from the simple ones.

Signals aren’t a basic object, but something built atop that underlying functionality, although they appear as a different class of object. Actually, they appear as two kinds of objects, simpler “Signal Head” objects and more complex “signal mast” objects that are composed of multiple heads and follow a specific set of rules affecting what they can display. This is very useful if you want to model a kind of signal supported by JMRI. Unfortunately this doesn’t include standard Japanese MLIT signaling, so I had to define my own set of rules for this.

In JMRI, objects have a hardware type that relates to the control bus. This doesn’t appear to be something that can be changed once an object is defined, so you have to know before creating an object how you will manage it. And you can’t change the control system without deleting the object and creating a new one.

That’s particularly bad since it means that if you build a complex layout, and then decide to change from say LocoNet to LCC as your control system, you will have to delete every object from every control panel that references it, and then manually add the new version. In essence, you have to re-create things from scratch. If you want to get your hands dirty with a text editor, you can probably fix this with a bunch of batch changes to the XML files that define the layout profile, but that’s not something most people would want to do.

Each object has an internal name based on the communications system and the object type followed by type-specific information about how to communicated with it. So a LocoNet turnout will be “LT” followed by a number, and an LCC turnout will be “MT” followed by a pair of Event IDs. Sensors are similarly named LS or MS and signal heads LH or MH (although I don’t think JMRI supports LCC signals yet).

Each object also has a human-friendly name that’s just a text string. This could be the label used on a control panel, such as “T11”, or it could be something more readable like “East Lead”.

Objects also have a “state”, which starts off as “unknown” when the program is first started (and any past state is forgotten). These can be controlled directly from the table of objects (there’s a “Cmd” button for each that cycles through the allowed states) or from a panel linked to the object (where clicking on the object’s icon does the same thing as clicking the “Cmd” button).

Control Panels

A Control Panel in JMRI is really just a window containing some icons that correspond to objects in JMRI. These icons can change when the object changes state (i.e., a signal icon can have different appearances for red or green signals). But they don’t have to. Also, the icon will very depending on the kind of control panel. If you want a traditional CTC panel, the track diagram is just a static graphic, and the icon that controls a turnout is the switch below the diagram. If you want a more modern look, the icon of the turnout is what you click, and its appearance will change depending on whether it is lined for a through route or a diverging one.

The “all layout” panel is designed to be used for a more schematic kind of overview, not attempting to replicate anything prototypical that I’m aware of. It’s useful if you have a moderate sized layout (or a really big monitor) and want a birds-eye view of the whole thing at once. The two local control panel types are better suited for more prototypical kinds of controls.

The “Panel” type is probably better for replicating older physical control panels with switches and indicator lights, such as CTC machines (and some really nice ones have been made that way). The “Control Panel” type can be used for that, but has additional capabilities that make it better at replicating modern CRT-based controls (where track color changes when occupied, or locked out for maintenance).

Unfortunately JMRI isn’t a graphics editor, and you will need to create at least part of your panel in an external editor, unless you want to use one of the pre-defined ones. Objects displayed on panels are normally represented as GIFs. It may be possible to use JPEG graphics also, but all of the predefined ones use the GIF format. A program like Photoshop Elements can be used to create GIF graphics, although it’s not very good for editing existing ones. I use it to make new ones using its internal PSD format, then export to GIF for use.

JMRI can do basic scaling and rotation, so if you need an object to be larger/smaller, or angled at 45 degrees, it can do that using the basic icon. At a minimum you’ll probably need to create a background graphic for your control panel, although there are some pre-defined, and possibly some control icons if none of the pre-defined ones are suitable. The “Control Panel” version does have some simply object editing capabilities, for creating circles and rectangles or setting the background color.