The Java EE 6 Tutorial

Laying Out Components with the h:panelGrid and h:panelGroup Tags

In a JavaServer Faces application, you use a panel as a layout container for a set of other components. A panel is rendered as an HTML table. Table 7–6 lists the tags used to create panels.

Table 7–6 Panel Component Tags

Tag 

Attributes 

Function 

h:panelGrid

columns,columnClasses, footerClass, headerClass, panelClass, rowClasses

Displays a table 

h:panelGroup

layout

Groups a set of components under one parent 

The h:panelGrid tag is used to represent an entire table. The h:panelGroup tag is used to represent rows in a table. Other tags are used to represent individual cells in the rows.

The columns attribute defines how to group the data in the table and therefore is required if you want your table to have more than one column. The h:panelGrid tag also has a set of optional attributes that specify CSS classes: columnClasses, footerClass, headerClass, panelClass, and rowClasses.

If the headerClass attribute value is specified, the panelGrid must have a header as its first child. Similarly, if a footerClass attribute value is specified, the panelGrid must have a footer as its last child.

Here is an example:

<h:panelGrid columns="3" headerClass="list-header"
    rowClasses="list-row-even, list-row-odd"
    styleClass="list-background"
    title="#{bundle.Checkout}">
    <f:facet name="header">
        <h:outputText value="#{bundle.Checkout}"/>
    </f:facet>
    <h:outputText value="#{bundle.Name}" />
    <h:inputText id="name" size="50"
         value="#{cashier.name}"
        required="true">
         <f:valueChangeListener
             type="listeners.NameChanged" />
    </h:inputText>
    <h:message styleClass="validationMessage" for="name"/>
    <h:outputText value="#{bundle.CCNumber}"/>
    <h:inputText id="ccno" size="19"
        converter="CreditCardConverter" required="true">
         <bookstore:formatValidator
             formatPatterns="9999999999999999|
                9999 9999 9999 9999|9999-9999-9999-9999"/>
    </h:inputText>
    <h:message styleClass="validationMessage"  for="ccno"/>
    ...
</h:panelGrid>

The preceding h:panelGrid tag is rendered as a table that contains components in which a customer inputs personal information. This h:panelGrid tag uses style sheet classes to format the table. The following code shows the list-header definition:

.list-header {
    background-color: #ffffff;
    color: #000000;
    text-align: center;
}

Because the h:panelGrid tag specifies a headerClass, the panelGrid must contain a header. The example panelGrid tag uses a facet tag for the header. Facets can have only one child, so an h:panelGroup tag is needed if you want to group more than one component within a facet. The example h:panelGrid tag has only one cell of data, so an h:panelGroup tag is not needed.

The h:panelGroup tag has an attribute, layout, in addition to those listed in Common Component Tag Attributes. If the layout attribute has the value block, an HTML div element is rendered to enclose the row; otherwise, an HTML span element is rendered to enclose the row. If you are specifying styles for the h:panelGroup tag, you should set the layout attribute to block in order for the styles to be applied to the components within the h:panelGroup tag. You should do this because styles, such as those that set width and height, are not applied to inline elements, which is how content enclosed by the span element is defined.

An h:panelGroup tag can also be used to encapsulate a nested tree of components so that the tree of components appears as a single component to the parent component.

Data, represented by the nested tags, is grouped into rows according to the value of the columns attribute of the h:panelGrid tag. The columns attribute in the example is set to 3, and therefore the table will have three columns. The column in which each component is displayed is determined by the order in which the component is listed on the page modulo 3. So, if a component is the fifth one in the list of components, that component will be in the 5 modulo 3 column, or column 2.