【问题标题】:ScrolledComposite parent with GridLayout具有 GridLayout 的 ScrolledComposite 父级
【发布时间】:2017-09-14 17:01:01
【问题描述】:

我想要一个ScrolledComposite,它的父级为GridLayout,但滚动条不显示,除非我使用FillLayout。我对FillLayout 的问题是它的孩子占据了可用空间的相等部分。

在我的情况下,有两个小部件,顶部的一个不应超过窗口的 1/4,ScrolledComposite 应占据剩余空间。但是,他们都占了一半。

有没有办法将GridLayoutScrolledComposite 一起使用,或者是否可以修改FillLayout 的行为?

这是我的代码:

private void initContent() {

    //GridLayout shellLayout = new GridLayout();
    //shellLayout.numColumns = 1;
    //shellLayout.verticalSpacing = 10;
    //shell.setLayout(shellLayout);
    shell.setLayout(new FillLayout(SWT.VERTICAL));

    searchComposite = new SearchComposite(shell, SWT.NONE);
    searchComposite.getSearchButton().addListener(SWT.Selection, this);

    ScrolledComposite scroll = new ScrolledComposite(shell, SWT.V_SCROLL | SWT.H_SCROLL | SWT.BORDER);
    scroll.setLayout(new GridLayout(1, true));

    Composite scrollContent = new Composite(scroll, SWT.NONE);
    scrollContent.setLayout(new GridLayout(1, true));

    for (ChangeDescription description : getChanges(false)) {
        ChangesComposite cc = new ChangesComposite(scrollContent, description);
    }

    scroll.setMinSize(scrollContent.computeSize(SWT.DEFAULT, SWT.DEFAULT));
    scroll.setContent(scrollContent);
    scroll.setExpandVertical(true);
    scroll.setExpandHorizontal(true);
    scroll.setAlwaysShowScrollBars(true);

}

【问题讨论】:

  • 我也遇到了同样的问题,你找到解决办法了吗?
  • Steve K 的回答应该被接受:它工作正常。

标签: java swt scrolledcomposite


【解决方案1】:

除了setLayout(),还需要调用setLayoutData()。在下面的代码示例中,看看GridData 对象是如何构造并传递给两个 setLayoutData() 调用的。

private void initContent(Shell shell)
{
    // Configure shell
    shell.setLayout(new GridLayout());

    // Configure standard composite
    Composite standardComposite = new Composite(shell, SWT.NONE);
    standardComposite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));

    // Configure scrolled composite
    ScrolledComposite scrolledComposite = new ScrolledComposite(shell, SWT.V_SCROLL | SWT.H_SCROLL | SWT.BORDER);
    scrolledComposite.setLayout(new GridLayout());
    scrolledComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
    scrolledComposite.setExpandVertical(true);
    scrolledComposite.setExpandHorizontal(true);
    scrolledComposite.setAlwaysShowScrollBars(true);

    // Add content to scrolled composite
    Composite scrolledContent = new Composite(scrolledComposite, SWT.NONE);
    scrolledContent.setLayout(new GridLayout());
    scrolledComposite.setContent(scrolledContent);
}

【讨论】:

  • 调用scrolledComposite.setLayout(...) 什么都不做。 ScrolledComposite 覆盖该方法并且不设置布局,因为默认情况下它已经有一个 ScrolledCompositeLayout。所以不知道.setLayoutData 调用它的孩子会发生什么。
【解决方案2】:

注意!此答案基于 Eclipse RAP,其行为可能与常规 SWT 不同。

几天前,我正在为完全相同的问题苦苦挣扎。我在同一页面上有两个ScrolledComposites,我需要左边的不会占用比需要更多的空间(即使空间可用)。

在尝试不同的解决方案时,我注意到ScrolledComposite 的行为取决于它的LayoutData,如下所示:

  • 如果layoutData 设置为new GridData(SWT.LEFT, SWT.TOP, false, true),则ScrolledComposite 将保持其预期大小,而不管父Composite 大小发生变化。
  • 如果layoutData 设置为new GridData(SWT.LEFT, SWT.TOP, true, true),那么ScrolledComposite 将根据父Composite 的大小变化进行收缩/扩展。这还包括扩展到所需的更大宽度(意味着列保持相等)。

基于这种行为,我能够通过向父 Composite 添加一个调整大小侦听器来解决问题,该侦听器根据父 Composite size 更改左侧 ScrolledCompositelayoutData

下面的例子说明了这种方法:

public class LayoutingScrolledComposites extends AbstractEntryPoint {
    public void createContents( Composite parent ) {    
        parent.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
        parent.setLayout(new GridLayout(2, false));

        ScrolledComposite sc1 = new ScrolledComposite(parent, SWT.H_SCROLL | SWT.V_SCROLL);
        Composite c1 = new Composite(sc1, SWT.BORDER);
        sc1.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, true, true));
        c1.setLayout(new GridLayout(3, false));
        sc1.setContent(c1);
        Label l1 = new Label (c1, SWT.BORDER);
        l1.setText("Some text");
        l1 = new Label (c1, SWT.BORDER);
        l1.setText("Some text");
        l1 = new Label (c1, SWT.BORDER);
        l1.setText("Some text");
        c1.setSize(c1.computeSize(SWT.DEFAULT, SWT.DEFAULT));

        ScrolledComposite sc2 = new ScrolledComposite(parent, SWT.H_SCROLL | SWT.V_SCROLL);
        sc2.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, true, true));
        Composite c2 = new Composite(sc1, SWT.BORDER);
        c2.setLayout(new GridLayout(3, false));
        sc2.setContent(c2);
        Label l2 = new Label (c2, SWT.BORDER);
        l2.setText("Some text");
        l2 = new Label (c2, SWT.BORDER);
        l2.setText("Some text");
        l2 = new Label (c2, SWT.BORDER);
        l2.setText("Some text");
        c2.setSize(c2.computeSize(SWT.DEFAULT, SWT.DEFAULT));

        parent.addListener(SWT.Resize, new Listener() {
            public void handleEvent(Event e) {
                int sc1_x = sc1.getContent().getSize().x;
                int sc2_x = sc2.getContent().getSize().x;

                //Enable/Disable grabExcessHorizontalSpace based on whether both sc's would fit in the shell
                if (LayoutingScrolledComposites.this.getShell().getSize().x > sc1_x+sc2_x) {
                    if (((GridData)sc1.getLayoutData()).grabExcessHorizontalSpace) {
                        //sc1 does not change width in this mode
                        ((GridData)sc1.getLayoutData()).grabExcessHorizontalSpace=false;                        
                    }
                } else {
                    if (!((GridData)sc1.getLayoutData()).grabExcessHorizontalSpace) {
                        //sc1 changes width in this mode
                        ((GridData)sc1.getLayoutData()).grabExcessHorizontalSpace=true;                     
                    }
                }
                parent.layout(); //Needed so that the layout change would take effect during the same event
            }
        });
    }
}

但是,在我看来,这种方法确实有点过于“骇人听闻”的解决方案。因此,我希望看到更好的方法。

【讨论】:

    【解决方案3】:

    我认为您在这里缺少的是为孩子定义GridData

    布局控制子元素的位置和大小。每个布局类都有一个相应的布局数据类,允许配置布局中的每个特定子级,如果它们填满整个空间,它们占用多少个单元格等。

    我猜你的网格布局可能有 4 行,顶部的小部件只占用一个单元格,而另一个孩子占用其余的单元格 (3)。这是通过GridData.verticalSpan 属性实现的。

    查看Understanding Layouts in SWT 并尝试不同的布局数据属性以了解它们的作用。

    【讨论】:

    • 对不起,我想我不够清楚。主要问题是,如果我将 ScrolledComposite 放在 GridLayout 中,它不会显示其滚动条,它仅适用于 FillLayout - 但它不符合我的需要。我将编辑原始帖子以明确这一点。
    • FillLayout 强制控件大小相同。最初,控件将与最高控件一样高,与最宽控件一样宽。似乎这种布局会导致您的控件足够大,以便 ScrolledComposite 显示滚动条。但是,当您拥有GridLayout 时,您必须通过GridData 对象指定控件在每个单元格中的布局方式。这决定了它们的大小。如果你不这样做,可能内容不够大。只是猜测 O:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-12-04
    • 2017-05-05
    • 1970-01-01
    • 2010-12-26
    • 1970-01-01
    • 2018-01-11
    • 2011-05-18
    相关资源
    最近更新 更多