Skip to main content

Layout Tips - Stretching components to fit browser window

ADF Faces is packaged with rich set of layout managers which makes layout problems trivial. If you really want to have a feel of ADF Faces Layout components, please go through this ADF Faces Demo. If you come from Java Swing world, you can see lots of familiar faces here as well. I really like the ADF Faces stretchable layouts with which you can easily build hassle free, browser friendly web applications. Recently, I noticed an interesting post from Matt Cooper on exploring the richness of PanelStretchLayout - Stretchable Tiled Layout . This idea is very useful when you need to stretch multiple child components based on the browser size.

A Case Study

At this time, let me share some basic tips on lay outing components on a web page built using ADF Faces by taking a simple example.

Consider a use case where you need to build a web page as shown below.


Apparently, screen is split in two parts - left hand side contains basic search functionality and right hand side contain a tabbed pane. UI requirement here is that inside the right pane all the components are supposed to occupy maximum available size on the screen(i.e. components are supposed to be stretchable). ADF Faces lay outing mechanism got a PanelSplitters component to divide a region into two parts with a repositionable divider.

PanelSplitters are used to divide a region into two parts with a repositionable divider. The two parts are identified as the "first" facet and the "second" facet. If the contained component supports it, the contents of a section will stretch to fill up all available space in that section. The panel splitter can be adjusted with the mouse, by pressing a collapse button, or by use of the arrow keys when the splitter is selected. A panel splitter can split horizontally or vertically based on the orientation attribute.

So af:panelSplitter can be used to split the screen in the above mentioned case as well.

Tabbed panel on right hand side can be realized using af:panelTabbed

This component uses <af:showdetailitem> to organize content into each tab body panel. The <af:showdetailitem> will allow stretching if:
* It contains a single child
* It has stretchChildren="first" specified
* The child has no width, height, margin, border, and padding
* The child must be capable of being stretched


At this stage, the jspx may look like as shown below;


How to stretch child components?

Now the task left is to identify the layout for the container which is smart enough to stretch it children as well. Fortunately ADF Faces do support af:panelStretchLayout that fits well with our requirement.

The panelStretchLayout component stretches the child in the center facet to fill all of available space. The available space may be constrained by the presence of other children in the top/bottom/start/end facets. When these children are present, they occupy space defined by the topHeight/bottomHeight and startWidth/endWidth attributes.

So far, so good. Now’s the time to sweat your brain. <af:panelStretchLayout>  comes with only 3 facets. As per the above UI design requirement, it is required to have 4 graphs to be displayed in equal size, occupying the available area on the parent container. No worries, <af:panelStretchLayout>  is smart enough to stretch it child 'layout containers' as well and there is a provision to specify heights in percentage for each facets ( topHeight / bottomHeight). So let us go ahead and add a child panelStretchLayout to keep the additional elements. Now the web page may have the below shown structure.


How to stretch a table?

Before winding up this session, let us have a quick look at stretchable table as well. Consider the second tab of the above UI where the requirement is to stretch table to fill the entire available area.


Obviously table (Here table is added inside panel header) needs to be wrapped inside a af:panelStretchLayout. Interestingly af:table got one special attribute - columnStretching - for stretching one of its column to spread over the available space of its immediate parent container. And ideal column for stretching could be one with maximum length, say for example 'description' column.

Further Reading
Chapter 8 Organizing Content on Web Pages from Web User Interface Developer's Guide will help you to understand ADF Faces layout components better.
Learn More ...

If  you are curious to learn the internals of the ADF Business Components and ADF Binding Layer,  the following book is for you - Oracle ADF Real World Developer’s Guide.
More details about this book can be found in this post- http://jobinesh.blogspot.in/2012/07/pre-order-your-copy-of-oracle-adf-real.html

Comments

Marcos Ortega said…
Great !! Well Done !
bala said…
Hi,
Lets say there are 5 columns in a table. If we want all the columns to be equally spaced and occupy the entire browser width, would it be possible?
Jobinesh said…
Bala
There is no direct declarative support for this specific case, as of now
bala said…
jobinesh,
Thanks for the reply. I have one more question:
How to assign width to columns in tables in a LOV window. In general, how to design model based LOV's.
Jobinesh said…
Bala
Currently ,this is not supported.But the default implementation is good enough to meet most of the use cases. That said, however there are plans to enhance this feature as well.
noname said…
Great stuff!
But I have another problem: how to get adf to give you scrollbars when content grows beyond page height? Using some other layout?
Beto said…
Hello!
I have a "resizing" issue.
I need to resize a table depending on the screen resolution. I wanted to resize the column width using percentages (%). Let's say:
Table width: 100%
Column1 width: 30%
Column2 width: 50%
Column3 width: 20%

This doesnt work, and has some bugs I think. Working with pixels works fine for me.

I tried to use your this stretchpanel but it did not work neither.

Do you have any suggestions for this?

Thanks,
Beto
Jobinesh said…
Beto
You may need to try setting columnStretching if the requirement is to stretch column to fill the available area in a table
Web design said…
Thanks for sharing. Did you know that CSS enables you to control over the positions and dimensions of all page elements.
sri said…
can your share the jspx page code. for me the page renders differently for different browsers
Vinitha said…
Hi,

The post was very useful.. i have 2 showdetailitems inside panelaccordin ... I need the items inside the panel accordin of equal height... but the inline style in detailitem doesn support it... i am unable to set the height for the detail items inside the panel accordin.. can u pl suggest me a slution on the same ..
Jobinesh said…
Vinitha,
I don't think you need to specify inline style here. Keep discloseMany="true" for panelAccordion, and disclosed="true" for showDetailItem. Refer demo - http://jdevadf.oracle.com/adf-richclient-demo/faces/components/panelAccordion.jsp
sanjay said…
Hey Jo,

Does adf has both sides panel splitter or Is there a way to use a panel splitter for left and right splits.
for example, when clicked on left arrow button, hide left pane and show right pane
when clicked on right arrow button, hide right pane and to show left pane

We have 2 big graphs on the left right sides of panel splitter(as shrieked graphs), we wanted to see the full view one at a time, on either sides.

Thanks,
Sanjay
Jobinesh said…
Sanjay,
Please see the demo -http://jdevadf.oracle.com/adf-richclient-demo/faces/components/panelSplitter.jspx
Shivakumar said…
This comment has been removed by the author.
Shivakumar said…
How to stretch the ADF table vertically, so that it occupies the entire dialog size.
Anonymous said…
Hi Jobinesh,

I was wondering if it is possible to set up a table in ADF where each row is of a different size based on the data it contains. If not, are there any work arounds I could try to change the row heights on a table?
maruf hosen said…
Nice article and great knowledge. Thanks for the share. I love this story and enjoy with your words!
Split face Tile
Sumeet Singh said…
My ADF Page is splitted in 2 sections using panelSplitter. In the first section of panelSplitter i have PanelCollection having table. It shows some records. What i want is to by readjusting the pannelSplitter the height of my table auto grows or shrinks.

Can you help me in this?
Hi Jobinesh,

I am Using Jdeveloper 11.1.1.7.0 . I am getting unwanted vertical scroll bar for table, when i am using pagination as shown below.














Eventhough i am setting fetch size as 25, and autoheightrows as 0 , the screen is not fitting to 25 records and it is showing vertical scroll bar. Could any one please provide solution for this.

Thanks in advance.

"Ramu".
This comment has been removed by the author.
Please find the code for the table in above comment.


panelGroupLayout id="pgl" layout="scroll"

panelCollection id="pc1" featuresOff="detach freeze statusBar wrap reorderColumnsMenuItem"

af:table value="#{bindings.VO1.collectionModel}"

var="row" rows="#{bindings.VO1.rangeSize}"

emptyText="#{bindings.VO1.viewable ? 'No data to display.' : 'Access Denied.'}"

fetchSize="25"

scrollPolicy="page" rowBandingInterval="0"

contentDelivery="immediate"

rowSelection="multiple" id="t1"

panelCollection

panelGroupLayout
shri hari said…
Nice! Really cool stuff and very inspiring. Thanks for sharing!
Web Designing Company In India

Popular posts from this blog

Happy New Year 2018 !

We can't go back and change the beginning, but we always can start where we are and change the ending. Believe in yourself and you will be unstoppable!

Wishing you and your family a very happy new year 2018 !!!

How to set Bind Variable Values at runtime ?

In this post I'm sharing a couple of approaches for programmatically setting bind variables values at run time. This post is an attempt to explain 'When to use what ?'[ In case if you are familiar with 'Bind Variables' in ADF BC, please refer Section 5.10, Working with Bind Variables in Fusion Developer's Guide ]

1. Set the Bind Variable value using RowSet::setNamedWhereClauseParam(...)

You can use use the setNamedWhereClauseParam(...) method on the ViewObject interface (which extends oracle.jbo.RowSet) to set the value for bind variables. Please note this sets the value on default RowSet. In other words, this doesn't have any effect on the secondary RowSets that you/system generates.
ViewObject vo = am.findViewObject("EmployeesView1"); vo.setNamedWhereClauseParam("bindVarDeptId", new Number(10)); vo.executeQuery();
2. Set the Bind Variable value using ViewObject's VariableValueManager::setVariableValue(...)

VariableValueManager Ma…