getOffsetHeight returns 0 although onload has been called

766 views
Skip to first unread message

George Agiasoglou

unread,
Nov 29, 2011, 11:08:11 AM11/29/11
to google-we...@googlegroups.com
Hi group, 

Consider an application which has a DeckLayoutPanel as a shell, and has two DockLayoutPanel as children, which means only one child is shown at any time. I am using MVP with Activities and Places, there are two places and each place corresponds to displaying a child. 

When the app is initialised both children are injected (by gin) and added to the DeckLayoutPanel.

And looks like 

class MyApplication {

 MyApplication(DockLayoutPanel child1, DockLayoutPanel child2) {
 ...
}
 ...

}

Application displays child1, user changes to other place to display child2. Everything is displayed fine however I need to calculate an area using getOffsetHeight and getOffsetWidth, however both calls return 0. If now I change the token of the place in the url to another valid token both calls return actual values.

Any ideas why this is happening?


Thanks,
G



--
"Please consider the environment before printing this e-mail"
 
The Newspaper Marketing Agency: Opening Up Newspapers:
 
http://www.nmauk.co.uk/
 
This e-mail and any attachments are confidential, may
be legally privileged and are the property of NI Group 
Limited (which is the holding company for the News
International group, is registered in England under number
81701 and whose registered office is 3 Thomas More Square, 
London E98 1XY, VAT number GB 243 8054 69), 
on whose systems they were generated.

If you have received this e-mail in error, please notify 
the sender immediately and do not use, distribute, store 
or copy it in any way.

Statements or opinions in this e-mail or any attachment 
are those of the author and are not necessarily agreed 
or authorised by NI Group Limited or any member of its 
group.

NI Group Limited may monitor outgoing or incoming 
emails as permitted by law. It accepts no liability 
for viruses introduced by this e-mail or attachments.

skippy

unread,
Nov 29, 2011, 2:53:42 PM11/29/11
to Google Web Toolkit
From what I have found is the objects need to be visable in the
Document object first.
So try this:

public static void adjustHeight(final DockLayoutPanel topPanel, final
SimplePanel bodyPanel, final DockLayoutPanel outerPanel, final boolean
isIpad)
{
Scheduler.get().scheduleDeferred(new Scheduler.ScheduledCommand()
{
public void execute()
{
// do your stuff.

outerPanel.forceLayout();
}
});
}

let me know if this help!

On Nov 29, 10:08 am, George Agiasoglou
<George.Agiasog...@newsint.co.uk> wrote:
> Hi group,
>
> Consider an application which has a *DeckLayoutPanel* as a shell, and has


> two DockLayoutPanel as children, which means only one child is shown at any
> time. I am using MVP with Activities and Places, there are two places and
> each place corresponds to displaying a child.
>
> When the app is initialised both children are injected (by gin) and added

> to the *DeckLayoutPanel.*

Vitrums

unread,
Nov 30, 2011, 4:26:16 AM11/30/11
to google-we...@googlegroups.com
getOffsetHeight() of an element which display property was set to none will always return 0

Ed

unread,
Nov 30, 2011, 4:43:00 AM11/30/11
to Google Web Toolkit
Make sure your widget is attached (check the attached property) before
requesting the widget for any dimensions.

Example: in my animation components I always first check that the
widget is attached as otherwise the animations are based on (most of
the time) incorrect dimensions as the browser didn't had time to
render them correctly.
This check overcomes a lot of problems.

George Agiasoglou

unread,
Nov 30, 2011, 5:37:05 AM11/30/11
to google-we...@googlegroups.com
Thank you for your suggestions, however, the display property is not set to none, actually is not set at all.

George Agiasoglou

unread,
Nov 30, 2011, 7:19:21 AM11/30/11
to google-we...@googlegroups.com
 t @Vitrums

I am convinced that my problem is caused because the property display is set to none, however I don't know how to solve it. 

I could add an AnimationCallback on the decklayoutPanel to find out when the widget is finally being displayed, but that kinda defeats the use of Activity.start()

LazyLoading and how to implement this?

Any suggestions?

Many thanks for your help so far!
-G

Ed

unread,
Nov 30, 2011, 8:25:56 AM11/30/11
to Google Web Toolkit
Use firebug to analyze your problem.
If it's your display property then change this by
widget.getElement().getStyle().setDisplay(Display.BLOCK) (can be
little different).
By default the Display property is set to auto so if you aren't
setting it, it wouldn't give you any problem.


On Nov 30, 1:19 pm, George Agiasoglou

George Agiasoglou

unread,
Nov 30, 2011, 11:10:29 AM11/30/11
to google-we...@googlegroups.com
The problem is that I call getOffsetHeight/Width on a panel which belongs to a widget which has display property set to none. The display property is set to none because that widget is not currently displayed by the decklayoutpanel but it is attached to it, which is the desired behaviour.  

I am using firebug and chrome dev tools extensively. To use those tools, that means that your view is layed out in the browser so everything is fine. 

The DeckLayoutPanel sets disiplay: none to all its children apart from the one currently being displayed. I tried, to postpone the call to getOffsetHeight after deckLayoutPanel.setWidget(widget) but still returned 0.

Thanks, 
G << pulls his hair :( 

Jens

unread,
Nov 30, 2011, 12:10:39 PM11/30/11
to google-we...@googlegroups.com
getOffsetHeight/Width only returns a value other than 0 if the element has been successfully rendered by the browser (possibly including elements that have visibility:hidden css).

When you call DeckLayoutPanel.setWidget(w) the DeckLayoutPanel schedules a layout command which will be executed after all of your code has been executed and just before the browser takes back control (see: Scheduler.get().scheduleFinally()). I think this has been done because you could call DeckLayoutPanel.setWidget() multiple times in your code, but when your code is done, the necessary DOM operations will be executed only once.

You can force the DOM operations by calling DeckLayoutPanel.forceLayout() just after you have called DeckLayoutPanel.setWidget() and then try to do your calculations. But I am not quite sure if its enough. If not, your best bet is to defer your calculations until everything has been rendered by the browser:

final Panel p = ...
Scheduler.get().scheduleDeferred(new Scheduler.ScheduledCommand() {
  public void run() {
    p.getOffsetHeight() ... //calculate your stuff
  }
});

Using a deferred command should definitely work.

-- J.

Andrei

unread,
Nov 30, 2011, 12:14:45 PM11/30/11
to Google Web Toolkit
You don't need getOffsetHeight to achieve what you want. There are two
solutions:

1. Use LayoutPanel instead of DockLayoutPanel. LayoutPanel allows you
to add two widgets that occupy the same space. If you don't specify
the position of each child widget, each child widget will occupy the
entire space available. From this moment all you need to do is hide
one of them depending on where users clicks.

2. When necessary, detach one widget and attach the other one. In each
case these widgets should pick up their size automatically from their
parent widget - there is no need to set their size explicitly as long
as you use widgets that support resize.

George Agiasoglou

unread,
Nov 30, 2011, 12:39:24 PM11/30/11
to google-we...@googlegroups.com
Unfortunately, I need the width and height of the area because I append that information on a url.

I will try the deferred command and let you know.


Many thanks,
G

George Agiasoglou

unread,
Nov 30, 2011, 12:46:18 PM11/30/11
to google-we...@googlegroups.com
Absolutely brilliant, the deferred command worked like a charm.

Many thanks to all of you!
-G
Reply all
Reply to author
Forward
0 new messages