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?
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); } };
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 ...
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 ?
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.
> 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.
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) ?
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.
> 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
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
On 8/21/06, Luc Claes <luc.cl...@gmail.com> wrote:
> > 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:
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 !