While this section provides an overview how Controls work please see the Javadoc, which provides extensive information and examples.
Figure 1. Post Sequence Diagram - created with Enterprise Architect courtesy Sparx Systems
In Click all control classes must implement the Control interface. The Control interface is depicted below in Figure 2.
Figure 2. Control Interface Diagram - created with Enterprise Architect courtesy Sparx Systems
Methods on the Control interface include:
public class ActionDemo extends BorderPage {
    // Uses listener style 1
    public ActionLink link = new ActionLink();
    // Uses listener style 2
    public ActionButton button = new ActionButton();
    public ActionDemo() {
        // Verbose but provides compile time safety
        link.setActionListener(new ActionListener() {
            public boolean onAction(Control source) {
                return onLinkClick(source);
            }
        });
        // Succinct but typos will cause runtime errors
        button.setListener(this, "onButtonClick");
    }
    // Event Handlers --------------------------------------------------------- 
    public boolean onLinkClick(Control source) {
        ..
        return true;
    }
    public boolean onButtonClick() {
        ..
        return true;
    }
} 
All call back listener methods must return a boolean value. If they return true 
the further processing of other controls and page methods should continue. 
Otherwise if they return false, then any further processing should be aborted. 
By returning false you can effectively exit at this point and redirect or forward 
to another page.  This execution logic is illustrated in the 
Page Execution Activity Diagram.
Being able to stop further processing and do something else can be very handy. For example your 
Pages onRender() method may perform an expensive database operation. By returning
false in an event handler you can skip this step and render the template or forward to the
next page.
Figure 3. Package Class Diagram - created with Enterprise Architect courtesy Sparx Systems
The key control classes include:/com/mycorp/page/Login.propertiesIf you want to tailor messages for a particular page this is where to place them.
/click-page.propertiesIf you want messages to be used across your entire application this is where to place them.
/com/mycorp/control/CustomTextField.properties
/click-control.properties
# Click Control messages
field-maxlength-error={0} must be no longer than {1} characers
field-minlength-error={0} must be at least {1} characters
field-required-error=You must enter a value for {0}
file-required-error=You must enter a filename for {0}
label-required-prefix=
label-required-suffix=<span class="required">*</span>
label-not-required-prefix=
label-not-required-suffix= 
not-checked-error=You must select {0}
number-maxvalue-error={0} must not be larger than {1}
number-minvalue-error={0} must not be smaller than {1}
select-error=You must select a value for {0}
table-first-label=First
table-first-title=Go to first page
table-previous-label=Prev
table-previous-title=Go to previous page
table-next-label=Next
table-next-title=Go to next page
table-last-label=Last
table-last-title=Go to last page
table-goto-title=Go to page
table-page-banner=<span class="pagebanner">{0} items found, displaying {1} to {2}.</span>
table-page-banner-nolinks=
  <span class="pagebanner-nolinks">{0} items found, displaying {1} to {2}.</span>
table-page-links=<span class="pagelinks">[{0}/{1}] {2} [{3}/{4}]</span>
table-page-links-nobanner=<span class="pagelinks-nobanner">[{0}/{1}] {2} [{3}/{4}]</span>
table-no-rows-found=No records found.
table-inline-first-image=/click/paging-first.gif
table-inline-first-disabled-image=/click/paging-first-disabled.gif
table-inline-previous-image=/click/paging-prev.gif
table-inline-previous-disabled-image=/click/paging-prev-disabled.gif
table-inline-next-image=/click/paging-next.gif
table-inline-next-disabled-image=/click/paging-next-disabled.gif
table-inline-last-image=/click/paging-last.gif
table-inline-last-disabled-image=/click/paging-last-disabled.gif
table-inline-page-links=Page   {0} {1} {2} {3} {4}
# Message displayed when a error occurs when the application is in "production" mode
production-error-message=
  <div id='errorReport' class='errorReport'>The application encountered an unexpected error.
  </div> 
Figure 4. Containers Class Diagram
The following classes provides convenient extension points for creating custom Containers: Lets cover each of them here.
public class Div extends AbstractContainer {
    
    public Div(String name) {
        super(name);
    }
    public String getTag() {
        // Return the control's HTML tag.
        return "div";
    }
} 
Lets try out the newly created Container above: (note the MockContext used in this test is described in the
Mock Test Support documentation)
   
public class Test {
    public static void main (String args[]) {
        // Create mock context in which to test the container.
        MockContext.initContext();
        // Create a div instance called "mydiv"
        String containerName = "mydiv";
        Div mydiv = new Div(containerName);
        
        // Add a control to the container
        mydiv.add(new TextField("myfield"));
        System.out.println(mydiv);
    }
} 
Executing the above example results in the following output:
<div name="mydiv" id="mydiv">
    <input type="text" name="myfield" id="myfield" value="" size="20" />
</div> 
public class FieldAndContainer extends AbstractContainerField {
    public FieldAndContainer(String name) {
        super(name);
    }
    // Return the html tag to render
    public String getTag() {
        return "div";
    }
} 
To test the new class we use the following snippet:
public class Test {
    public static void main (String args[]) {
        // Create mock context in which to test the container.
        MockContext.initContext();
        // Create a FieldContainer instance called "field_container"
        String containerName = "field_container";
        FieldAndContainer fieldAndContainer = new FieldAndContainer(containerName);
        
        // Add a couple of fields to the container
        fieldAndContainer.add(new TextField("myfield"));
        fieldAndContainer.add(new TextArea("myarea"));
        System.out.println(fieldAndContainer);
    }
} 
Executing the snippet produces the output:
<div name="field_container" id="field_container">
    <input type="text" name="myfield" id="myfield" value="" size="20"/>
    <textarea name="myarea" id="myarea" rows="3" cols="20"></textarea>
</div> 
// EmployeePage.java
public EmployeePage extends Page {
    private Form form;
    
    public void onInit() {
        // Create form
        Form form = new Form("form");
        
        // Add a couple of fields to the form
        form.add(new TextField("firstname"));
        form.add(new TextField("lastname"));
        form.add(new IntegerField("age"));
        form.add(new DoubleField("salary"));
        // Add a submit button to form
        form.add(new Submit("submit", "Add Employee"));
        // Add form the page
        addControl(form);
    }
} 
Lets imagine we want to create a layout using Div <div> and HTML List <ol> tags.
We could provide the markup for the employee.htm template as shown below,
using a template engine such as Velocity:
<!-- employee.htm -->
${form.startTag()}
    <div style="margin: 1em;">
        <ol>
            <li>
                <label for="firstname">Firstname:</label>
                ${form.fields.firstname}
            </li>
            <li>
                <label for="lastname">Lastname:</label>
                ${form.fields.lastname}
            </li>
            <li>
                <label for="age">Age:</label>
                ${form.fields.age}
            </li>
            <li>
                <label for="salary">Salary:</label>
                ${form.fields.salary}
            </li>
        </ol>
    </div>
    ${form.fields.submit}
${form.endTag()} 
Using a CSS stylesheet, the markup above can be styled and transformed into
a fancy looking form.
There are pros and cons to using the template approach.
One of the advantages of the Template approach, is that the layout is explicit and one can easily
tweak it if needed. For example instead of using divs and ordered lists, one can
change the template to leverage a table layout.
A disadvantage of the Template approach, is added redundancy.
In the example above we created the fields in Java, and laid them out using markup
in the template.
If the requirements should change to add a new field for example, one will have to add the
field in the Page as well as the template.
It is also possible to "generify" the layout using template engines. Macro.vm is an example of a generic form layout using Velocity.
// HtmlList.java
// Create a list <ol> html element, that accepts <li> elements as children
public class HtmlList extends AbstractContainer {
    public String getTag() {
        return "ol";
    }
    // Can only add ListItems: <li> tags
    public Control add(Control control) {
        if (!(control instanceof ListItem)) {
            throw new IllegalArgumentException("Only list items can be added.");
        }
        return super.add(control);
    }
} 
// ListItem.java
// Create a listItem <li> element
public class ListItem extends AbstractContainer {
    public String getTag() {
        return "li";
    }
} 
Another component that will be used in the example below is a FieldLabel which renders
an HTML label element for a specified Field.
// FieldLabel.java
// Create an html <label> element for a specified Field
public class FieldLabel extends AbstractControl {
    private Field target;
    private String label;
    public FieldLabel(Field target, String label) {
        this.target = target;
        this.label = label;
    }
    public String getTag() {
        return "label";
    }
    // Override render to produce an html label which produces:
    // 
    public void render(HtmlStringBuffer buffer) {
        // Open tag: <label
        buffer.elementStart(getTag());
        // Set attribute to target field's id
        setAttribute("for", target.getId());
        // Render the labels attributes
        appendAttributes(buffer);
        // Close tag: <label for="firstname">
        buffer.closeTag();
        // Add label text: <label for="firstname">Firstname:
        buffer.append(label);
        // Close tag: <label for="firstname">Firstname:</label>
        buffer.elementEnd(getTag());
    }
} 
Now the form can be assembled.
Continuing with the employee example from the template approach,
we again create an EmployeePage, but this time an HtmlForm and HtmlList is used to create
a custom layout:
// EmployeePage.java
public class EmployeePage extends Page {
    // A form instance variable
    private HtmlForm form;
    // Build the form when the page is initialized
    public void onInit() {
        // Create an HtmlForm which is ideal for composing manual layouts
        form = new HtmlForm("form");
        
        // Create a list and add it to the form. 
        HtmlList list = new HtmlList();
        form.add(list);
        
        // Add firstname field and pass in its name, label and the list to add the field to
        addTextField("firstname", "Firstname:", list);
        addTextField("lastname", "Lastname:", list);
        addTextField("age", "Age:", list);
        addTextField("salary", "Salary:", list);
        
        // Add a submit button to form
        form.add(new Submit("submit", "Add Employee"));
        // Add the form to the page
        addControl(form);
    }
    
    // Provide a helper method to add fields to the form
    private void addTextField(String nameStr, String labelStr, List list) {
        // Create a new ListItem <li> and add it to the List
        ListItem item = new ListItem();
        list.add(item);
        // Create a textfield with the specified name
        Field field = new TextField(nameStr);
        
        // Create a field label, which associates the label with the field id.
        // label.toString would output: <label for="firstname">Firstname:</name>
        FieldLabel label = new FieldLabel(field, labelStr);
        // Next add the label and field to the list item.
        // item.toString would then produce:
        // <li>
        //   <label for="firstname">Firstname:</name>
        //   <input type="text" name="firstname" id="form_firstname" value="" size="20"/>
        // </li>
        //
        item.add(label);
        item.add(field);
    }
} 
    
Now the employee.htm template would only need to specify the name of the 
top level component, in this case form.
<!--employee.htm-->
${form}
    
which produces the following markup:
    
<!-- employee.htm -->
<form method="post" id="form" action="/myapp/employee.htm">
<input type="hidden" name="form_name" id="form_form_name" value="form"/>
    <ol>
        <li>
            <label for="firstname">Firstname:</label>
            <input type="text" name="firstname" id="form_firstname" value="" size="20"/>
        </li>
        <li>
            <label for="lastname">Lastname:</label>
            <input type="text" name="lastname" id="form_lastname" value="" size="20"/>
        </li>
        <li>
            <label for="age">Age:</label>
            <input type="text" name="age" id="form_age" value="" size="20"/>
        </li>
        <li>
            <label for="salary">Salary:</label>
            <input type="text" name="salary" id="form_salary" value="" size="20"/>
        </li>
    </ol>
    <input type="submit" name="submit" id="form_submit" value="Add Employee"/>
</form> 
Again using a CSS stylesheet, the markup above can be styled and transformed into
a fancy looking form.
There is a live demo
showing the programmatic approach.
The advantage of the programmatic approach is that there is no redundancy. Each Field is
created and added using normal Java. There is no need to specify where the Field
must reside in the markup.
If new requirements arrive and more fields added, only the Page has to be updated.
No need to change the template as the layout is taken care of by the CSS and
markup produced by the components.
A disadvantage is that it is harder to visualize what output would be rendered by the containers.
Whether you use the template or programmatic
layout approach, is up to you. Both work well and have advantages and disadvantages
over the other.