1

I'm trying to center an element that contains a CellTable. The actual centering logic works okay, but I'm having problems with all those attaching/detaching events. Basically, I'm doing this in my container widget:

@Override
public void onLoad() {
  super.onLoad();
  center();
}

However, it seems that onLoad on the container does not mean that all children have loaded, so... the actual centering routine is called too early and Element.getOffsetWidth/getOffsetHeight are both returning 0. This results in the container being displayed with the left upper corner in the center of the screen.

Same thing happens if I use an AttachEvent.Handler on the CellTable.

So... is there any event on CellTable, or on Widget or whatever that allows me to trigger an action when the DOM subtree has been attached to the DOM?

Thanks in advance.

Ionuț G. Stan
  • 176,118
  • 18
  • 189
  • 202

2 Answers2

2

Take a look at scheduleDeferred. A deferred command is executed after the browser event loop returns.

Scheduler.get().scheduleDeferred(new ScheduledCommand() {
    @Override
    public void execute() {
        center();
    }
});
pistolPanties
  • 1,880
  • 13
  • 18
  • It seems to work, but what are the chances that this command would be execute *before* the command used internally by CellTable to render the rows? I'm asking because it uses `scheduleFinally`, and to be honest, I haven't yet understand all this variety of scheduling. – Ionuț G. Stan Aug 24 '11 at 12:12
  • None, unless CellTable schedules other deferred commands to render the rows. Here is a useful answer about Scheduler methods. [http://stackoverflow.com/questions/5131086/using-the-gwt-scheduler](http://stackoverflow.com/questions/5131086/using-the-gwt-scheduler). – pistolPanties Aug 24 '11 at 12:48
1

Override onAttach instead of onLoad. onAttach default implementation calls onLoad followed by doAttachChildren (which calls onAttach on each child widget), so the following code should call center after the children have been attached:

@Override
public void onAttach() {
  super.onAttach();
  center();
}

(BTW, the default implementation of onLoad is a no-op)

Thomas Broyer
  • 64,353
  • 7
  • 91
  • 164
  • Doesn't work because the table data is rendered using `Scheduler.scheduleFinally` inside `HasDataPresenter.ensurePendingState()`. However, `HasDataPresenter.resolvePendingState` does the real work, and it seems this can be invoked indirectly using `CellTable.getRowElement` which calls `HasDataPresenter.flush` and then `HasDataPresenter.resolvePendingState`. – Ionuț G. Stan Aug 24 '11 at 11:49
  • Quite hacky IMHO, but it seems the only way to force rendering on the `CellTable`. An alternative solution, cleaner, would have been to listen for the `LOADED` event using `AbstractHasData.addLoadingStateChangeHandler`. Unfortunately, the `LOADED` event is triggered before the rendering is performed. – Ionuț G. Stan Aug 24 '11 at 11:49