Table of Contents
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 in
Section A.1, “API for Painting Components”. The client-side interface depends on the
implementation of the client-side engine. In Vaadin Release 5, the client-side
engine uses the Google Web Toolkit framework. Painting the user interface with a
GWT widget is described in Section 11.3, “Google Web Toolkit Widgets”.
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 Vaadin 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 (predecessor of Vaadin released in 2006) the older versions 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} } ]
Components are identified with a PID or
paintable identifier in the id
attribute. Each component instance has its individual PID, which is usually an
automatically generated string, but can be set manually with
setDebugId()
method.
Section A.2, “JSON Rendering” gives further details on JSON. For more information about handling UIDL messages in the client-side components, see Chapter 11, Developing New Components.
You can track and debug UIDL communications easily with the Firebug extension for Mozilla Firefox, as illustrated in Section A.2, “JSON Rendering” below.
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 Vaadin Release 5,
the only implementation of the interface is the
JsonPaintTarget
, detailed in Section A.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()); }
Serialized data can be attributes or variables, serialized with the
addAttribute()
and
addVariable()
methods, respectively. You must always
serialize the attributes first and the variables only after that.
The API provides a number of variations of the methods for serializing
different basic data types. The methods support the native Java data types and
strings of the String
class. addVariable()
also supports vectors of
strings.
Contained components are serialized by calling the
paint()
method of a sub-component, which will call
the paintContent()
for the sub-component, allowing
the serialization of user interfaces recursively. The
paint()
method is declared in the server-side
Paintable
interface and implemented in the abstract
base classes, AbstractComponent
and
AbstractComponentContainer
(for layouts).
Layout components have to serialize the essential attributes and variables
they need, but not the contained components. The
AbstractComponentContainer
and
AbstractLayout
baseclasses manage the recursive
painting of all the contained components in layouts.
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); }