我有一个适合整个窗口的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。)
答案 0 :(得分:8)
这种情况正在发生,因为当您向FlowLayout添加另一个组件时,它会调整大小,从而增加其自身的高度,从而将底部组件推到可见区域下方。代码中没有任何东西缩小中心组件,因此底部组件保持在原始位置。
还有一件事是你正在使用FitLayout for 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);
}
});
}
答案 1 :(得分:1)
发生这种情况是因为在此声明中调用onRender
topComponent
事件:
contentPanel.setTopComponent(topContainer);
然后,稍后,您要添加一个组件:topContainer.add(buttonTwo);
。调整窗口大小时,会触发onRender
事件,并显示添加的按钮。问题的解决方案涉及触发onRender
的{{1}}事件。
不幸的是,topContainer
受到保护,因此您无法直接调用它:
http://dev.sencha.com/deploy/gxtdocs/com/extjs/gxt/ui/client/widget/LayoutContainer.html#onRender%28com.google.gwt.user.client.Element,%20int%29
您需要使用onRender
以编程方式触发此操作,而不是手动调整窗口大小:
http://dev.sencha.com/deploy/gxtdocs/com/extjs/gxt/ui/client/widget/Component.html#fireEvent%28com.extjs.gxt.ui.client.event.EventType%29
答案 2 :(得分:0)
一旦浏览器完成呈现窗口小部件,它就不会再次呈现该组件,所以我们可以再次使用它 contentPanel.layout() 要么 contentPanel.layout(真) 它根据新布局重新呈现小部件。