views:

25

answers:

1

I'm using gwt-dnd to implement drag-and-drop functionality in my GWT program. To get scrolling to work right, I need

<ScrollPanel>
    <AbsolutePanel>
        <VerticalPanel>
             <!-- lots of draggable widgets -->
        </VerticalPanel>
    </AbsolutePanel>
</ScrollPanel>

I have to manually set the size of the AbsolutePanel to be large enough to contain the VerticalPanel. When I add widgets to the VerticalPanel, though, the size reported by VerticalPanel.getOffsetHeight() isn't immediately updated - I guess it has to be rendered by the browser first. So I can't immediately update the AbsolutePanel's size, and it ends up being too small. Argh!

My stop-gap solution is to set up a timer to resize the panel 500ms later. By then, getOffsetHeight will usually be returning the updated values. Is there any way to immediately preview the size change, or anything? Or, alternatively, can I force a render loop immediately so that I can get the new size without setting up a timer that's bound to be error-prone?

+2  A: 

This is a common problem with DOM manipulations. The offsetHeight doesn't update until a short time after components are added. I like to handle this using a recursive timer until a pre-condition is violated. E.g. In your case let there be a function which adds components and will be defined as below:

public void addComponent(Widget w)
{
 final int verticalPanelHeight = verticalPanel.getOffsetHeight();
 verticalPanel.add(w);
 final Timer t = new Timer(){
  public void run()
  {
   if(verticalPanelHeight != verticalPanel.getOffsetHeight())
    absolutePanel.setHeight(verticalPanel.getOffsetHeight() + 10 + "px");
   else
    this.schedule(100);
  }
 };
 t.schedule(100);
}
Gaurav Saxena