GXT(Ext-GWT):ContentPanel的布局问题

我有一个适合整个窗口的ContentPanel。 它有一个topComponent,一个中心的小部件和一个bottomComponent。

当我在ContentPanel渲染一次后尝试将小部件添加到topComponent时,我遇到了布局问题:

public void onModuleLoad() { final Viewport viewport = new Viewport(); viewport.setLayout(new FitLayout()); final ContentPanel contentPanel = new ContentPanel(new FitLayout()); contentPanel.setHeaderVisible(false); final LayoutContainer topContainer = new LayoutContainer( new FlowLayout()); final Button buttonOne = new Button("Top:One"); topContainer.add(buttonOne); contentPanel.setTopComponent(topContainer); contentPanel.add(new Button("Center")); contentPanel.setBottomComponent(new Button("Bottom")); viewport.add(contentPanel); RootPanel.get().add(viewport); // Later, add a second button to the topComponent ... Scheduler.get().scheduleDeferred(new ScheduledCommand() { @Override public void execute() { final Button buttonTwo = new Button("Top:Two"); topContainer.add(buttonTwo); // Doesn't show up at first. topContainer.layout(); // Now, buttonTwo shows up. But we have // a new problem: the "Bottom" button disappears... contentPanel.layout(true); // This doesn't do anything, BTW. } }); } 

关于这一点的一个有趣的事情是,只要我调整浏览器窗口大小,布局就会自行纠正。 我可以做些什么来使它立即正确重新布局(我已尝试在几个地方和组合中添加几个layout()调用等,但到目前为止还没有任何运气。)

(我正在使用GWT 2.1.1和GXT 2.2.1。)

发生这种情况是因为当您向FlowLayout添加另一个组件时,它会resize,从而增加其自身的高度,从而将底部组件推到可见区域下方。 代码中没有任何东西缩小中心组件,因此底部组件保持在其原始位置。

还有一件事是你使用FitLayout为contentPanel包含3个组件,FitLayout用于容器内部只有一个组件,它应该填充其父组件。

您需要考虑以下事项:

1)使用RowLayout,它可以更好地控制组件的布局方式

2)确定您愿意放置垂直滚动条的组件,因为您要动态添加组件。

对于您当前的要求,以下代码应该足够:

 public void onModuleLoad() { final Viewport viewport = new Viewport(); viewport.setLayout(new FitLayout()); // final ContentPanel contentPanel = new ContentPanel(new FlowLayout()); // contentPanel.setHeaderVisible(false); final LayoutContainer topContainer = new LayoutContainer( new FlowLayout()); final Button buttonOne = new Button("Top:One"); topContainer.add(buttonOne); // contentPanel.setTopComponent(topContainer); final LayoutContainer centerPanel = new LayoutContainer(new FitLayout()); centerPanel.add(new Button("Center")); // contentPanel.add(centerPanel); final LayoutContainer botPanel = new LayoutContainer(new FlowLayout()); botPanel.add(new Button("Bottom")); // contentPanel.setBottomComponent(botPanel); final ContentPanel panel = new ContentPanel(); panel.setHeaderVisible(false); panel.setLayout(new RowLayout(Orientation.VERTICAL)); panel.add(topContainer, new RowData(1, -1, new Margins(4))); panel.add(centerPanel, new RowData(1, 1, new Margins(0, 4, 0, 4))); panel.add(botPanel, new RowData(1, -1, new Margins(4))); viewport.add(panel, new FlowData(10)); RootPanel.get().add(viewport); // Later, add a second button to the topComponent ... Scheduler.get().scheduleDeferred(new ScheduledCommand() { @Override public void execute() { final Button buttonTwo = new Button("Top:Two"); topContainer.add(buttonTwo); // Doesn't show up at first. panel.layout(true); } }); } 

发生这种情况是因为在此语句中调用了topComponentonRender事件:

 contentPanel.setTopComponent(topContainer); 

然后,稍后,您要添加一个组件: topContainer.add(buttonTwo); 。 调整窗口大小时,会触发onRender事件,并显示添加的按钮。 您的问题的解决方案涉及触发onRender事件。

不幸的是, onRender受到保护,因此您无法直接调用它: http : //dev.sencha.com/deploy/gxtdocs/com/extjs/gxt/ui/client/widget/LayoutContainer.html#onRender%28com.google.gwt .user.client.Element,%20int%29

您将需要使用fireEvent以编程方式触发此操作,而不是手动调整窗口大小: http : //dev.sencha.com/deploy/gxtdocs/com/extjs/gxt/ui/client/widget/Component.html#fireEvent%28com .extjs.gxt.ui.client.event.EventType 29%

一旦浏览器完成呈现窗口小部件,它就不会再次呈现该组件,所以再次执行它我们可以使用contentPanel.layout()或contentPanel.layout(true)它根据新布局重新呈现窗口小部件。