PDA

View Full Version : javascript error when using LayoutContainer with DockLayoutPanel in IE7



mike b
21 Dec 2010, 3:42 PM
I'm finding that b/c LayoutContainer doesn't implement RequiresResize that I get the failure below.

Any tips for implementing RequiresResize?

Thanks,
Mike

Test case:


public void onModuleLoad() {
DockLayoutPanel outer = new DockLayoutPanel(Unit.EM);
outer.addNorth(new HTML("North"), 15);
LayoutContainer lc = new LayoutContainer();
lc.add(new HTML("Center"));

outer.add(lc);

RootLayoutPanel rp = RootLayoutPanel.get();
rp.add(outer);
}Error message:


com.google.gwt.core.client.JavaScriptException: (TypeError): 'children' is null or not an object number: -2146823281 description: 'children' is null or not an object
at com.google.gwt.dev.shell.BrowserChannelServer.invokeJavascript(BrowserChannelServer.java:237)
at com.google.gwt.dev.shell.ModuleSpaceOOPHM.doInvoke(ModuleSpaceOOPHM.java:126)
at com.google.gwt.dev.shell.ModuleSpace.invokeNative(ModuleSpace.java:561)
at com.google.gwt.dev.shell.ModuleSpace.invokeNativeVoid(ModuleSpace.java:289)
at com.google.gwt.dev.shell.JavaScriptHost.invokeNativeVoid(JavaScriptHost.java:107)
at com.google.gwt.layout.client.LayoutImplIE6.resizeHandler(LayoutImplIE6.java)
at com.google.gwt.layout.client.LayoutImplIE6.finalizeLayout(LayoutImplIE6.java:148)
at com.google.gwt.layout.client.Layout.layout(Layout.java:511)
at com.google.gwt.user.client.ui.LayoutCommand.execute(LayoutCommand.java:66)
at com.google.gwt.core.client.impl.SchedulerImpl$Task$.executeScheduled$(SchedulerImpl.java:50)
at com.google.gwt.core.client.impl.SchedulerImpl.runScheduledTasks(SchedulerImpl.java:229)
at com.google.gwt.core.client.impl.SchedulerImpl.flushFinallyCommands(SchedulerImpl.java:328)
at com.google.gwt.core.client.impl.Impl.exit(Impl.java:238)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at com.google.gwt.dev.shell.ModuleSpace.onLoad(ModuleSpace.java:409)
at com.google.gwt.dev.shell.OophmSessionHandler.loadModule(OophmSessionHandler.java:183)
at com.google.gwt.dev.shell.BrowserChannelServer.processConnection(BrowserChannelServer.java:510)
at com.google.gwt.dev.shell.BrowserChannelServer.run(BrowserChannelServer.java:352)
at java.lang.Thread.run(Unknown Source)

mike b
21 Dec 2010, 3:49 PM
arghhh worse than I thought. Its using RootLayoutPanel at all.


public void onModuleLoad() {
LayoutContainer lc = new LayoutContainer();
lc.add(new HTML("Center"));
RootLayoutPanel rp = RootLayoutPanel.get();
rp.add(lc);
}Is RootLayoutPanel completely incompatiable with GXT?

Thanks,
M

sven
21 Dec 2010, 5:32 PM
The code works fine for me. However you should not use it, as GXT does not implement any of the needed interfaces due to backward compatibility.

mike b
22 Dec 2010, 5:45 AM
I think there would only be problems in IE6 and IE7. Who knows, maybe its just the unique IE/Windows bundle that is the standard here at my employer.

Anyway, this solution seems to work. I just wrap the LayoutContainer in a GWT Composite (not ResizeComposite) and GWT apparently renders it w/out the offending javascript.



public class GXTWrapper extends Composite {

FlowPanel panel;

public GXTWrapper() {

panel = new FlowPanel();
panel.setSize("100%", "100%");
initWidget(panel);
}

public void wrap(LayoutContainer lc ) {
panel.add(lc);
}

public void unwrap(LayoutContainer lc ) {
panel.remove(lc);
}

}

sven
22 Dec 2010, 5:49 AM
I missed the IE7 in the topic, i only run it in IE8 and FF.

The code you are using now is not sizing the layoutcontainer. GXT containers needs also to be sized to make the layout work correctly. Why do you want to use a RootLayoutPanel and put the layoutcontainer into it?

mike b
22 Dec 2010, 5:56 AM
I have previously set the sizes in my GXT containers w/ px rather than %. % doesn't seem to work. For example, in a LayoutContainer with a BorderLayout, when I call setSize("100%", "100%") I end up with an 1 inch square. I would have thought that it would fill space of about 1200px/800px

Is there a strategy for setting a LayoutContainer to fill available space in an enclosing div or table?

Thanks,
mike

sven
22 Dec 2010, 5:58 AM
Is there a strategy for setting a LayoutContainer to fill available space in an enclosing div or table?

You need to know when the parent sizes and than resize the layoutcontainer.

As you use a RootLayoutPanel you probably want it to be as big as the browser? You can use a Viewport for this.

mike b
22 Dec 2010, 5:58 AM
Oh, I'm trying to use the GWT 2x LayoutPanel framework rather than the old one. This is supposed to work better than RootPanel. Also, I have been mandated to get rid of java compiler warnings due to deprecation. So, that necessitates going to RootLayoutPanel as many of the old Panels have been deprecated.

Thanks,
Mike

mike b
22 Dec 2010, 6:20 AM
Viewport looks like it would be great if GXT owned the entire application. HOwever, about 75% is written in pure GWT. So, GXT needs to be able to "play well with others" and be controlled by a GWT navigation.

I just tried Viewport and it did expand fully, but went off the page on the right and bottom because it wasn't aware of the other tabs and menu bars on the top of the screen.

Is there a way around that? I"m looking at hacking Viewport.onWindowResize()

thanks,
Mike

sven
22 Dec 2010, 6:21 AM
You can setup an own window resize listener (Window class from GWT handles this) and resize your widget as needed. No need to use Viewport in this case.

mike b
22 Dec 2010, 6:28 AM
thanks!

mike b
22 Dec 2010, 8:30 AM
Sven, thanks for the resize tip. Somehow I hadn't seen that before.

So, I ended up shoving my GXT ResizeableLayoutContainers into a FlowPanel (i.e. a DIV). When I put the GXT window onto the screen, I call listenForResize. When I remove it from the screen, I call stopResizing so that the window doesn't continue wasting resources resizing when its not visible.

I found that its necessary to use the Scheduler to actually resize the widget so that GWT has finished resizing its stuff first.



................
protected ResizeHandler resizeHandler = new ResizeHandler() {

@Override
public void onResize(ResizeEvent event) {
if( getParent() != null ) {
int pw = getParent().getOffsetWidth();
int ph = getParent().getOffsetHeight();
GWT.log("onResize: w-"+pw + " h-"+ph);

resizeToParent();

}
}
};
..............

public void resizeToParent() {

//let GWT do a bunch of other resizing before
// doing this widget
Scheduler.get().scheduleDeferred(new ScheduledCommand() {
@Override
public void execute() {
int w = getParent().getOffsetWidth();
int h = getParent().getOffsetHeight();
GWT.log("resizeToParent: w-"+w + " h-"+h);
setSize(w,h );

}
});

}

sven
22 Dec 2010, 8:31 AM
Add a nullcheck in the scheduledcommand. getParent() could return null if the widget gets removed from a parent in the meantime.