在SWT应用程序中,我有一个包含两列的GridLayout
的复合词。第一个包含标签,第二个包含标签和复选框。我对其中一些使用TextLayout
s并手动绘制它们(在绘图侦听器中),因此我必须手动计算它们的大小。我使用setSize()
设置小部件的计算大小,并在各自的widthHint
中设置heightHint
和GridData
。标签的GridData
个对象(网格的第一列)使用(SWT.RIGHT, SWT.CENTER, false, false)
创建,第二列中的小部件使用(SWT.FILL, SWT.CENTER, true, false)
创建。小部件的computeSize()
返回我期望的大小(例如,第一列的宽度不超过68像素,第二列的宽度不超过128像素)。
但是computeSize()
的{{1}}返回的宽度远远大于我期望看到的(或想要的),即253,而我期望68 + 128 + 3 * 4 + 2 * 2 = 212或接近它的东西。
因此,Composite
上的pack()
会使其变得比我想要的更广泛。我可以使用Composite
强制Composite
所需的宽度,但是包含我的复合的shell上的后续操作无论如何都会调用复合的setSize()
,因此它的宽度会被破坏。复合pack()
widthHint
的设置也不会奏效。
GridData
本身是具有Composite
的上级Composite
的孩子,GridLayout
GridData
。
为什么(SWT.LEFT, SWT.FILL, false, true)
决定computeSize()
的宽度应为253,如果列中小部件的宽度计算为68和128像素宽且Composite
相应地设定?它是如何工作的?除了儿童小部件的计算大小之外,它还考虑了什么?我在哪里可以找到其算法的描述(实际计算大小的widthHints
GridLayout
的来源,相当复杂且难以理解)?
如何在更改父layout (Composite composite, boolean move, int x, int y, int width, int height, boolean flushCache)
的布局时让布局管理器保持Composite
的所需宽度,包括Composite
(调整大小,更改字体等)?
答案 0 :(得分:1)
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,无论控件如何说明其首选大小。