HOME > SUPPORT > RIB LOADING

 Rib Loading

Unlike other UI builders, Ribs is not a code generator. Instead Ribs does UI persistence in the form of clean and simple XML description files of UI panels. These "rib" file are loaded with a single line of code:

// Load Swing UI panel from rib file
ui = Ribs.getRib(myController)

This has many advantages over code generators:

  • Better separation between Controller code and UI code
  • Better support for iterative development
  • Smaller UI definition files
  • Better forward compatibility
  • Better opportunity for localization
  • Less code means less maintenance!

Controller.java/Controller.rib Pairing

With Ribs, the developer will always create a <whatever>.java file for every <whatever>.rib file, and these files will reside in the same directory or package. This means that if you create a CustomerEditor.rib, you'll create a CustomerEditor.java in the same directory. Or if you create a FontPanel.rib, you'll create a FontPanel.java.

Enforcing this pairing is good Model-View-Controller architecture, but it also does two useful things: provides a convenient way to locate the rib file from a Java class and gives Ribs something to configure callbacks for.

So when you call Ribs.getRib(myController), Ribs knows to look for the Controller.rib in the same directory. And, from then on, any manipulation of controls in that UI panel will call myController.respondUI() (individual control callbacks can be changed from this default).

The getRib() RJPanel

Ribs loads all UI panels in its own JPanel subclass, RJPanel. This RJPanel acts as manager for all the UI controls in the panel, providing many useful features, foremost among them is locating controls by name:

// Access individual UI controls by name
ui.get("WhateverComponent");
ui.getButton("OKButton");
ui.getTextField("NameText") ).

The second most useful feature of the RJPanel is a unified way of getting and setting values on controls:

// Set values in UI controls
ui.setValue("NameText", user.getName());
ui.setValue("AgeSlider", user.getAge());
ui.setValue("MarriedCheckBox", user.isMarried());

// Get values from UI controls
user.setName(ui.getStringValue("NameText"));
user.setAge(ui.getIntValue("AgeSlider"));
user.setMarried(ui.getBoolValue("MarriedCheckBox));

This "Unified Accessor Model" not only makes updating and responding to UI controls particularly convenient, but it also provides side-effect protection against Swing's tendency to fire action listeners on controls even when updating from the model (sometimes resulting in an infinite loop of model updates and UI refreshes).

Controller.getUI() - A place to load Rib files

Ribs encourages the convention that all Controller objects implement a getUI() method to load the Swing UI panel:

/**
 * An example controller class.
 */

public class MyController {

    // The Swing UI panel
    RJPanel     _ui;

    /** Returns the Swing UI panel. */
    public RJPanel getUI()
    {
        // If ui panel not loaded, load from rib file
        if(_ui==null)
            _ui = Ribs.getRib(this);

        // Return Swing UI panel
        return _ui;
    }
}

This convention isn't an absolute requirement (you could choose to load the UI as the variable initializer or in a method with a different name). But it will make your controller structure more recognizable to other Ribs developers and provides a convenient place to do additional control configuration, if necessary. Additionally, some of Ribs more advanced features depend on being able to locate a controller's UI panel via this method.

Controller.getUI() - A place to configure Rib files

The Ribs designer provides functionality to do a remarkable amount of UI design and configuration. However, it's impossible to provide a graphical solution for every possible UI requirement. Fortunately, there's an easy way to address this, by simply performing additional standard Swing configuration when a Rib file is loaded. Here's an example of some configuration by expanding the rib file loading line above:

// If ui panel not loaded, load from rib file and configure
if(_ui==null) {

    // Load from rib file
    _ui = Ribs.getRib(this);

    // Add a mouse listener to submit button
    _ui.getButton("SubmitButton").addMouseListener(myMouseListener);

    // Add a table model to customer table
    _ui.getTable("CustomerTable").setModel(new CustomerTableModel());

    // Cache UI control variable for convenient use by controller
    _nameText = _ui.getTextField("NameText");
}

Instant Gratification: ui.setWindowVisible(true)

Ribs UI panels can also, optionally, manage a window. Applications generally have many more distinct UI panels than they do windows. However, when you have a UI panel that does want to be in its own window, this is very convenient. Here's an example of a main method for our above controller class simply displaying the UI panel in its own window:

public static void main(String args[])
{
    // Make controller UI window visible
    new MyController().getUI().setWindowVisible(true);
}