如果在界面上有一个大文本框,一般我们会指定它的GridData为GridData.FILL_BOTH,这样在窗口改变大小时它的大小会随着变化。但在同一个GridLayout里,如果有多个这样的文本框,一定要注意它们的GridData中的grabExcessHorizontalSpace属性,该属性指出当一行中所有单元格的大小(宽/高)还不足以填充父控件时,是否增大其尺寸。
举一个具体的例子,有两行控件,父控件的Layout定义为new GridLayout(4,false),既有四列。第一行控件依次为Label0、Text1和Button2,其中Text3占2列;第二行为Text2,独占4列,我们希望第一行中的按钮右端和第二行中的文本框右端对齐,两个文本框都随窗口变宽而变宽,代码如下:
import org.eclipse.swt.*; import org.eclipse.swt.custom.*; import org.eclipse.swt.graphics.*; import org.eclipse.swt.layout.*; import org.eclipse.swt.widgets.*; public class MyLayout { public static void main (String [] args) { Display display = new Display (); Shell shell = new Shell (display); GridLayout gridLayout = new GridLayout (); gridLayout.numColumns = 4; shell.setLayout (gridLayout); Label label0 = new Label (shell, SWT.NONE); label0.setText ("label0"); Text text1 = new Text (shell, SWT.BORDER); text1.setText ("text1"); GridData data = new GridData (); data.horizontalAlignment = GridData.FILL; data.horizontalSpan = 2; data.grabExcessHorizontalSpace = true; text1.setLayoutData (data); Button button2 = new Button (shell, SWT.PUSH); button2.setText ("button2"); Text text3 = new Text (shell, SWT.BORDER); text3.setText ("text3"); data = new GridData (); data.horizontalAlignment = GridData.FILL; data.verticalAlignment = GridData.FILL; data.horizontalSpan = 4; data.grabExcessHorizontalSpace = true; //Wrong! text3.setLayoutData (data); shell.pack (); shell.open (); while (!shell.isDisposed ()) { if (!display.readAndDispatch ()) display.sleep (); } display.dispose (); } }
因为想到两个文本框的宽度要变大,所以指定它们的GridData的grabExcessHorizontalSpace属性为true,而运行结果却与我们想的有差别。原因是下面的文本框实际上在宽度上占据了第一行中最靠两边的两个单元格,使得第一行中间的两个单元格宽度变小。为了解决这个问题,只要把定义第二个文本框Text3的grabExcessHorizontalSpace的语句去掉即可(缺省值为false)。
还需要注意,有时候为了简单起见,我们常使用GridData data=new GridData(GridData.FILL_BOTH)来定义GridData,这个FILL_BOTH上包含了FILL_HORIZONTAL和FILL_VERTICAL,而它们各自又包含了HORIZONTAL_ALIGN_FILL、GRAB_HORIZONTAL以及VERTICAL_ALIGN_FILL、GRAB_VERTICAL。所以,如果你是用构造方法定义的GridData,并且又希望不要grabExcessHorizontalSpace,则应该手动指定它为false才行。