在SWT应用程序中,我有一个带有两个列的GridLayout组合。第一个包含标签,第二个包含文本和复选框。我对其中一些使用TextLayout并手动绘制它们(在绘制侦听器中),因此我必须手动计算它们的大小。我用setSize()设置了小部件的计算大小,并在它们各自的widthHint中设置了heightHintGridData。使用GridData创建标签的(SWT.RIGHT, SWT.CENTER, false, false)对象(网格的第一列),使用(SWT.FILL, SWT.CENTER, true, false)创建第二列的小部件。小部件的computeSize()返回我期望的大小(例如,第一列的宽度不超过68像素,第二列的宽度不超过128像素)。

但是computeSize()Composite返回的宽度比我期望看到的(或想要的)大得多,即253,而我期望68 + 128 + 3 * 4 + 2 * 2 = 212或接近于它。
因此,pack()上的Composite使其变得比我想要的宽得多。我可以用Composite强制使用setSize()的所需宽度,但是在包含我的复合材料的外壳上进行的后续操作无论如何都会调用复合材料的pack(),因此其宽度会受到破坏。组合的widthHintGridData设置也不起作用。

Composite本身是具有Composite的上级GridLayout的子级,具有具有GridData(SWT.LEFT, SWT.FILL, false, true)

如果计算列中的窗口小部件的宽度分别为68和128像素,并相应地设置其computeSize(),为什么Composite决定widthHints的宽度应为253?它是如何工作的?除了计算出的子窗口小部件大小以外,还需要考虑什么?我在哪里可以找到其算法的说明(实际上计算大小的GridLayoutlayout (Composite composite, boolean move, int x, int y, int width, int height, boolean flushCache)的来源相当复杂且难以理解)?

如何在更改父Composite的布局(包括Composite)(调整大小,更改字体等)时,使布局管理器保持所需的Shell宽度?

最佳答案

GridLayout充满惊喜。如果您不拘泥于此,建议您切换到FormLayout。这功能更强大,并且可以让您更好地控制UI的最终结果。与GridLayout相比,这是一个范式转换,但是非常值得学习。

使用FormLayout,您可以使用父级的尺寸或任何同级Controls(即Controls共享父级)的位置和尺寸来定位和调整控件大小。这就像为每个控件声明几个布局约束一样,管理器将尽最大努力满足您的需求。

这是您开始的tutorial。它向您介绍FormData,它声明四个锚点(上,下,右,左)和FormAttachments,它们定义了FormData对象中的约束。

对于您的问题,可以使用例如来布局第一列。父级宽度的40%,每行放置在上一行标签的下方。第二列的控件相对于其标签(在左侧)和上一行的标签或控件(在其顶部)放置。

现在,似乎困扰您的是第二列中某些控件的宽度。在FormLayout中,可以通过将其声明为例如来为右锚设置显式约束。以父级的100%宽度(从第一列的40%右锚开始),然后将依赖于父级父级的布局,或者通过将右锚设置为从像素的右边缘算起的绝对边距(以像素为单位)第一列。可以通过引用第一列中的标签来完成,但是要切换对齐方式。这是必要的,因为默认情况下,从Control A的右锚到同级B的关系将自动使用B的左侧。在代码中,这种第二种可能性将像这样阐明:

FormData fd;
//row 1
Label lblC1R1;
Control ctrlC2R1;
//row 2
Label lblC1R2;
Control ctrlC2R2;

...

fd = new FormData(); //for ctrlC2R2;
fd.top = new FormAttachment(lblC1R1);  //top edge clings to (y-coord of) bottom of row 1 label (could reference row 1 control, too)
fd.left = new FormAttachment(lblC1R2); //left edge clings to right side of row 2 label
fd.right = new FormAttachment(lblC1R2, 200, SWT.RIGHT); //right edge is defined as a distance of +200 px from *right* side of row 2 label (by default, it would use the left side)
//we don't set fd.bottom, so the control may grow or shrink with ie. font size

ctrlC2R2.setLayoutData(fd);


这将从第一列的右侧开始将第二列控件的宽度固定为200px,无论控件说出其首选大小如何。

关于java - GridLayout如何计算合成大小,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/31919113/

10-10 09:04