Project Documentation

Guide to Tobago

Preliminary version -- work in progress


Tobago is a JavaServer Faces (JSF) framework and component library. It provides a comfortable way to layout screens of desktop-like applications with a consistent look & feel. Tobago emphasizes the separation of structure and design of screens. Screens are developed independently of the view technology -- no HTML, CSS, or JavaScript. Because of strict separation a screen can be displayed with different themes. These themes can be used to render screens according to different cooperate design without changing the sources of the screens.

This guide assumes basic knowledge about JSF. For more information about JSF see one of the various books about JSF, the Sun Java 5 Tutorial or the JSF Specification.

Environment

Building and Deploying the Tobago Examples

Tobago uses Maven as a build management system. The provided examples are normally build with Maven, but it would be easy to use an alternative build system. The necessary artifacts can be downloaded here or from the Maven repository.

We will use the address book demo as an example in this guide. Since the address book example is currently not part of the Tobago distribution, you have to check-out the sources from the Apache Subversion repository. We will use the latest release tag for this.

svn co https://svn.apache.org/repos/asf/myfaces/tobago/tags/tobago-1.0.22/example/addressbook/ tobago-addressbook

You will need Java 5 and Maven 2.0.9 or later to build the address book example. Use the following command to compile the sources and deploy the web application on an embedded Jetty server:

mvn jetty:run-exploded

If you point your browser to http://localhost:8080/ and you will be directed to the login dialog of the address book example.
 

Address Book Login

You can click on the guest/guest or admin/admin links or fill in the authentication information yourself and press the 'Login' button. After displaying a splash screen for a while the application will direct you to the address list page.
 

Address List

A freshly started instance of the address book example will not contain any addresses in the list. But you can add addresses by pressing the 'New' button in the tool bar. The addresses will be stored in an embedded Derby database.

Building Tobago

To use the latest version of Tobago you can use the snapshot artifacts build by our continuous integration server Continuum, which are available in the Apache snapshot repository.

Alternatively, you can build Tobago yourself. You will need Java 5 and Maven 2.0.9 or later.

Check-out Tobago from the Apache Subversion repository

svn co https://svn.apache.org/repos/asf/myfaces/tobago/trunk/ tobago

To build the complete project with all sub-modules you have to enter the following command

mvn install -Pall-modules

For more information on building Tobago -- especially the 1.0.x branch -- see Getting Started.

Building your own Tobago Application

The Tobago example distribution contains the tobago-example-blank WAR, which can act as starting point for your own Tobago application. Since Tobago is based on JSF you need a JSF implementation if the application server you are targeting doesn't contain one.

If you cannot use Java 5 or higher you can use retrotranslated JARs from the Tobago distribution to develop and run Tobago applications with Java 1.4 (only Tobago 1.0.x).

A Tobago application is a web application which is packaged as a WAR. For a JSF application the FacesServlet needs to be configured in the /WEB-INF/web.xml. To serve the internal resources of Tobago directly from the Tobago JARs the Tobago ResourceServlet has to configured, too. The configuration of a Tobago application is controlled by the WEB-INF/tobago-config.xml file. This can be used to declare the available themes and the default theme. Additionally, it can be used to locally add markup -- see the Themes section for further information.

A Minimal Tobago Page

You can use JSP or Facelets to write Tobago pages. For Facelets support the extension module tobago-facelets has to be added as a dependency. Because the address book example uses JSP as rendering technology we will focus on JSP for now.

Tobago provides two tag libraries -- the core library and the extension library. The corresponding TLDs contain documentation for the provided tags which is generated from annotations on the underlying tag classes. The core tag library contains basic controls and the extension library convenience tags for pre-assembled tag compositions -- for example a composition of a label and an input control.

A minimal Tobago JSP page looks like this:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
<%@ taglib uri="http://myfaces.apache.org/tobago/component" prefix="tc" %>
<%@ taglib uri="http://myfaces.apache.org/tobago/extension" prefix="tx" %>
<f:view>
  <tc:page>
    <f:facet name="layout">
      <tc:gridLayout/>
    </f:facet>
    <tc:out value="Hello World"/>
  </tc:page>
</f:view>

A similar page is part of the blank WAR:
https://svn.apache.org/repos/asf/myfaces/tobago/tags/tobago-1.0.22/example/blank/src/main/webapp/helloWorld.jsp

Creating a Tobago page

The address book example needs an address editing page to add new addresses to the address book and to update existing ones.

A simple version of an address editor allows to edit the first and last name of a person and basic address data like street, house number and city. Such an editor could look like this:
 

Simple Address Editor

This page is generated by the following code:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
<%@ taglib uri="http://myfaces.apache.org/tobago/component" prefix="tc" %>
<%@ taglib uri="http://myfaces.apache.org/tobago/extension" prefix="tx" %>
<f:view>
  <tc:page width="400">
    <f:facet name="layout">
      <tc:gridLayout rows="fixed;*" margin="10"/>
    </f:facet>
    <tc:box label="Address">
      <f:facet name="layout">
        <tc:gridLayout rows="fixed;fixed;fixed;fixed"/>
      </f:facet>
      <tx:in label="First Name"/>
      <tx:in label="Last Name"/>

      <tc:panel>
        <f:facet name="layout">
          <tc:gridLayout columns="6*;1*"/>
        </f:facet>
        <tx:in label="Street / No"/>
        <tc:in />
      </tc:panel>

      <tx:in label="City"/>
    </tc:box>

    <tc:cell />
  </tc:page>
</f:view>

We have a box with the label "Address" containing four rows of input controls for first name, last name, street, house number, and city.

Basic Controls

HTML offers a decent set of basic controls. These controls form the basis of the Tobago controls including single-line input controls, text areas, check boxes, radio buttons, links, buttons, labels, and others.

The Tobago demo contains an overview page for the basic controls.
 

Basic Controls

Live demo of the basic controls: http://www.irian.biz/tobago-example-demo/faces/overview/basic.jsp

The basic controls page also shows two variants of a normal input control: the date input control and the time input control.

Text Input

The single-line text input control comes in two flavors: the <tc:in> tag from the core tag library (tc is the preferred prefix for the core tag library) and the <tx:in> from the extension tag library (tx).

The extension tag library provides convenient shorthands for boilerplate code. For every input control there is for example an extended version, which layouts a label next before the input field. The label is connected with the field. If the label is clicked the related field is focused.

A code fragment from the address book example:

<tx:in value="#{controller.currentAddress.firstName}"
    label="#{bundle.editorFirstName}" required="true">
  <f:validateLength minimum="2" maximum="20"/>
</tx:in>

The value attribute refers the content of the control. If a value binding is used, this content can be written back into a bean property.

The label attribute generates the textual description for the control. The theme decides how the label is actually rendered, for example it assigns a default width. This width can be overwritten with the labelWidth attribute. If you utilize a value binding to a resource bundle declared by a <tc:loadBundle> tag, you automatically get localization for the text labels. An underscore in the label transforms the following character into an access key. The theme normally underlines the access key to make this circumstance visible to the user. The access key can be used to quickly focus the related input control by pressing Alt in combination with the access key.

If the control is marked as required the respective validation takes place. Additionally, the theme tries to visualize this fact. Speyside renders a small check mark icon inside the field, which vanishes if the field contains any data.

For more information about the possible attributes of an input tag see the TLD documentation for <tc:in> and <tx:in>.

Sheet

The sheet control is used to display tabular data.

The address book example uses a sheet to give an overview of all stored addresses.
 

Sheet

Live demo of a sheet: http://www.irian.biz/tobago-example-demo/faces/overview/sheet.jsp

A code fragment from the address book example:

<tc:sheet columns="1*;1*;1*" value="#{controller.currentAddressList}"
    var="address" state="#{controller.selectedAddresses}"
    sortActionListener="#{controller.sheetSorter}" rows="25"
    showRowRange="left" showPageRange="right" showDirectLinks="center">
  <tc:columnEvent event="dblclick" >
    <tc:command action="#{controller.editAddress}"/>
  </tc:columnEvent>
  <tc:column id="firstName" label="#{bundle.listFirstName}" sortable="true"
      rendered="#{controller.renderFirstName}">
    <tc:out value="#{address.firstName}"/>
  </tc:column>
  <tc:column id="lastName" label="#{bundle.listLastName}" sortable="true"
      rendered="#{controller.renderLastName}">
    <tc:out value="#{address.lastName}"/>
  </tc:column>
  <tc:column id="dayOfBirth" label="Birthday" sortable="true"
      rendered="#{controller.renderDayOfBirth}">
    <tc:out value="#{address.dayOfBirth}">
      <f:convertDateTime pattern="#{bundle.editorDatePattern}"/>
    </tc:out>
  </tc:column>
</tc:sheet>

Tab Group

The tab group control displays rectangular content in the same area of the screen with the help of tab panels.

In the address book example the tab group is used to structure the input controls for an address into three groups for general, business, and miscellaneous information.
 

Tab Group

Live demo of a tab group: http://www.irian.biz/tobago-example-demo/faces/overview/tab.jsp

A code fragment from the address book example:

<tc:tabGroup switchType="reloadTab" immediate="true">
  <tc:tab label="#{bundle.editorTabPersonal}">
    <jsp:include page="tab/personal.jsp"/>
  </tc:tab>

  <tc:tab label="#{bundle.editorTabBusiness}" rendered="#{!controller.simple}">
    <jsp:include page="tab/business.jsp"/>
  </tc:tab>

  <tc:tab label="#{bundle.editorTabMisc}" rendered="#{!controller.simple}">
    <jsp:include page="tab/misc.jsp"/>
  </tc:tab>
</tc:tabGroup>

Menu

The menu control can be used to render a menu bar at the top of a screen like it is typically used in desktop applications. But the location for menus is not limited to this place.
 

Menu

Live demo of a menu: http://www.irian.biz/tobago-example-demo/faces/overview/toolbar.jsp

A code fragment from the address book example:

<tc:menuBar>
  <tc:menu label="#{bundle.menuFile}">
    <tc:menuCommand label="#{bundle.menuFileNew}" action="#{controller.createAddress}" immediate="true"
        image="image/org/tango-project/tango-icon-theme/16x16/actions/contact-new.png"/>
    <tc:menuCommand label="Add Dummy Addresses" action="#{controller.addDummyAddresses}" immediate="true"/>
    <tc:menuSeparator/>
    <tc:menuCommand label="#{bundle.admin}" action="#{admin.admin}"
        image="image/org/tango-project/tango-icon-theme/16x16/categories/preferences-system.png"/>
    <tc:menuSeparator/>
    <tc:menuCommand label="Logout" action="#{controller.logout}"
        image="image/org/tango-project/tango-icon-theme/16x16/actions/system-log-out.png"/>
  </tc:menu>

  <tc:menu label="#{bundle.menuSettings}">
    ...
  </tc:menu>

  <tc:menu label="#{bundle.menuHelp}">
    ...
  </tc:menu>
</tc:menuBar>

Tool Bar

The tool bar control is used to render a special rectangular area of buttons. There are two versions of toolbars: a standalone version and version that embeds itself in the border of a box. To embed a tool bar it has to be attached to a <tc:box> via a toolbar facet.

The address book example uses a tool bar below the menu to provide convenient access to the most common actions from the menu.
 

Tool Bar

Live demo of a tool bar: http://www.irian.biz/tobago-example-demo/faces/overview/toolbar.jsp

A code fragment from the address book example:

<tc:toolBar iconSize="big">
  <tc:button label="#{bundle.toolbarAddressList}" action="#{controller.search}" immediate="true"
      image="image/org/tango-project/tango-icon-theme/32x32/mimetypes/x-office-address-book.png"
      disabled="#{facesContext.viewRoot.viewId == '/application/list.jsp'}"/>
  <tc:button label="#{bundle.listNew}" action="#{controller.createAddress}"
      image="image/org/tango-project/tango-icon-theme/32x32/actions/contact-new.png"/>
  <tc:button label="#{bundle.toolbarAbout}"
      image="image/org/tango-project/tango-icon-theme/32x32/apps/help-browser.png">
    <tc:popupReference for=":page:about"/>
  </tc:button>
  <tc:button label="#{bundle.admin}" action="#{admin.admin}"
      image="image/org/tango-project/tango-icon-theme/32x32/categories/preferences-system.png"/>
</tc:toolBar>

Popup

Popups are used to render small modal dialogs inside the current screen. The original screen is disabled until the popup is released with one of the popup buttons.
 

Tool Bar

A code fragment from the address book example:

<tc:popup id="about" width="300" height="220" left="200" top="200">
  <tc:box label="About">
    <f:facet name="layout">
      <tc:gridLayout rows="150px;*;fixed" columns="150px;*"/>
    </f:facet>

    <tc:image width="150" height="150"
        value="image/org/tango-project/tango-icon-theme/address-book-splash-screen.png"/>
    <tc:panel>
      ...
    </tc:panel>

    <tc:cell spanX="2"/>

    <tc:cell spanX="2">
      <tc:panel>
        <f:facet name="layout">
          <tc:gridLayout columns="*;fixed"/>
        </f:facet>
        <tc:cell/>
        <tc:button label="OK">
          <tc:attribute name="popupClose" value="immediate"/>
        </tc:button>
      </tc:panel>
    </tc:cell>
  </tc:box>
</tc:popup>

File Upload

The file select control can be used to upload files.
 

File Upload

A code fragment from the address book example:

<tc:file value="#{controller.uploadedFile}" required="true">
  <tc:validateFileItem contentType="image/*"/>
</tc:file>

Features and Concepts

Layout

Tobago organizes the placement of components with the help of layout managers. The main layout manager is called grid layout. It divides the available rectangular space into grid cells. The grid is spawned by the column and row values of the <tc:gridLayout> tag. The syntax of these values is based on the multi-length notation known from HTML.

To add a layout manager to a container like box, panel or page you have to add a layout facet (i.e. a facet with the name 'layout') to the respective container tag.

A code fragment from the address book example:

<tc:panel>
  <f:facet name="layout">
    <tc:gridLayout columns="*" rows="fixed;fixed;*"/>
  </f:facet>
  <tx:in label="First Name"/>
  <tx:in label="Last Name"/>
  <tc:cell />
</tc:panel>

In this example we place to two input controls with labels into two consecutive rows. Below the two input fields we add a spacer element. The layout token 'fixed' advises the layout manager to give the input control the height, which this kind of control normally possesses in the selected theme.

The values of the column and row attributes of the <tc:gridLayout> tag can contain a semicolon separated list of layout tokens. A layout token can be an exact length in pixels like 200px, a percentage length like 25%, a relative length like 2*, or a specific length called fixed, which's exact length is determined by the theme and make sure the control is usable -- a single-line input control for example needs to be so high that characters from the assigned font can be read inside the control.

Relative lengths are determined last by the layout manager. The available remaining space is distributed among the existing relative lengths. Each length receives space proportional to the integer before the '*'. A single '*' is a shorthand for '1*'.

The layout manager handles the rendered attribute of controls, too. If the rendered attribute is dynamically defined by a value binding, the page can contain fewer controls in some cases than in others. The layout manager can then distribute the newly available space between the remaining relative and percentage lengths.

Themes

A theme defines how the structured view is actually rendered. It provides the look & feel of the controls inside a view. It appoints colors, dimensions, spacing, fonts and other graphical properties.

Tobago includes a small collection of themes called after cities on the island Tobago: Scarborough, Speyside, Charlotteville, and Richmond. Scarborough is a basic theme, which tries to focus on features of plain HTML, Speyside is the main theme of Tobago, Charlotteville and Richmond are mainly color variations of Speyside.
 

Scarborough

Scarborough
 

Speyside

Speyside
 

Charlotteville

Charlotteville
 

Richmond

Richmond

Markup

Since you don't have direct control over design without writing your own theme, Tobago supports the concept of markup. You can assign certain logical markup values to a control to fine-tune the rendering. A theme specifies the supported markup for every control. The standard theme already provides some helpful markups.
 

<tc:out> strong, deleted, number
<tc:in> number
<tc:label> number
<tc:treeNode> strong

Also see the standard tobago-config.xml

The markup strong is normally emphasized, deleted is rendered struck out, and number is right aligned. Multiple markups can be combined as a comma separated list:

...
<tc:label value="Normal"/>
<tc:out value="999.99"/>

<tc:label value="Number"/>
<tc:out markup="number" value="999.99"/>

<tc:label value="Emphasized"/>
<tc:out markup="strong" value="999.99"/>

<tc:label value="Emphasized Number"/>
<tc:out markup="number,strong" value="999.99"/>
...

This code fragment is rendered like this:
 

Markup example

You can add markup in your own theme or extend the current themes on the fly by adding a <renderers> section into the tobago-config.xml.

The address book example adds markup values to the <tc:progress> control to be able to colorize the control depending on the criticallity of the progress value. On the administration page the progress control is used to visualize the memory consumption of the VM.

<renderers>
  <renderer>
    <name>Progress</name>
    <supported-markup>
      <markup>ok</markup>
      <markup>warn</markup>
      <markup>error</markup>
    </supported-markup>
  </renderer>
</renderers>

See the address book tobago-config.xml for a complete example.

The various progress variants look like this:
 

Progress markup

Markup attributes are rendered into HTML as extra CSS style classes, which can be used to modify the normal styling of a control. In the progress example the following CSS is added to the Speyside theme:

.tobago-progress-value-markup-ok {
  background: green;
}

.tobago-progress-value-markup-warn {
  background: yellow;
}

.tobago-progress-value-markup-error {
  background: red;
}

See the address book example Speyside tobago.css.

The tobago.css file is collected by the Tobago resource manager and can be used to overwrite and extend the default tobago.css file of the theme.

Tobago 1.0.x and Tobago 1.5.x are using the old name style.css, since Tobago 2.0.0 tobago.css is used, style.css will also be included for compatibility.

The example theme provides an example for styling sheet cells and contains more complex examples of markup, which need addtional JavaScript to generate more dynamic behaviours like fade-out effects or client-side change detection.

Partial Rendering

To avoid the reload of complete screens Tobago provides partial rendering, which advises the client to update only parts of the screen to optimize the amount of data sent to the client and the time to render necessary updates. Some controls like the tab control and the sheet directly support partial rendering. Whereas container controls like the generic panel allow to group arbitrary controls to be able to update them exclusively as a group.

Virtual Forms

The page tag establishes an implicit form for all controls on the screen. The form tag allows to divide these controls into smaller groups to be able to manage validation only for these grouped controls.

A code fragment from the address book example:

<tc:form>
  <tx:selectOneChoice label="#{bundle.footerLanguage}"
      value="#{controller.language}">
    <f:selectItems value="#{controller.languages}"/>
    <f:facet name="change">
      <tc:command action="#{controller.languageChangedList}"/>
    </f:facet>
  </tx:selectOneChoice>
</tc:form>

Security

The extension module tobago-security allows to protect method bindings with the help of annotations. The module provides alternative command components with security handling. The available annotations are @RolesAllowed, @DenyAll, and @PermitAll.

A code fragment from the address book example:

public class AdminController {

  @RolesAllowed("admin")
  public String admin() {
    return OUTCOME_ADMIN;
  }

  ...
}