form4j Form Definition

Anatomy of a Form Definition


This anatomy has its equivalent within the XML form definitions:
<?xml version='1.0' encoding='ISO-8859-1'?>
<!DOCTYPE FormDefinition SYSTEM "file:./dtd/form4j.dtd">

<FormDefinition version="0.2">

    <Layout>
        <!-- declaration for the table layout -->
    </Layout>

    <Conditions>
        <!-- optional XPath expr. to control conditional form parts -->
    </Conditions>
    
    
    <!-- optional field traversal specification -->
    <Traversal class='..' fieldNames=''
    />
    

    <!-- evt.nested areas with common attributes and form fields -->
    <Area>
        <Fields>

            <Area>
                <Fields>
                </Fields>
            </Area>

        </Fields>
    </Area>

</FormDefinition>

Form Layout

The layouting of form components is based on the TableLayout. (If you're serious about doing elaborate form layouts, it's a good idea to have a look into the table layout article).

Basically, the table layout needs a global description of rows and columns to define the table cells. Single components are then assigned to one or more table cells by their specific constraints.
To make the XML definition more readable, we predefine the row/column declarations by a set of constant declarations. These constants may subsequently be used within the row and columns declarations. A 5x5 layout may look like:

<!-- declarations for the underlying TableLayout -->
<Layout>
   <Constants>
      <Constant name="BORDER" value="20.0"/>
      <Constant name="GAP"    value="10.0"/>
      <Constant name="FIELD"  value="&TableLayoutConstants.PREFERRED;"/>
      <Constant name="ROW"    value="&TableLayoutConstants.PREFERRED;"/>
   </Constants>
   <Columns>BORDER,FIELD,GAP,FIELD,BORDER</Columns>
   <Rows>BORDER,ROW,GAP,ROW,BORDER</Rows>
</Layout>
This layout declaration defines a table with the following cells:
20pix height20pixpreferred10pixpreferred20pix
preferred height20pixpreferred10pixpreferred20pix
10pix height20pixpreferred10pixpreferred20pix
preferred height20pixpreferred10pixpreferred20pix
20pix height20pixpreferred10pixpreferred20pix
The effective size of the cells named preferred depends on the preferred size of the form fields you'll later associate with these cells.

Conditions

The visibility (and for some fields also the editability) may be controlled by XPath Conditions.
The underlying model re-evaluates all these conditions whenever the data changes. All form elements 'listening' to some condition may change their visibility (editability) in turn.
This general feature may be used to achieve: Example: Multipage Form
Let's sketch out, how to create a two page form based on the following XML Data!

<twoPageForm>
    <pageNr>0</pageNr>
    <!-- more xml data  -->
</twoPageForm>
The pageNr field may have two values 0,1 to select among the two pages. To declare conditions for each page, we would have the following conditions element within the formdefinition:

<!-- conditions to switch the two pages of this form definition  -->
<Conditions>
    <Condition name="IsPage0" 
               xpathPredicate="/twoPageForm/pageNr[text() = '0']"
    />     
    <Condition name="IsPage1" 
               xpathPredicate="/twoPageForm/pageNr[text() = '1']"
    />
</Conditions>
        
Then we collect all form elements for each page into separate Area elements:

<!-- form elements for page 0  -->
<Area visibleWhen='IsPage0'>
    <!-- form fields of page 0 ...  -->
</Area>

<!-- form elements for page 1  -->
<Area visibleWhen='IsPage1'>
    <!-- form fields of page 1 ... -->
</Area>
To allow interactive selection among the form pages, we may add a tab element, that references the /twoPageForm/pageNr/text() value within the data, causing the specific form area to become visible:

<!-- a tab as page selector -->
<Tab constraints="1, 3, 9, 3" 
    key="/twoPageForm/pageNr/text()" 
    selection="0,1"
/>
Caution with white-space when you use text() in the xpath predicates! If in doubt, use normalize-space(text()) to ignore white space.

Constant Conditions

Instead of a qualified condition name, the following constant conditions may occur within the visibleWhen and enabledWhen condition attributes:

Nested Conditions

Condition bound attributes are ANDed along their ancestor axis.
For an visibleWhen condition in some field, all eventually existing visibleWhen are ANDed: they all must be true for the specific field to become visible.
The only exception from this nesting rule are the constant conditions always and never. These are evaluated directly, without taking any ancestor conditions into account.

Focus Traversal and Visualisation


Example form traversal in (left-to-right): Default, Declaration and Fieldname Order Policy

The default field order when traversing the form (with repeated TAB keys) consists in: This is normally sufficient.

Another readily available traversal policy is to use the container order of the fields. This somewhat technical policy reflects the order in which the field are added to the form container.
You may activate container order by specifying (in the Traversal section of your form definition):

    <!-- container order traversal specification -->
    <Traversal class='java.awt.ContainerOrderFocusTraversalPolicy'/>

Yet another traversal policy is to use the declaration order of the fields. This policy reflects the order in which the field were declared within your form definition.
You may activate declaration order by specifing (in the Traversal section of your form definition):

    <!-- declaration order traversal specification -->
    <Traversal class='org.form4j.form.traversal.DeclarationOrderFocusTraversalPolicy'/>

Finally: when you need full control over the traversal order and don't like to order the fields within your form definition, you may choose the field name order. This policy reflects the order in which the fields were declared within your form definition.
You may activate field name order by specifing (in the Traversal section of your form definition):

    <!-- declaration order traversal specification -->
    <Traversal 
          class='org.form4j.form.traversal.FieldNameOrderFocusTraversalPolicy'
          fieldNames='field5,field2,....'
    />
Attention: with that amount of control over traversal inevitably comes more responsibility: take care that field names really exists and that all fields are included in the fieldNames attribute or else you will have unreachable fields within your form!

Areas

Form areas are elements to structure form definitions.
They have no effect on the layout and don't correspond to swing containers.
Typical usage for areas are:

Area Titles

Area titles are very similar to plain Labels, except that their constraints are defined within a titleConstraints attribute and their text within a title attribute in the area element.
Attribute Description Req. Inher.
titleConstraints The TableLayout constraints for the area title.
When this parameter is missing, the area will have no title.
No No
title The title for this area No No
focusTitleColor The foreground color for this title, when one of the area fields become focused.
(See the colors section)
No Yes

Area Borders

Attribute Description Req. Inher.
borderConstraints The border constraints for the area borders.
Usually row1,col1,row2,col2.
When this attribute exists, a border rectangle with these constraints is painted. The border line will appear exactly in the middle of the resp. column/row.
Full control over border locations and gaps is achieved by having specific inner-border columns/row in the layout definition.
No No
borderLightColor The color of the lighted part of the engraved border line when no field in this area is focused.
(See the colors section)
No Yes
borderShadowColor The color of the shaded part of the engraved border line when no field in this area is focused.
(See the colors section)
No Yes
focusBorderLightColor The color of the lighted part of the engraved border line when a field in this area is focused.
(See the colors section)
No Yes
focusBorderShadowColor The color of the shaded part of the engraved border line when a field in this area is focused.
(See the colors section)
No Yes

Example


    <Area borderConstraints="1,17,7,20" titleConstraints="2,17,6,17,l,c" 
          title="Account">
        <Fields>...</Fields>
    </Area>
        
Note how the borders are drawn in the middles of the rows/columns declared by the borderConstraints="1,17,7,20" attribute:

When one of the fields becomes focused, the same border looks slightly different: