Wednesday, December 1, 2010

Creating a centered page layout using ADF Faces (only)

by Eduardo Rodrigues

It’s been a long time since I last posted here about my old friend: ADF. But now that I’m working in ADF BC’s awesome development team, I was already feeling the self-pressure and urge to go back to this vast subject. Let’s start easy though.

As you all might have noticed, ADF has gone a long way since it’s early days. ADF Faces 11g is quite different from its 10g predecessor. One of the differences, besides all the rich components and built-in AJAX capabilities, is the fact that some of the components that were present in 10g have moved from ADF Faces library to Apache Trinidad (or MyFaces). One of those components was the “rowLayout”. That layout component certainly makes it very easy to center its content in relation to the entire page, both horizontally and vertically. However, using Trinidad components ad tag libraries alongside with ADF Faces, although possible, may not be always desired. So, the question is: how to achieve same layout using only ADF Faces’ layout manager?

If you’re somewhat used to the particularities of ADF Faces’ layout manager, you probably already know that setting up a container that not only stretches 100% of the page’s (or of its parent container’s) height but also centers its content vertically is not as easy and straightforward as one would think.

Thinking fast, the first approach most come up with (including myself) is this:

panelStretchLayout (only center facet enabled) > panelGroupLayout (Layout = horizontal ; Valign = middle) > panelGroupLayout (Layout = vertical ; Halign = center)

Pretty intuitive and simple, right? Yes! But the layout manager doesn’t seem to agree.

The problem with this layout structure is basically the fact that a horizontal panelGroupLayout does not support being stretched inside a panelStretchLayout facet. This is actually clearly documented: http://goo.gl/GYVud

After a lot of trial-and-fail, I eventually found a way (thanks to my good friends and ADF gurus Maiko Rocha and George Maggessy).

The layout structure is this:

panelStretchLayout (top, bottom and center facets enabled; TopHeight = 33% ; BottomHeight = 33%) > panelGroupLayout (Layout = vertical ; Halign = center)

Even if you don’t need any content going in the Top or Bottom facets, it’s important to add at least an empty panelGroupLayout to both of them just to ensure the specified 33% of height will be allocated.

To wrap up, here’s a complete source code example of a page with a page-centered login form:


<?xml version='1.0' encoding='UTF-8'?>
<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" version="2.1"
          xmlns:f="http://java.sun.com/jsf/core"
          xmlns:af="http://xmlns.oracle.com/adf/faces/rich">
  <jsp:directive.page contentType="text/html;charset=UTF-8"/>
  <f:view>
    <af:document id="d1" title="Login Page">
      <af:form id="f1" defaultCommand="#{'pgTplt:cbLogin'}">
            <af:panelStretchLayout id="psl1" startWidth="33%" endWidth="33%"
                                   topHeight="33%" bottomHeight="33%">
              <f:facet name="center">
                <af:panelGroupLayout id="pgl1" layout="vertical"
                                     halign="center">
                  <af:panelFormLayout id="pflLogin" rows="2" maxColumns="1">
                    <af:inputText id="itUsername" label="Username"
                                  value="#{Login.username}"/>
                    <af:inputText label="Password" id="itPassword" secret="true"
                                  value="#{Login.password}"/>
                    <af:spacer width="10" height="10" id="s1"/>
                    <af:commandButton text="Login" id="cbLogin"
                                      actionListener="#{Login.doLogin}"/>
                  </af:panelFormLayout>
                </af:panelGroupLayout>
              </f:facet>
              <f:facet name="bottom">
                <af:panelGroupLayout id="pgl2"/>
              </f:facet>
              <f:facet name="top">
                <af:panelGroupLayout id="pgl3"/>
              </f:facet>
            </af:panelStretchLayout>
      </af:form>
    </af:document>
  </f:view>
</jsp:root>

And this is how the page above should look like:


image

8 comments:

Bogdan Petridean said...

Hi Eduardo,

Great article, thank you.

As an optimization you do not need to set the left, right and bottom facets of the panelStretchLayout.
The top facet of the paneStretchLayout set to 33% and the panelGroupLayout (vertical || scroll) with halign = center will do the job.
Please correct me if I'm wrong.

Thank you again,
Bogdan.

Anonymous said...

definitely, it's not in the center of the page vertically. Its' located under 33%. Only when the height of the formLayout is 33% of the page, it's centered.

Anonymous said...

I tried, but its displaying at top-center of the page... how to make it at the middle of the page?

A.Mateus said...

Thanks man. It worked OK.
Save me few hours of work.

Anonymous said...

Very nice! Just started learning ADF faces...this is exactly what i was looking for.

Alexandr Sokolovski said...

Here you can read how to create nice layouts

http://adfpractice-sokol.blogspot.com/2012/06/complex-forms-simple-and-easy.html

and here how to place it in the center of the page

http://adfpractice-sokol.blogspot.com/2012/06/obtaining-hostname-and-printers-via.html

Unknown said...

I have the same issue, it is not aligned vertically, help!

Norber said...

Thanks for the article.

I have a example created about layout in ADF faces

http://adfsalvaje.blogspot.com.es/2014/07/ejemplo-de-maquetacion-de-una-pagina.html