我们已经查看了简单的示例说明如何根据父代小窗口来确定子代小窗口的大小和位置。到目前为止,已响应调整大小侦听器进行了计算。这通常是处理简单小窗口定位的最佳方法。然而,当放置小窗口时,应用程序使用公共模式。这些模式可以构造为可配置的布局算法, 许多不同的应用程序都可以重复使用该算法。
SWT 定义了布局,它提供组合体中子代小窗口的通用定位和缩放。布局是抽象类布局的子类。可以在 org.eclipse.swt.layout 包中找到 SWT 标准布局。
当对小窗口重新调整大小和定位时,应了解一些一般定义。
这些概念与应用程序有关,不管是否使用了布局。可以认为布局是封装调整大小功能以便重复使用的便捷方法。
布局还引入了一些附加概念。
有关用来演示这些概念的进一步讨论和图片, 参见了解 SWT 中的布局。
以下代码片段说明了一种简单情况,应用程序使用调整大小回调来将标号的大小调整为它的父代外壳程序的大小。
Display display = new Display ();
Shell shell = new Shell (display);
Label label = new Label (shell, SWT.CENTER);
shell.addControlListener(new ControlAdapter() {
public void controlResized(ControlEvent e) {
label.setBounds (shell.getClientArea ());
}
});
以下代码片段使用布局来获得相同的效果:
Display display = new Display ();
Shell shell = new Shell (display);
Label label = new Label (shell, SWT.CENTER);
shell.setLayout(new FillLayout());
即使对于此简单示例,使用布局也减少了应用程序代码。对于更复杂的布局,简化更大。
SWT 提供了可以用于许多情况的三个缺省布局类。
FillLayout 是最简单的布局类。它将小窗口布局在单行或单列中,强制它们使用相同的大小。最初,所有小窗口都将与最高的小窗口一样高,并且与最宽的小窗口一样宽。FillLayout 不会覆盖,并且您不能指定页边距和间距。
可以使用 FillLayout 来对任务栏或工具栏中的按钮进行布局, 或者将复选框叠放在组中。 当组合体只具有一个子代时, 还可以使用 FillLayout。在以上示例中,FillLayout 导致标号完全填充它的父代外壳程序。
RowLayout 也在行中来布局小窗口, 但是它比 FillLayout 更灵活。它可以覆盖小窗口,根据需要创建足够多的行来显示它们。它还提供布局的每个边缘上可配置的页边距,以及布局中的小窗口之间可配置的间距。可以包装 RowLayout, 它强制所有小窗口使用相同大小。如果您调整 RowLayout, 则组合体中保留的额外空间将被分配为小窗口之间的页边距。
可以在 RowData 对象(应该在小窗口中使用 setLayoutData 来设置它)中指定 RowLayout 中的每个小窗口的高度和宽度。
GridLayout 是功能最强大(也最复杂)的布局。 GridLayout 在网格中布局小窗口, 就会有许多可配置的参数,当调整组合体的大小时,用来控制网格行和列的行为。
GridLayout 定义用来控制布局的总体策略的 API。最重要的属性为 numColumns,它确定网格的水平大小。通常,当您首次设计窗口的外观时,就要决定此值。网格中的小窗口的次序与您创建它们的次序相同。要更改网格中的小窗口的次序,可以使用控件方法 moveAbove(Control) 和 moveBelow(Control)。这些方法允许小窗口在布局中互相之间前后插入。(“上面”和“下面”是指小窗口 Z 坐标次序,而不是网格本身的位置。)
下表总结了 GridLayout 的可配置参数。
属性 |
描述 |
---|---|
horizontalSpacing |
一个单元格的右边缘与它的相邻单元格的左边缘之间的像素数目。 |
makeColumnsEqualWidth |
指定是否应该强制所有列为相同宽度。 |
marginWidth |
用于网格的右边缘和左边缘上的页边距的像素数目。 |
marginHeight |
用于网格顶部和底部边缘上的页边距的像素数目。 |
numColumns |
应该用来生成网格的列数。 |
verticalSpacing |
一个单元格的底部边缘与它的相邻单元格的顶部边缘之间的像素数目。 |
GridLayout 支持网格中的每个小窗口的许多其他布局参数。这些特性是在 GridData 对象中指定的。必须将 GridData 设置为网格中的每个小窗口的 layoutData。
GridData 类定义样式常量, 它允许您在 GridData 构造器中指定布局参数的常用组合。还可以使用 GridData 中的公用方法来单独设置这些属性。
通过使用 GridData 可以获得一些高动态和复杂的布局。将不同小窗口的这些值组合在网格中可以生成布局的许多不同的组合。即使最复杂的对话框布局也可以使用 GridData 来指定。允许小窗口跨越单元格的能力产生许多甚至不象网格的布局。
下表总结了 GridData 的可配置参数。 有关进一步的描述和使用各种网格参数的示例屏幕捕获, 参见了解 SWT 中的布局。
属性 |
描述 |
---|---|
grabExcessHorizontalSpace |
指定单元格是否应该增大,以便使用网格中可用的任何额外水平空间。在根据小窗口和它们的网格数据计算网格中的单元格大小之后, 将把“组合体”中余下的任何额外空间分配给夺取额外空间的那些单元格。 |
grabExcessVerticalSpace |
指定单元格是否应该增大,以便使用网格中可用的任何额外的垂直空间。 |
heightHint |
指定小窗口的最低高度(以及包含小窗口的行的最低高度)。 |
horizontalAlignment |
可以是 BEGINNING、CENTER、END 和 FILL 的其中之一。FILL 意味着将调整小窗口的大小,以便占据它的网格单元格的整个宽度。 |
horizontalIndent |
小窗口与它的网格单元格的左边缘之间的像素数目。 |
horizontalSpan |
指定小窗口应该跨越的网格中的列数。缺省情况下,小窗口占据网格中的一个单元格。它可以通过增大此值来水平获取其他单元格。 |
verticalAlignment |
可以是 BEGINNING、CENTER、END 和 FILL 的其中之一。FILL 意味着将调整小窗口的大小,以便占据它的网格单元格的整个高度。 |
verticalSpan |
指定小窗口应该跨越的网格中的行数。缺省情况下,小窗口占据网格中的一个单元格。它可以通过增大此值来垂直获取其他单元格。 |
widthHint |
指定小窗口的最小宽度(以及包含小窗口的列的最小宽度)。 |
有时,可能需要编写您自己的定制布局类。当您具有用于应用程序中的许多不同位置的复杂布局时,这样作最合适。当您可以使用特定于应用程序的知识来优化布局时也是合适的。在构建定制布局之前,考虑下列事项:
除非您正在编写将供一些 组合体小窗口使用的很普通的布局, 否则,计算大小和定位调整大小侦听器中的子代通常更简单且更容易。许多 SWT 定制小窗口都是以此方式编写的。尽管新的小窗口可以作为组合体/布局对来实现, 但是,作为组合体来实现它将更为明了, 该组合体在调整大小侦听器中实现它的布局, 而在 computeSize 中计算它的首选大小,并且不会涉及到编写额外的类。
如果您仍然认为需要定制布局类,则最好是首先在调整大小侦听器中实现布局算法。这使得算法本身的调试更简单。一定要测试布局的各种情况:将大小调整得更小、更大、覆盖和剪辑。一旦算法生效,就可以将代码重分解因子成布局的子类。
布局负责实现两种方法:
可以在了解 SWT 中的布局中找到关于定制布局的进一步讨论。