Chapter 10. User Interface Definition Language (UIDL)

User Interface Definition Language (UIDL) is a language for serializing user interface contents and changes in responses from web server to a browser. The idea is that the server-side components "paint" themselves to the screen (a web page) with the language. The UIDL messages are parsed in the browser and translated to GWT widgets.

The UIDL is used through both server-side and client-side APIs. The server-side API consists of the PaintTarget interface, described below in Section 10.1, “API for Painting Components”. The client-side interface depends on the implementation of the client-side engine. In IT Mill Toolkit Release 5, the client-side engine uses the Google Web Toolkit framework. Painting the user interface with a GWT widget is described in Section 8.3, “Integrating a GWT Widget”.

UIDL supports painting either the entire user interface or just fragments of it. When the application is started by opening the page in a web browser, the entire user interface is painted. If a user interface component changes, only the changes are painted.

Since IT Mill Toolkit Release 5, the UIDL communications are currently done using JSON (JavaScript Object Notation), which is a lightweight data interchange format that is especially efficient for interfacing with JavaScript-based AJAX code in the browser. The use of JSON as the interchange format is largely transparent; IT Mill Toolkit version 4 and older used an XML-based UIDL representation with the same API. Nevertheless, the UIDL API uses XML concepts such as attributes and elements. Below, we show examples of a Button component in both XML and JSON notation.

With XML notation:

<button id="PID2" immediate="true" caption="My Button" focusid="1">
    <boolean id="v1" name="state" value="false"></boolean>
</button>

With JSON notation:

["button",
 {"id": "PID2",
  "immediate":true,
  "caption": "My Button",
  "focusid":1,
  "v":{"state":false}
 }
]

JSON is used in IT Mill Toolkit Release 5, because JSON is very fast to parse compared to XML. A JSON message can be directly evaluated as a JavaScript statement. The client-side engine of IT Mill Toolkit parses and evaluates the UIDL messages using the JSON library available in the Google Web Toolkit. For more information about handling UIDL messages in the client-side components, see Chapter 8, Developing Custom Components.

UIDL communications can be easily tracked and debugged using the Firebug extension for Mozilla Firefox.

10.1. API for Painting Components

Serialization or "painting" of user interface components from server to the client-side engine running in the browser is done through the PaintTarget interface. In IT Mill Toolkit Release 5, the only implementation of the interface is the JsonPaintTarget, detailed in Section 10.2, “JSON Rendering” below.

The abstract AbstractComponent class allows easy painting of user interface components by managing many basic tasks, such as attributes common for all components. Components that inherit the class need to implement the abstract getTag() method that returns the UIDL tag of the component. For example, the implementation for the Button component is as follows:

    public String getTag() {
        return "button";
    }

AbstractComponent implements the paint() method of the Paintable interface to handle basic tasks in painting, and provides paintContent() method for components to paint their special contents. The method gets the PaintTarget interface as its parameter. The method should call the default implementation to paint any common attributes.

    /* Paint (serialize) the component for the client. */
    public void paintContent(PaintTarget target) throws PaintException {
        // Superclass writes any common attributes in the paint target.
        super.paintContent(target);
        
        // Set any values as variables of the paint target.
        target.addVariable(this, "colorname", getColor());
    }

The AbstractField provides an even higher-level base class for user interface components. The field components hold a value or a property, and implement the Property interface to access this property. For example the property of a Button is a Boolean value.

    public void paintContent(PaintTarget target) throws PaintException {
        super.paintContent(target);

        // Serialize the switchMode as an attribute
        if (isSwitchMode())
            target.addAttribute("type", "switch");

        // Get the state of the Button safely
        boolean state;
        try {
            state = ((Boolean) getValue()).booleanValue();
        } catch (NullPointerException e) {
            state = false;
        }
        target.addVariable(this, "state", state);

    }