布局是SWT中很重要的一个部分。毕竟人家SWT主要做的是UI,什么东西放在什么地方就是他们的主要工作。所以我主要看了一下布局相关的东西,并和大家一起分享一下。
Layout包中主要提供了连带上面我们所讲过的FillLayout方式总共4种方式的布局类型。分别为:
l FillLayout(充满式布局,通常都对只有一、两个对象时使用,上面已经介绍过)
l RowLayout(简单排列式布局,由于功能太弱可以完全被GridLayout取代。我一会简单介绍一下)
l GridLayout(网格式布局,是我们常用的一种布局。它相当于将一个屏幕看成是一个大的表格,然后对其进行具体的分配)
l StackLayout(堆栈式布局,通常用于几个重叠对象的交替显示)
RowLayout类是简单布局类,下面给出一个例子:
package swt.examples;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.DeviceData;
import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
public class RowLayOut {
public static void main(String [] args) {
Display display = new Display(new DeviceData());
System.out.println(display.getBounds().width);
Shell shell = new Shell(display);
shell.setSize(200,150);
RowLayout rowLayout = new RowLayout(); //创建一个RowLayout对象。默认是
//横向排,加一个参数//SWT.VERTICAL则是竖向排
rowLayout.marginTop = 10; //设置离上面的高度。
rowLayout.marginLeft = 20; //设置离左边的高度
shell.setLayout(rowLayout);
Button btn1 = new Button(shell,SWT.NONE);
Button btn2 = new Button(shell,SWT.NONE);
Button btn3 = new Button(shell,SWT.NONE);
btn1.setText("btn1");
btn2.setText("btn2");
btn3.setText("btn3");
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch())
display.sleep();
}
display.dispose();
}
}
具体效果如左下图:
右边图是当参数为SWT.VERTICAL时的情况。
GridLayout常被称为表格布局。它主要有GridLayout对象类与GridData两个部分共同组合构成。其中GridLayout类主要负责对整体布局效果的设定,numColumns负责对每行总格数的设定,verticalSpacing、horizontalSpacing分别负责对水平与垂直间距的设定,makeColumnsEqualWidth代表水平平分。下面我们也用一个简单的例子来说明它的具体用法。
package swt.examples;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.DeviceData;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
public class GridLayOut {
public static void main(String [] args) {
Display display = new Display(new DeviceData());
System.out.println(display.getBounds().width);
Shell shell = new Shell(display);
shell.setSize(200,150);
GridLayout gridLayout = new GridLayout(); //定义一个GridLayout对象
gridLayout.numColumns = 6; //设定GridLayout对象的列数
shell.setLayout(gridLayout); //设定shell的排列方式
GridData gridData; //声明一个GridData对象
Text text1 = new Text(shell,SWT.NONE);
text1.setText("1");
gridData = new GridData(GridData.VERTICAL_ALIGN_FILL);/**定义一个
/*gridData的类型,其中VERTICAL_ALIGN_FILL代表垂直方向按单
/*元格拉伸对齐。下面的HORIZONTAL_ALIGN_FILL代表在水平方向上
/*按单元格拉伸对其,而FILL_BOTH代表双向拉伸充满。当然还有水/*平方向上的FILL_HORIZONTAL等。**/
gridData.verticalSpan = 2;//设置垂直方向所占用的单元格数
text1.setLayoutData(gridData); //设置Text对象的GridData
Text text2 = new Text(shell,SWT.NONE);
text2.setText("2");
gridData = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
gridData.horizontalSpan = 5;
text2.setLayoutData(gridData);
Text text3 = new Text(shell,SWT.NONE);
text3.setText("3");
gridData = new GridData(GridData.FILL_BOTH);
gridData.horizontalSpan = 4; //设置水平方向上所占用的单元格数
text3.setLayoutData(gridData);
Text text4 = new Text(shell,SWT.NONE);
text4.setText("4");
gridData = new GridData(GridData.VERTICAL_ALIGN_FILL);
gridData.verticalSpan = 2;
text4.setLayoutData(gridData);
Text text5 = new Text(shell,SWT.NONE);
text5.setText("5");
gridData = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
gridData.horizontalSpan = 5;
text5.setLayoutData(gridData);
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch())
display.sleep();
}
display.dispose();
}
}
具体效果如下图:
从上面的例子可以看出,GridLayout相当于一个表格,而GridData相当于表格中的单元格,我们可以通过控制GridLayout来控制建立个每行多少列的表格、表格的边距是多少,在通过GridData来设定每个单元格具体是什么样子的、是否需要水平或垂直合并单元格、每个单元格具有什么样一种拉伸属性等等。
StackLayout是堆栈式显示方式顾名思义,就是说某个位置有一堆东西,然后你去选择使用哪一个。下面我们还是举个小例子
package swt.examples;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StackLayout;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
public class StackLayOut {
private Display display;
private Shell shell;
private StackLayout stackLayout;
private Composite composite;
private Composite cmp;
private Composite cmp1;
public StackLayOut() {
display = new Display();
shell = new Shell(display);
shell.setSize(200, 150);
GridLayout gridLayout = new GridLayout();
GridData gridData;
gridLayout.numColumns = 2;
shell.setLayout(gridLayout);
Button btn = new Button(shell, SWT.NONE);
Button btn1 = new Button(shell, SWT.NONE);
gridData = new GridData();
btn.setText("red");
btn.setLayoutData(gridData);
gridData = new GridData();
btn1.setText("green");
btn1.setLayoutData(gridData);
gridData = new GridData(GridData.FILL_BOTH);
gridData.horizontalSpan = 2;
composite = new Composite(shell, SWT.BORDER);
composite.setLayoutData(gridData);
stackLayout = new StackLayout();
composite.setLayout(stackLayout);
cmp = new Composite(composite, SWT.BORDER);
cmp.setBackground(new Color(composite.getDisplay(), new RGB(255
, 0, 0)));
cmp.setLayout(new FillLayout());
cmp1 = new Composite(composite, SWT.BORDER);
cmp1.setBackground(new Color(composite.getDisplay(), new RGB(0,
255, 0)));
cmp1.setLayout(new FillLayout());
stackLayout.topControl = cmp;
btn.addMouseListener(new MouseListener() {
public void mouseDoubleClick(MouseEvent e) {
}
public void mouseUp(MouseEvent e) {
stackLayout.topControl = cmp;
composite.layout();
}
public void mouseDown(MouseEvent e) {
}
});
btn1.addMouseListener(new MouseListener() {
public void mouseDoubleClick(MouseEvent e) {
}
public void mouseUp(MouseEvent e) {
stackLayout.topControl = cmp1;
composite.layout();
}
public void mouseDown(MouseEvent e) {
}
});
}
public void open() {
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch())
display.sleep();
}
display.dispose();
}
public static void main(String[] args) {
StackLayOut slo = new StackLayOut();
slo.open();
}
}
具体效果如下图:
如上例所示StackLayout方法使用很简单,不需要什么特殊的设置,只是你需要通过设置你的StackLayout对象的topControl属性为你要显示的控件名即可。而且需要记住,每当你设置过topControl属性以后都需要将你的父对象(在上例中为composite)重新layout一下。这样它才能刷新显示。同时在上例中我们提到了事件的用法,我们将会在下面的篇幅对SWT中的事件处理进行简单的介绍。