Java 网格布局-共享相对空间

Java 网格布局-共享相对空间,java,layout,swt,Java,Layout,Swt,是否可以为网格布局中所有占用多余水平空间的列定义手动比率? 当使用带有抓取过多水平空间选项的多个项目的网格布局时,尤其是表格、树等,布局会根据各种因素自动确定如何分割多个项目之间的空间,例如每个项目有多少列。这导致空间在它们之间被不均匀地分割,这是设计的意图,通常是一件好事 如果希望空间完全均匀地分割,也可以使用“使列大小相同”选项 但是,是否可以为列定义一个不同的、非自动的、非相等的空间百分比?例如,是否可以将我示例中的项目划分为80/20,将较大的部分分配给列数较少的项目,或者,通过自动

是否可以为网格布局中所有占用多余水平空间的列定义手动比率?

当使用带有抓取过多水平空间选项的多个项目的网格布局时,尤其是表格等,布局会根据各种因素自动确定如何分割多个项目之间的空间,例如每个项目有多少列。这导致空间在它们之间被不均匀地分割,这是设计的意图,通常是一件好事

如果希望空间完全均匀地分割,也可以使用“使列大小相同”选项


但是,是否可以为列定义一个不同的、非自动的、非相等的空间百分比?例如,是否可以将我示例中的项目划分为80/20,将较大的部分分配给列数较少的项目,或者,通过自动方法,哪个会被认为更小?

是的,您可以这样通过编程实现:

  • 获取屏幕的大小

  • 根据屏幕编辑
    GridView
    的大小(例如,将大小设置为50%屏幕的1/2)

  • 通过调用
    view.invalidate()

  • 与答案非常相关:

    是的,这是可能的,但不像
    GridLayout\setWeight(col,weight)
    那么简单。不幸的是,您必须先收听
    Shell
    (或容纳
    GridLayout
    的容器)的
    Resize
    事件,然后设置所包含组件的
    GridData
    。下面的代码将百分比设置为75%和25%:

    public static void main(String[] args)
    {
        Display display = Display.getDefault();
        final Shell shell = new Shell(display);
        shell.setLayout(new GridLayout(2, false));
    
        Composite left = new Composite(shell, SWT.BORDER);
        Composite right = new Composite(shell, SWT.BORDER);
    
        final GridData leftData = new GridData(SWT.FILL, SWT.FILL, true, true);
        final GridData rightData = new GridData(SWT.FILL, SWT.FILL, true, true);
    
        left.setLayoutData(leftData);
        right.setLayoutData(rightData);
    
        shell.addListener(SWT.Resize, new Listener()
        {
            @Override
            public void handleEvent(Event arg0)
            {
                Point size = shell.getSize();
    
                leftData.widthHint = (int) (size.x * 0.75);
                rightData.widthHint = size.x - leftData.widthHint;
    
                System.out.println(leftData.widthHint + " + " + rightData.widthHint + " = " + size.x);
            }
        });
    
        shell.pack();
        shell.open();
        shell.layout();
    
        while (!shell.isDisposed())
        {
            if (!display.readAndDispatch())
                display.sleep();
        }
        display.dispose();
    }
    
    启动后:

    调整大小后:


    您也可以使用列数较多的GridLayout,通过让内容跨越多个列,您可以根据需要分配空间,而不必听resize

    例如,对于70:30的分布,创建10列栅格布局。让第一个子节点跨越7列,第二个子节点跨越3列

    根据您的使用情况,使用GridLayout的一个缺点可能是,如果子项想要变大,它不会强制子项减小到父项的大小(我经常遇到这样一个问题,即长标签可能只是换行)

    避免此问题的一个选项是实现一个支持百分比的简单布局管理器:

    public class ColumnLayout extends Layout {
    
      int[] percentages;
      public ColumnLayout(int... percentages) {
        this.percentages = percentages;
      }
    
      @Override
      protected Point computeSize(Composite composite, int wHint, int hHint, boolean flushCache) {
        Control[] children = composite.getChildren();
        int height = hHint;
        int width = wHint;
        int consumedPercent = 0;
        for (int i = 0; i < children.length; i++) {
          int percent;
          if (i >= percentages.length) {
            percent = (100 - consumedPercent) / (children.length - percentages.length);
          } else {
            percent = percentages[i];
            consumedPercent += percent;
          }
          Point childSize = children[i].computeSize(wHint == -1 ? -1 : wHint * percent / 100, hHint);
          if (wHint == -1) {
            width = Math.max(width, childSize.x * (100 - percent) / 100);
          }
          if (hHint == -1) {
            height = Math.max(height, childSize.y);
          }
        }
        return new Point(width, Math.max(height, 0));
      }
    
      @Override
      protected void layout(Composite composite, boolean flushCache) {
        Control[] children = composite.getChildren();
        Rectangle available = composite.getClientArea();
        int x = available.x;
        int consumedPercent = 0;
        for (int i = 0; i < children.length - 1; i++) {
          int percent;
          if (i >= percentages.length) {
            percent = (100 - consumedPercent) / (children.length - percentages.length);
          } else {
            percent = percentages[i];
            consumedPercent += percent;
          }
          int w = available.width * percent / 100;
          children[i].setBounds(x, available.y, w, available.height);
          x += w;
        }
        if (children.length > 0) {
            children[children.length - 1].setBounds(x, available.y,
                    available.width - (x - available.x), available.height);
        }
      }
    }
    
    公共类ColumnLayout扩展了布局{
    int[]百分比;
    公共列布局(整数…百分比){
    这个。百分比=百分比;
    }
    @凌驾
    受保护点计算(复合复合、int-wHint、int-hHint、布尔flushCache){
    Control[]children=composite.getChildren();
    int高度=hHint;
    int宽度=呜呜声;
    int consumedPercent=0;
    for(int i=0;i=百分比长度){
    百分比=(100-消费百分比)/(children.length-percenters.length);
    }否则{
    百分比=百分比[i];
    消费百分比+=百分比;
    }
    点childSize=children[i]。计算(wHint==-1?-1:wHint*百分比/100,hHint);
    如果(呜呜声==-1){
    宽度=数学最大值(宽度,childSize.x*(100%)/100);
    }
    如果(hHint==-1){
    高度=数学最大值(高度,儿童尺寸y);
    }
    }
    返回新点(宽度,数学最大值(高度,0));
    }
    @凌驾
    受保护的空心布局(复合、布尔flushCache){
    Control[]children=composite.getChildren();
    可用矩形=composite.getClientArea();
    int x=可用的.x;
    int consumedPercent=0;
    for(int i=0;i=百分比长度){
    百分比=(100-消费百分比)/(children.length-percenters.length);
    }否则{
    百分比=百分比[i];
    消费百分比+=百分比;
    }
    int w=可用宽度*百分比/100;
    儿童[i].立根(x,可用.y,w,可用.height);
    x+=w;
    }
    如果(children.length>0){
    children[children.length-1].setBounds(x,可用.y,
    可用宽度-(x-可用.x),可用高度);
    }
    }
    }
    

    这就是说,我现在通常只是把我想包装的标签放在一个额外的“笼子”组合中,以限制它们的水平尺寸要求

    对答案有什么反馈吗?@Baz还没有,还没有时间测试。很快。不过,我对你完全有信心,Baz=)公平地说,慢慢来。我只是想检查一下我给出的答案,看看它们是否有效。@Baz很好用。有趣的是,我学到了在尝试此操作之前确保关闭“使列大小相同”选项的困难方法-这会导致一个滑稽的错误,其中列大小不同,但左侧的列总是较大的列。