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

发布于 2024-10-31 04:17:22 字数 1482 浏览 0 评论 0原文

我有一个适合整个窗口的内容面板。它有一个顶部组件、一个位于中心的小部件和一个底部组件。

当我尝试在 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。)

I have a ContentPanel that fits the entire window. It has a topComponent, a widget in the center, and a bottomComponent.

I'm getting layout problems, when I try to add widgets to the topComponent after the ContentPanel has been rendered once:

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.
        }
    });
}

One interesting thing about this is, that the layout corrects itself, as soon as I resize the browser window. What can I do to make it re-layout correctly immediately (I've tried adding several layout() calls etc. in several places and combinations, but haven't had any luck so far.)

(I'm using GWT 2.1.1 with GXT 2.2.1.)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

贩梦商人 2024-11-07 04:17:22

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

另一件事是,您将 FitLayout 用于包含 3 个组件的 contentPanel,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);
            }
        });
}

This is happening because when you add another component to a FlowLayout it resizes, thus increasing its own height, which pushes the bottom component below the visible area. There is nothing in the code which shrinks the center component, such that the bottom component stays in its original place.

One more thing is that you are using FitLayout for contentPanel which contains 3 components, a FitLayout is used for Containers with only one component inside, which is supposed to fill out its parent.

You need to consider the following:

1) Use RowLayout, which allows a much better control on how components should be laid out

2) Decide on which component are you willing to place a vertical scroll bar, since you are adding components dynamically.

For your current requirement the following code should suffice:

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);
            }
        });
}
っ〆星空下的拥抱 2024-11-07 04:17:22

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

contentPanel.setTopComponent(topContainer);

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

不幸的是,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

This is happening because the onRender event of topComponent is being invoked in this statement:

contentPanel.setTopComponent(topContainer);

Then, later, you are adding a component: topContainer.add(buttonTwo);. When you resize the window, the onRender event is triggered, and the button you added shows up. The solution to your problem involves triggering the onRender event for topContainer.

Unfortunately, onRender is protected and therefore you cannot call it directly:
http://dev.sencha.com/deploy/gxtdocs/com/extjs/gxt/ui/client/widget/LayoutContainer.html#onRender%28com.google.gwt.user.client.Element,%20int%29

You will want to use fireEvent to trigger this programmatically instead of manually resizing the window:
http://dev.sencha.com/deploy/gxtdocs/com/extjs/gxt/ui/client/widget/Component.html#fireEvent%28com.extjs.gxt.ui.client.event.EventType%29

婴鹅 2024-11-07 04:17:22

一旦浏览器完成渲染小部件,它就不会再次渲染该组件,因此我们可以使用
内容面板.layout()
或者
内容面板.layout(true)
它根据新布局重新呈现小部件。

once browser completes rendering the widget it won't render that component again so to do it again we can use
contentPanel.layout()
or
contentPanel.layout(true)
it re-renders the widgets as per new layout.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文