在SWT应用程序中,我有一个具有两列的GridLayout
的组合。第一个包含标签,第二个包含文本和复选框。我对其中一些使用TextLayout
,并手动绘制它们(在绘制侦听器中),因此我必须手动计算它们的大小。我用setSize()
设置小部件的计算大小,并在各自的GridData
s中设置widthHint
和heightHint
。标签(网格的第一列)的GridData
对象使用(SWT.RIGHT, SWT.CENTER, false, false)
创建,第二列的小部件使用(SWT.FILL, SWT.CENTER, true, false)
创建。小部件的computeSize()
返回我期望的大小(例如。第一列宽度不超过68像素,第二列宽度不超过128像素)。
但是Composite
的computeSize()
返回的宽度比我期望看到的(或想要的)大得多,即253,而我期望68 + 128 + 3 * 4 + 2 * 2 = 212或接近它的东西。因此,Composite
上的pack()
使它比我想要的宽得多。我可以用setSize()
强制Composite
的所需宽度,但是包含我的组合的shell上的后续操作无论如何都会调用组合的pack()
,因此它的宽度被破坏了。设置合成的GridData
的widthHint
也不能工作。
Composite
本身是上层Composite
和GridLayout
的子节点,GridData
和(SWT.LEFT, SWT.FILL, false, true)
的子节点。
为什么computeSize()
决定Composite
的宽度应该是253,如果列中的小部件的宽度被计算为68和128像素宽,并且它们的widthHints
被相应地设置?它是如何工作的?除了计算子部件的大小之外,它还考虑了什么?我在哪里可以找到它的算法描述(GridLayout
的layout (Composite composite, boolean move, int x, int y, int width, int height, boolean flushCache)
的源代码,实际计算大小,相当复杂和难以理解)?
我如何使布局管理器保持Composite
所需的宽度,同时改变父Composite
s的布局,包括Shell
(调整大小,字体变化等)?
GridLayout
充满惊喜。如果您没有教条地坚持它,我建议您切换到FormLayout
。这更强大,让你对UI的最终结果有更多的控制。与GridLayout
相比,这是一种范式转变,但非常值得学习。
对于FormLayout
,您可以使用父元素的尺寸,或者任何兄弟元素的位置和尺寸(即Controls
)。Controls
共享父控件)用于定位和大小控制。这就像为每个控件声明了几个布局约束,管理器将尽其所能满足你的愿望。
这是一个入门教程。它向您介绍了FormData
,它声明了四个锚点(上、下、右、左),FormAttachments
定义了FormData
对象中的约束。
对于您的问题,您可以使用eg布局第一列。父元素宽度的40%,每一行都位于前一行的标签下方。第二列的控件相对于它们的标签(在它们的左侧)和前一行的标签或控件(在它们的顶部)放置。
现在似乎困扰您的是第二列中一些控件的宽度。在FormLayout
中,您可以通过将其声明为eg来为正确的锚设置显式约束。在父元素的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,从第一列的右侧开始,无论控件的首选大小如何