An Oracle JDeveloper Best Practices Document
Written by Matt
Cooper, Mike Elges & Dana
Singleterry, Oracle
August, 2008
Best Practices
Layout Best Practices
Best PracticesRevision
1.0
Technologies
JDeveloper, ADF, ADF Faces
Keywords
Layout
Publisher
Matt Cooper, Mike Elges
& Dana Singleterry
Publish date
August 4, 2008
Problem Description
A developer needs to be able to
develop a Rich Client
Interface and avoid basic layout issues that tend to be pervasive
across
screens and applications. There are a number of low-level layout issues
within
ADFv that:
Tend to repeat themselves
across screens and across
applications.
Impact perception of usability,
quality, and fit ‘n’ finish.
Are annnoying to users in the
aggregate – no single item is
terrible, but a collection of 6 items, repeating themselves on multiple
screens gets frustrating and detracts from the message.
In most cases, there’s a
simple approach and best practice
that will assist developers in avoiding these pitfalls.
This
document discusses basics of page layout and
provides guidance to avoid common browser pitfalls, a recommended
process for
creating layouts, and illustrates layout examples.
Technical Best Practice Description
This Layout Best Practices document
is not necessarily a
pattern but instead, a laundry list of known layout issues that are
encountered
when developing a Rich Client Interface and, how to avoid these
pitfalls in
your application development.
Various
ADF Components are described and demonstrated
throughout this document including document, showDetailItem,
decorativeBox,
panelSplitter, panelStretchLayout, panelBorderLayout and so on. Not one
component by itself but many are combined to achieve the desired layout
for a
screen and / or an application.
Best Practices: The User Experience
To save a great deal
of
development grief and enjoy reduced maintenance costs:
Never try to
stretch something vertically when inside of a flowing (non-stretched)
container. Attempting to do this will result in inconsistent behavior
across web browsers.
Never specify a
height value with percent units. Instead, define such stretching
declaratively as by following the process outlined below.
Never use the
"position" style.
Take advantage of
the layout pattern examples
for guidance on how best to create a desired layout. Be sure to click
on the "View Page Source" and the "View Template Source" links to see
what tags and attributes are used as well as what the component
structure looks like for each specific pages.
Build up the
outer structure of your page using a structure of components that
support being stretched and also stretch their children.
Each layout or
panel component's tag documentation will identify whether this is
supported and how to achieve it in its "Geometry Management"
documentation. Some components have attributes to determine whether
children will be stretched or not. For example:
Inside of the
stretchable structure created in step 1, you can create islands of
flowing (non-stretched) components. To make this transition from
stretching to flowing, use panelGroupLayout
(page source)
with layout="scroll" since it supports being stretched but will not
stretch its children.
For a reliable
page layout:
Do not specify
heights using percent units. Instead, use components that stretch their children.
Do not use the
position style.
Do not attempt
to stretch anything vertically inside of these flowing islands.
Many leaf
components do not make sense by themselves. For example, if you have a
series of input components, you would never want to just place these in
a panelGroupLayout (page source)
because it would be much better for usability if you placed them in a panelFormLayout (page source) so
the labels and fields will line up.
A sample list of
components that cannot be reliably stretched includes:
Apache MyFaces
Trinidad HTML Component - tableLayout
JSF HTML
Component - panelGrid
Customize the
appearance of
components
Appearance may
be customized using the following mechanisms:
Use themed decorativeBox
(page source)
components to organize your page layers with visual distinction and
decorative borders as seen in some of the sample skins. Note that not
all skins have alternative themes so you may not see any distinction.
If your decorativeBox
(page source)
components are not showing up with different colored backgrounds and
you know that you are using a skin that has definitions for alternate
themes, you might be missing a web.xml context-param setting for
"oracle.adf.view.rich.tonalstyles.ENABLED" being set to false. Your document (page source) component
also has a theme attribute so you can use it to change the main
background styling of your page.
Use a custom
skin for consistently modified appearances if the existing skin doesn't
provide all that you need.
For
instance-specific alternative styling, use the styleClass attribute.
Keep the corresponding style definitions in an easy-to-maintain
location such as in a custom skin, in the metaContainer facet of the document (page source) component,
or as close to the top of the page as possible for optimal performance.
As a last
resort, use component attributes such as inlineStyle, contentStyle, and
labelStyle. These are less declarative, harder to maintain, contribute
more to the page's raw HTML size, and may not even be needed if one or
more of the above mechanisms are used.
Styles are
directly processed by the web browser, which gives you a great deal of
power but at the cost of being less declarative and error-prone. The
browsers do not support all styles on all elements and certain
combinations of styles produce non-obvious results. Here is some
guidance on style configurations to avoid:
Component
Situation
to Avoid
*
An inlineStyle with a "height"
value with "%" units
*
An inlineStyle with "height",
"top", and "bottom" values
*
An inlineStyle with "width",
"left", and "right" values
*
An inlineStyle with a
"position" value
Child being stretched by a
parent component
An inlineStyle with "width" or
"height" values
Scrolling:
You should
only have scrollbars around flowing island content. The recommended
transition component for switching from a stretching outer frame into a
flowing island is the panelGroupLayout
(page source)
with layout="scroll". If the contents of this panelGroupLayout (page source)
cannot fit in the space allocated, the browser will determine whether
scrollbars are needed and will add them automatically.
It is not
recommended that you nest scrolling panelGroupLayout
(page source)
components because this will make the user see multiple scrollbars.
Also, this should only be used at transitions from stretching to
flowing areas and since you should not have stretching areas inside of
flowing areas, you would generally never end up with nested scrollbars.
It is best to minimize the number of areas that a user must scroll in
order to see what he or she is looking for. Take time to consider what
scrolling the user will need. In cases where undesired scrollbars
exist, you may want to simply change the layout attribute of that panelGroupLayout (page source) to
"vertical".
There is a
known, unresolved scrolling issue that has been logged against Internet
Explorer 7.0.5730.11. If a scrolling box has contents that are set to
be as wide as the containing box and if the contents are large enough
to warrant the need for a vertical scrollbar, an unnecessarily needed
horizontal scrollbar will be added. The browser is failing to adjust
the width of the contents for the presence of the vertical scrollbar
and thus a horizontal scrollbar appears. This horizontal scrollbar lets
you scroll the small amount of space equal to the width of the vertical
scrollbar.
Workarounds involve setting the widths of the contents to be smaller
than full width so that the browser has enough space for a vertical
scrollbar to fit. For example, you may want to add a styleClass that
only shows up in Internet Explorer that assigns "width: 90%" on an
af:panelHeader tag. You can achieve this with code like this:
<af:group
rendered="#{adfFacesContext.agent.agentName=='ie'}"><![CDATA[
<style type="text/css">
.MyInternetExplorerWorkaround {
/* Workaround for bug in IE 7.0.5730.11 which incorrectly calculates
the need for
horizontal scrolling. */
width: 90%;
}
</style>
]]></af:group> ...
<af:panelHeader text="Introduction"
styleClass="MyInternetExplorerWorkaround">
...
</af:panelHeader>
In
many cases, to apply these kinds of styles, you
need to use multiple components together. In a scrolling area, adding
an extra
panelGroupLayout with layout="vertical" with the padding defined on
it, inside of the outer layout="scroll" panelGroupLayout, will be
required. In a stretching area, you may need to wrap a component inside
of a
panelStretchLayout with spacers in its top, start, end, and bottom
facets for
the padding.