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

Java GXT(Ext GWT):ContentPanel的布局问题,java,gwt,gxt,Java,Gwt,Gxt,我有一个内容面板,适合整个窗口。它有一个topComponent、一个位于中间的小部件和一个bottomComponent 在ContentPanel呈现一次之后,当我尝试将小部件添加到topComponent时,我遇到了布局问题: public void onModuleLoad() { final Viewport viewport = new Viewport(); viewport.setLayout(new FitLayout()); final Conte

我有一个内容面板,适合整个窗口。它有一个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一起使用。)

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

发生这种情况是因为在该语句中调用了
topComponent
onRender
事件:

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

不幸的是,
onRender
受到保护,因此您无法直接调用它:

您需要使用
fireEvent
以编程方式触发此事件,而不是手动调整窗口大小:

之所以会发生这种情况,是因为当您将另一个组件添加到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);
            }
        });
}

不幸的是,
contentPanel.layout()
contentPanel.layout(true)
在我的情况下没有任何作用。“遇到布局问题”是什么意思?@Travis:就像我代码中的注释提到的:起初按钮wo没有出现。然后,当我调用layout()时,它确实出现了。但现在“底部”按钮消失了。只要我手动调整窗口大小(即使只有一个像素),布局就会自动更正,即所有按钮都会显示出来。我如何准确触发事件?我在contentPanel和topContainer上尝试了
fireEvent(Events.Render)
fireEvent(Events.Resize)
。我还在contentPanel.getBottomComponent()上试过。到目前为止不起作用。我的contentPanel中的FitLayout只有一个子项:中心按钮。“顶部组件”和“底部组件”是分开的。那么,您将代码更改为根本不使用“setTopComponent”和“setBottomComponent”——这是可行的,因为它没有使用ContentPanel的topComponent/bottomComponent特性。(我为解决这个问题而实施的临时解决方案与您的类似。)但是,我确实希望使用topComponent/bottomComponent功能,因为它在我正在处理的项目的现有代码中的其他地方都使用过——布局应该可以使用它,在您现有的代码中,您是否动态地将小部件添加到顶部或底部组件?我这样问是因为在呈现contentPanel之后,顶部和底部容器不参与布局。手动调整浏览器窗口的大小时,将调用onResize并调整高度。如果您坚持使用“顶部”和“底部”组件,您可以尝试的一件事是,通过动态获取高度和宽度,在面板上调用“设置大小”方法。@Swapnil:在现有代码中,到目前为止,没有必要向“顶部/底部”组件添加小部件。但是GXT文档没有说,您不能在那里动态添加小部件,所以我们假设这是可行的。现在,通过我们的解决方案(即没有顶部/底部组件),样式有点不同(加上一些其他小问题)。原始样式可以手动模仿,但这不是一个非常干净的解决方案我刚刚尝试了
contentPanel.setSize(contentPanel.getWidth(),contentPanel.getHeight())-不幸的是不起作用。还有其他想法吗?@Chris你可以试着从gwt的Window类中获取高度和宽度。如果坚持使用topComponent和bottomComponent,则中心组件必须收缩,请在向顶部组件添加小部件并收缩中心组件时,尝试计算中心组件的可用高度。基本上在这里,你必须掌握布局。我接受你的答案,我将坚持我们已经实施的解决方案。让顶部/底部组件在可变高度下正常工作似乎比其他任何事情都要复杂。我希望GXT文档已经警告过我们这个限制。谢谢你的帮助!