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.
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
Thanks for your reply. It works with DeferredCommand.
But is it a bug? In version 1.0.21 "getOffset..." methods work fine for
popups...
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
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
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
My bad! You're quite right, overriding onLoad() is the preferred approached.
Scott
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
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
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
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
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