Determine widget size after load

415 views
Skip to first unread message

Glenn

unread,
Oct 17, 2011, 7:48:03 PM10/17/11
to Google Web Toolkit
I have a GWT Canvas which I would like to size to the allocated width/
height of it's container Widget. In my case I have a LayoutContainer
whose size is 30% width so it varies depending on the window size.

I can use onResize() to detect when the size has changed but how do I
size the canvas initially to the proper size? When my class gets
constructed the size is zero so I can't do it in the constructor.

Is there an event/callback that I can use to detect the layout size at
startup so I can create the canvas and draw it with the appropriate
sizes?

In android land I have an onLayout() callback that is convenient for
this type of initialization. Is there something similar for GWT?

Thanks,

Glenn

Uemit

unread,
Oct 18, 2011, 10:50:28 AM10/18/11
to google-we...@googlegroups.com
I think there are two ways to do that. 

1.) Call forceLayout() on your LayoutContainer. This will call onResize on all client widgets which implement the RequireResize interface.
In the onResize method of your canvas widget you can retrieve the available width by calling getParent().getOffsetWidth() (instead of getParent() you can call it on a container panel etc)

2.) When the canvas widget gets constructed you can issue a deferred command and set the size in it: 
Scheduler.get().scheduleDeferred(new ScheduledCommand() {
    @Override
    public void execute() {
        canvasWidget.onResize();
    }
});

 

Glenn

unread,
Oct 18, 2011, 1:05:52 PM10/18/11
to Google Web Toolkit
The 2nd method appears to work. See comments below.

On Oct 18, 7:50 am, Uemit <uemit.se...@gmail.com> wrote:
> I think there are two ways to do that.
>
> 1.) Call forceLayout() on your LayoutContainer. This will call onResize on
> all client widgets which implement the RequireResize interface.
> In the onResize method of your canvas widget you can retrieve the available
> width by calling getParent().getOffsetWidth() (instead of getParent() you
> can call it on a container panel etc)
>

I called forceLayout after adding the container to it's parent but the
size available via getElement().getClientWidth() when onSize is called
is -22,0. It would appear the layout engine has not actually done
it's job yet so the sizes are not apportioned.

> 2.) When the canvas widget gets constructed you can issue a deferred command
> and set the size in it:
>
> Scheduler.get().scheduleDeferred(new ScheduledCommand() {
>     @Override
>     public void execute() {
>         canvasWidget.onResize();
>     }
> });

This 2nd approach works! I'm a bit worried about timing since #1 did
not work though. Can I know for sure the size has been set by the
time it has been scheduled?

I decided to combine the two suggestions so after I've added my layout
to the DOM I use the Scheduler trick to call onResize() on the
container. This allows other child views that have also been added
during the creation process to get notified including the layout that
contains the Canvas element.

I could have called forceLayout() but since the layout seemed to have
already been done by the time the scheduler callback occurred I just
used onResize().

This seems like something that should be in the framework - calling
onResize() when a layout has been added to the DOM.

Thanks for the tip!

Glenn

unread,
Oct 18, 2011, 6:21:31 PM10/18/11
to Google Web Toolkit
OK, now that I have a workaround for a basic LayoutPanel I've
discovered that when the Canvas is on one of the tabs of a TabPanel I
have the same problem - when a tab becomes visible how do I
communicate the size information to the canvas drawing routine? I
tried making a SelectionHandler for the TabPanel and calling onResize
but the new tab is not visible yet. Ditto for using the Schedule
trick and calling onResize().

Any ideas for how to obtain the container size of a Canvas when it's
on a tab panel?

Uemit

unread,
Oct 20, 2011, 10:54:03 AM10/20/11
to google-we...@googlegroups.com
Are you using a TabPanel or a TabLayoutPanel? I think you have to use a TabLayoutPanel instead of a TabPanel because the TabLayoutPanel implements both ProvideResize and RequireResize interfaces.
Basically you always have to a chain of Panels which implement those interfaces in order to properly propagate the resize event. 
If you put your Canvas Widget not in a LayoutPanel you have to set a specific height and width for the parent container widget in order to retrieve the dimensions otherwise I think getOffsetWidth will always return 0. 


eho...@usdataworks.com

unread,
May 21, 2015, 5:39:25 PM5/21/15
to google-we...@googlegroups.com
The deferred command works most of the time, but not always.  I'm seeing a zero height and width about 5% of the time in Chrome.

Anyone have other ideas?

Blaze

unread,
May 22, 2015, 9:58:38 AM5/22/15
to google-we...@googlegroups.com
You need to initiate the sizing of the canvas after the real sizing fo the wrapper components is done.

What I mean is, this wrapp has some kind of layout logic(usually this layouts are not happening before the comp becomes attached and visible) . So u need to lesten for this "event", and after this is done to use wrap.getSize and set this size on the canvas. In this moment the wrap.size will have the correct values...

eho...@usdataworks.com

unread,
May 27, 2015, 11:14:50 AM5/27/15
to google-we...@googlegroups.com
I don't understand.  What event are you talking about?  And what "wrapper"?
Reply all
Reply to author
Forward
0 new messages