PopupPanel and it's size (GWT 1.1)

1283 views
Skip to first unread message

Ayzen

unread,
Aug 13, 2006, 5:40:13 PM8/13/06
to Google Web Toolkit
Hi.

This code works in GWT 1.0.21 and doesn't work with new release:

setPopupPosition(0, 0);
super.show();
setPopupPosition((Window.getClientWidth() - getOffsetWidth()) / 2,
(Window.getClientHeight() - getOffsetHeight()) / 2);

I'm using this in my popup's show() method for positioning it in the
middle of the screen, but in GWT 1.1 popup's "getOffset..." methods
return very small and not correct numbers.

What's wrong with PopupPanel in GWT 1.1 or what should I use to get the
size of my popup?

Thanks.

blambeau

unread,
Aug 14, 2006, 10:28:36 AM8/14/06
to Google Web Toolkit
First idea: are you sure that you call the show() method before
querying getOffset...() methods ? Offset sizes cannot be determined
before adding the popup to the DOM (after super.show() when using
Popups).

Second idea: I've got similar problems with popups ... but in a more
complicated situation. The following example works correctly (maybe
your simplified example here does not suffer the problem at all) :

public void onModuleLoad() {

PopupPanel sample = new PopupPanel() {
public void show() {
super.show();

int cWidth = Window.getClientWidth();
int cHeight = Window.getClientHeight();
int myWidth = getOffsetWidth();
int myHeight = getOffsetHeight();
setPopupPosition((cWidth-myWidth)/2,(cHeight-myHeight)/2);
}
};

sample.add(new HTML("<h1>Hello world</h1>"));
DOM.setStyleAttribute(sample.getElement(),"border","1px dashed
black");
sample.show();
}

In my case, it seems that the getOffset...() methods return correct
results only when the browser has been "javascript idle" at least one
time between the popup creation and the Offset size query. I don't
understand the problem exactly for now but I resolved it by using
DeferredCommand. Really strange ...

blambeau

Ayzen

unread,
Aug 18, 2006, 4:20:26 AM8/18/06
to Google Web Toolkit
Hi blambeau.

Thanks for your reply. It works with DeferredCommand.

But is it a bug? In version 1.0.21 "getOffset..." methods work fine for
popups...

blambeau

unread,
Aug 18, 2006, 10:52:17 AM8/18/06
to Google Web Toolkit
I think it can be seen as a bug ...

However, I cant' understand the real bug cause, and then I'm not able
to provide a short entry point to reproduce it. This kind of material
is probably needed by the GWT team to fix the bug. Maybe you have ?

blambeau

Scott Blum

unread,
Aug 18, 2006, 5:25:17 PM8/18/06
to Google-We...@googlegroups.com
Hi Ayzen,

The size of any DOM element cannot be queried until it is fully
attached to the DOM. Instead of overriding show(), try overriding
onAttach():

protected void onAttach() {
super.onAttach();
int left = (Window.getClientWidth() - getOffsetWidth()) / 2;
int top = (Window.getClientHeight() - getOffsetHeight()) / 2;
setPopupPosition(left, top);
}

Scott

blambeau

unread,
Aug 18, 2006, 7:27:03 PM8/18/06
to Google Web Toolkit
Hi all,

same discussion here :
http://groups.google.com/group/Google-Web-Toolkit/browse_frm/thread/7bbb89e4c97ae1e6

I'm not sure to understand the problem exactly but it seems that, in
release 1.1, the real attachement of a widget to the DOM is not ensured
as a post condition of add(Widget). I think that the real attachement
is made asynchronously (need confirmation, by a GWT expert ...), and
notified by onAttach. When using popup, show() calls add() but cannot
ensure that the attachement is made.

Any expert comment welcome here.

Solutions:

1) DefferedCommand : not safe because you can't assume that the command
is actually executed before popup attachement (seems to be, but
not a specification).

2) onAttach will probably work, onLoad is better (javadoc of onAttach :
"It must not be overridden, [...] To receive notification when a widget
is attached to
the document, override the onLoad method). However, if your
popup/dialog is not directly responsible of its own placement, it's not
the place to use but ...

3) ... in this last case, the 'popup position responsible' may wait for
isAttached() to be true, with a repeating Timer for example (I don't
like that solution).

4) Finally, an external onLoad notification provided by the popup seems
the best choice to me.

blambeau

Scott Blum

unread,
Aug 18, 2006, 8:05:52 PM8/18/06
to Google-We...@googlegroups.com
On 8/18/06, blambeau <blam...@gmail.com> wrote:
> 2) onAttach will probably work, onLoad is better (javadoc of onAttach :
> "It must not be overridden, [...] To receive notification when a widget
> is attached to the document, override the onLoad method).

My bad! You're quite right, overriding onLoad() is the preferred approached.

Scott

Luc Claes

unread,
Aug 21, 2006, 9:53:53 AM8/21/06
to Google Web Toolkit
Hi,

I must be missing something.
Take the following simple example:

public class AboutDialog extends DialogBox {
public AboutDialog() {
DockPanel panel = new DockPanel();

setText("About");
HTML aboutText = new HTML("Test application");
panel.add(aboutText, DockPanel.CENTER);

setWidget(panel);
}

public void show() {
super.show();
DeferredCommand.add(new Command() {
public void execute() {
// 'Too late': the dialogbox 'jumps' to its destination position
center();
}
});
}

public void onLoad() {
center(); // 'Too early': getOffsetWidth and getOffsetHeight are not
yet defined
}

public void center() {
int nLeft = (Window.getClientWidth() - getOffsetWidth()) / 2;
int nTop = (Window.getClientHeight() - getOffsetHeight()) / 2;
setPopupPosition(nLeft, nTop);
}
}

- The popup dimensions seems not to be correctly defined at 'onLoad()'
time.
- Dimensions are correctly defined when using a DeferredCommand but the
dialogbox 'jumps' to its final destination (even if onLoad() is left
undefined).

Is there something wrong in the above code ?
If not, is there an intermediate solution (ie 'known' dimensions and
no jump effect) ?

Luc

Scott Blum

unread,
Aug 21, 2006, 2:55:16 PM8/21/06
to Google-We...@googlegroups.com
Luc,

Are you using 1.1.0? I tested your exact code on Win32 hosted,
IE/Win32 web, and FF/Win32 web. I commented out your show() override
and got exactly the behavior you would expect.. calling getOffset*()
from onLoad() worked fine for me.

Scott

Luc Claes

unread,
Aug 21, 2006, 3:29:15 PM8/21/06
to Google Web Toolkit

Scott,

Yes, I'm using GWT 1.1.0.

In both hosted mode (Win32) and FF 1.5.0.6, I obtain the following
values:

At 'onLoad()' time: getOffsetWidth() : 3, getOffsetHeight() : 3
At 'DeferredCommand' time: getOffsetWidth() : 78, getOffsetHeight() :
46

Luc

Scott Blum

unread,
Aug 21, 2006, 10:32:19 PM8/21/06
to Google-We...@googlegroups.com
Luc,

My mistake. You are indeed right, it's borked. I didn't notice
before I posted that in your sample, the text is off-center; just as
you'd expect if it centered on the top-left corner (as if it had zero
size). This is broken, and it seems the only workaround right now is
to do a DeferredCommand and deal with jumpiness. This issue is on
Joel's hotlist for the upcoming release.

Thanks!
Scott

blambeau

unread,
Aug 22, 2006, 5:57:10 AM8/22/06
to Google Web Toolkit
Hi,

your example confirms to me that the real behavior of GWT when
attaching widgets to the DOM stay unclear.

Could anyone provide a clear explanation of the way widgets are
attached?

Working on another example (not popup), I realized that the onLoad()
approach is not ensured to work, because
the real size of a Widget depends of its children. It seems that
onLoad() of the parent may be called before the
onLoad() notification of the children (probably a requirement for some
situations ?), explaining that the approach
does not work if the children load take some time.

Why does the DeferredCommand work ? Probably because the children
attachements is executed first ! Here again,
it's not a perfect explanation ... A better one should be based on the
architecture of GWT and javascript generated code.
I'm not GWT expert and I never used javascript before. Many subtilities
are unclear to me ... sorry !

blambeau

Reply all
Reply to author
Forward
0 new messages