swt实例

原创:swt教程1
4.1.1 SWT程序开发步骤
在eclipse的plugins目录下,找到文件 org.eclipse.swt.win32.win32.x86_3.2.1.v3235.jar,文件名中中3.2.1是eclipse的版本号,v3235是SWT的序列号,不同的eclipse版本这两个数字也不同。在DOS状态下,用jar命令将该文件解压,命令格式如下:
jar xf org.eclipse.swt.win32.win32.x86_3.2.1.v3235.jar
该命令将指定的文件org.eclipse.swt.win32.win32.x86_3.2.1.v3235.jar解压到当前目录下。解压后得到四个DLL文件:swt-win32-3235.dll,swt-awt-win32-3235.dll,swt-gdip- win32-3235.dll和swt-wgl-win32-3235.dll。这四个文件就是SWT的原生库文件。原生库文件为SWT通过JNI访问 windows本地API提供了接口,为使Java程序在启动时能够访问这些文件,可以通过以下方法进行设置:

方法一:将这四个DLL文件复制到jre的bin目录下。

方法二:设置环境变量,在PATH中加入这几个dll文件所在的目录。

方法三:在eclipse的Java项目中导入原生库文件。操作方法是:

在eclipse的包资源管理器中,右单击项目名→导入→常规→文件系统→下一步→浏览→选择DLL文件所在目录→确定→勾选DLL文件→完成。

导入SWT的原生库文件后,还要在eclipse的Java项目中配置构建路径,添加外部JAR,将文件org.eclipse.swt.win32.win32.x86_3.2.1.v3235.jar加入到项目中,操作方法是:
在eclipse的包资源管理器中,右单击项目名→构建路径→配置构建路径→库(L)→添加外部JAR→在eclipse的plugins文件夹中找到该jar文件→打开→确定。

例4.1 在Java应用程序中使用SWT的组件。

操作步骤:

① 新建一个Java项目,项目名为:sample4_1。

② 采用方法三在项目中导入原生库文件。

③ 配置构建路径,将org.eclipse.swt.win32.win32.x86_3.2.1.v3235.jar加入到项目中。eclipse包资源管理器可以看到导入的原生库文件和引入的jar文件,如图4.2所示。
④ 在项目中新建一个类,文件名为HelloSWT.java。

⑤ 在类文件中写入代码。




图4.2 包资源管理器 图4.3 程序运行结果

HelloSWT.java文件内容如下:


package edu.ch4;

import org.eclipse.swt.SWT;

import org.eclipse.swt.widgets.Display;

import org.eclipse.swt.widgets.Text;

import org.eclipse.swt.widgets.Shell;

import org.eclipse.swt.graphics.*;

class HelloSWT {




public static void main(String[] args) {

Display display=new Display();//创建一个display对象。

Shell shell=new Shell(display);//shell是程序的主窗体

shell.setLayout(null); //设置shell的布局方式

Text hello=new Text(shell,SWT.MULTI); //声明一个可以显示多行信息的文本框

shell.setText("Java应用程序"); //设置主窗体的标题

shell.setSize(200,100); //设置主窗体的大小

Color color=new Color(Display.getCurrent(),255,255,255);//声明颜色对象

shell.setBackground(color); //设置窗体的背景颜色

hello.setText("Hello, SWT World!\n\n你好,SWT世界!");//设置文本框信息

hello.pack(); //自动调整文本框的大小

//shell.pack(); //自动调整主窗体的大小

shell.open(); //打开主窗体

while(!shell.isDisposed()){ //如果主窗体没有关闭则一直循环

if(!display.readAndDispatch()){ //如果display不忙

display.sleep(); //休眠

}

}

display.dispose(); //销毁display

}

}

在包资源管理器中,右单击文件名HelloSWT.java→运行方式→Java应用程序,程序运行结果如图4.3所示。该窗体具有典型的Windows风格。

分析本例的源代码,可以看到,创建一个典型的SWT应用程序需要以下步骤:

①创建一个Display

②创建一个或多个Shell

③设置Shell的布局

④创建Shell中的组件

⑤用open()方法打开Shell窗体

⑥写一个事件转发循环

⑦销毁display


ouyangjl 2007年03月24日 22:38
4.2 SWT/JFace常用组件
SWT/JFace常用组件有按钮(Button类)、标签(Label类)、文本框(Text类)、下拉框(Combo类)和列表框(List类)等。
4.2.1 按钮组件
按钮(Button)组件是SWT中最常用的组件,Button类的构造方法是:
Button(Composite parent,int style)
该方法有两个参数:
第一个参数parent是指Button创建在哪一个容器上。Composite(面板)是最常用的容器,Shell(窗体)继承自 Composite,此参数也能接受Shell和任何继承自Compsite的类。第二个参数style用来指定Button的式样。SWT组件可以在构造方法中使用式样(style)来声明组件的外观形状和文字的式样。SWT组件的构造方法和Button类相似,参数的含义也相同。
1.Button组件常用式样
SWT.PUSH:按钮。
SWT.CHECK:多选按钮。
SWT.RADIO:单选按钮。
SWT.ARROW:箭头按钮。
SWT.NONE:默认按钮。
SWT.CENTER:文字居中,与SWT.NONE相同。
SWT.LEFT:文字靠左。
SWT.RIGHT:文字靠右。
SWT.BORDER:深陷型按钮。
SWT.FLAT:平面型按钮。
一个Button也可以指定多个式样,只要将指定的各个式样用符号“|”连接起来即可。如:
Button bt=new Button(shell,SWT.CHECK|SWT.BORDER|SWT.LEFT);
表示创建的按钮bt是一个复选按钮(CHECK),深陷型(BORDER)、文字左对齐(LEFT)。
2.Button组件的常用方法
setText(String string):设置组件的标签文字。
setBounds(int x,int y,int width,int height):设置组件的坐标位置和大小(x轴坐标,y轴坐标,组件宽度width,组件高度height)。
setEnabled(Boolean enabled):设置组件是否可用。true:可用(默认值),false:不可用。
setFont(Font font):设置文字的字体。
setForeground(Color color):设置前景色。
setBackgrount(Color color):设置背景色。
setImage(Image image):设置显示的图片。
setSelection(Boolean selected):设置是否选中(仅对复选框或单选框有效)。true:选中,false:未选中(默认值)。
setToolTipText(String string):设置鼠标停留在组件上时出现的提示信息。
以上方法在其他组件中也可使用。
例4.2 按钮示例。
按照例4.1的操作步骤建立项目、设置构建路径和引入原生库。类Sample4_2.java源代码如下:
package edu.ch4;
import org.eclipse.swt.*;
import org.eclipse.swt.widgets.*;
public class Sample4_2 {
public static void main(String[] args) {
Display display=new Display();//创建一个display对象。
Shell shell=new Shell(display);//shell是程序的主窗体
//shell.setLayout(null); //设置shell的布局方式
shell.setText("按钮示例"); //设置主窗体的标题
Button bt1=new Button(shell,SWT.NULL); //创建默认按钮
bt1.setText("SWT.NULL"); //设置按钮上的文字
bt1.setBounds(10,10,75,30); //设置按钮显示位置及宽度、高度
Button bt2=new Button(shell,SWT.PUSH|SWT.BORDER); //创建深陷型按钮
bt2.setText("SWT.PUSH");
bt2.setBounds(90,10,75,30);
Button check1=new Button(shell,SWT.CHECK);//创建复选按钮
check1.setText("SWT.CHECK");
check1.setBounds(10,50,75,30);
Button check2=new Button(shell,SWT.CHECK|SWT.BORDER);//创建深陷型复选按钮
check2.setText("SWT.CHECK");
check2.setBounds(90,50,75,30);
Button radio1=new Button(shell,SWT.RADIO);//创建单选按钮
radio1.setText("SWT.RADIO");
radio1.setBounds(10,90,75,30);
Button radio2=new Button(shell,SWT.RADIO|SWT.BORDER);//创建深陷型单选按钮
radio2.setText("SWT.RADIO");
radio2.setBounds(90,90,75,30);
Button arrowLeft=new Button(shell,SWT.ARROW|SWT.LEFT);//创建箭头按钮(向左)
arrowLeft.setBounds(10,130,75,20);
Button arrowRight=new Button(shell,SWT.ARROW|SWT.RIGHT|SWT.BORDER);
arrowRight.setBounds(90,130,75,20);
shell.pack(); //自动调整主窗体的大小
shell.open(); //打开主窗体
while(!shell.isDisposed()){ //如果主窗体没有关闭
if(!display.readAndDispatch()){ //如果display不忙
display.sleep(); //休眠
}
}
display.dispose(); //销毁display
}
}
运行结果如图4.4所示。

图4.4 按钮 图4.5 标签
4.2.2 标签组件
标签(Label类)组件是SWT中最简单的组件。Label类的构造方法和Button类相似,参数的含义与相同,格式如下:
Label(Composite parent,int style)
Label类的常用式样有以下几种:
Label类常用的式样如下:
SWT.CENTER:文字居中。
SWT.RIGHT:文字靠右。
SWT.LEFT:文字靠左。
SWT.NONE:默认式样。
SWT.WRAP:自动换行。
SWT.BORDER:深陷型。
SWT.SEPARATOR:分栏符,默认为竖线分栏。
SWT.HORIZONTAL:横线分栏符。
例4.3 标签示例。
package edu.ch4;
import org.eclipse.swt.*;
import org.eclipse.swt.widgets.*;
import org.eclipse.swt.graphics.Font;
public class Sample4_3 {
public static void main(String[] args) {
Display display=new Display();//创建一个display对象。
Shell shell=new Shell(display);//shell是程序的主窗体
//shell.setLayout(null); //设置shell的布局方式
shell.setText("标签示例"); //设置主窗体的标题
Label lb1=new Label(shell,SWT.BORDER|SWT.RIGHT);//深陷型、文字右对齐
lb1.setBounds(10,10,70,30);
lb1.setText("标签1");
lb1.setFont(new Font(display,"黑体",14,SWT.BOLD));//设置文字的字体字号
lb1.setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_BLUE));
Label lb2=new Label(shell,SWT.CENTER);//文字居中的标签
lb2.setBounds(90,10,70,30);
lb2.setText("标签2");
lb2.setFont(new Font(display,"宋体",14,SWT.NORMAL));//设置文字的字体字号
Label lb3=new Label(shell,SWT.SEPARATOR|SWT.BORDER);//竖直分栏符
lb3.setBounds(10,50,70,30);
Label lb4=new Label(shell,SWT.SEPARATOR|SWT.HORIZONTAL|SWT.BORDER);
//水平分栏符
lb4.setBounds(90,50,70,30);
shell.pack(); //自动调整主窗体的大小
shell.open(); //打开主窗体
while(!shell.isDisposed()){ //如果主窗体没有关闭则一直循环
if(!display.readAndDispatch()){ //如果display不忙
display.sleep(); //休眠
}
}
display.dispose(); //销毁display
}
}
程序运行结果如图4.5所示。
4.2.3 文本框组件
文本框(Text类)的式样如下:
SWT.NONE:默认式样。
SWT.CENTER:文字居中。
SWT.LEFT:文字靠左。
SWT.RIGHT:文字靠右。
SWT.MULTI:可以输入多行,须回车换行。
SWT.WRAP:可以输入多行,到行尾后自动换行。
SWT.PASSWORD:密码型,输入字符显示成“*”。
SWT.BORDER:深陷型。
SWT.V_SCROLL:带垂直滚动条。
SWT.H_SCROLL:带水平滚动条。
例4.4 各种文本框示例。
package edu.ch4;
import org.eclipse.swt.*;
import org.eclipse.swt.widgets.*;
public class Sample4_4 {
public static void main(String[] args) {
Display display=new Display();//创建一个display对象。
Shell shell=new Shell(display);//shell是程序的主窗体
shell.setText("文本框示例");
Text text1=new Text(shell,SWT.NONE|SWT.BORDER);//带边框
text1.setBounds(10,10,70,30);
Text text2=new Text(shell,SWT.PASSWORD);
text2.setBounds(90,10,70,30);
Text text3=new Text(shell,SWT.MULTI|SWT.V_SCROLL|SWT.H_SCROLL);
text3.setBounds(10,50,70,70);
Text text4=new Text(shell,SWT.WRAP|SWT.V_SCROLL);
text4.setBounds(90,50,70,70);
shell.pack();
shell.open();
while(!shell.isDisposed()){ //如果主窗体没有关闭则一直循环
if(!display.readAndDispatch()){ //如果display不忙
display.sleep(); //休眠
}
}
display.dispose(); //销毁display
}
}
运行结果如图4.6所示。

图4.6 文本框 图4.7 下拉框
4.2.4 下拉框组件
1.下拉框(Combo类)的式样
SWT.NONE:默认式样。
SWT.READ_ONLY:只读。
SWT.SIMPLE:无须单击下拉框,列表会一直显示。
2.下拉框(Combo类)的常用方法
add(String string):在Combo中增加一项。
add(String string,int index):在Combo的第index项后插入一项。
deselectAll():使Combo组件中的当前选择项置空。
removeAll():将Combo中的所有选项清空。
setItems(String[] items):将数组中的各项依次加入到Combo中。
select(int index):将Combo的第index+1项设置为当前选择项。
例4.5 下拉框示例。
package edu.ch4;
import org.eclipse.swt.*;
import org.eclipse.swt.widgets.*;
import org.eclipse.swt.events.*;
public class Sample4_5 {
private static Label lb;
public static void main(String[] args) {
Display display=new Display();//创建一个display对象。
final Shell shell=new Shell(display);//shell是程序的主窗体
shell.setText("下拉框示例");
final Combo combo=new Combo(shell,SWT.NONE);
combo.setBounds(10,10,100,25);
lb=new Label(shell,SWT.WRAP); //创建标签,可自动换行
lb.setBounds(120,10,100,35);
Button bt1=new Button(shell,SWT.NONE);
bt1.setBounds(20,60,100,25);
bt1.setText("设值");
bt1.addSelectionListener(new SelectionAdapter(){
public void widgetSelected(SelectionEvent e){ //按钮的单击事件
combo.removeAll(); //清空combo
for(int i=1;i<=3;i++){
combo.add("第"+i+"项"); //循环添加选项
}
combo.select(0); //设置默认选项
}
});
Button bt2=new Button(shell,SWT.NONE);
bt2.setBounds(130,60,100,25);
bt2.setText("取值");
bt2.addSelectionListener(new SelectionAdapter(){
public void widgetSelected(SelectionEvent e){ //按钮的单击事件
lb.setText("你选择的是:"+combo.getText());
}
});
shell.pack();
shell.open();
while(!shell.isDisposed()){ //如果主窗体没有关闭则一直循环
if(!display.readAndDispatch()){ //如果display不忙
display.sleep(); //休眠
}
}
display.dispose(); //销毁display
}
}
运行结果如图4.7所示。本例中,按钮bt1和bt2添加了按钮选择监听事件代码。下拉框最初没有值,单击【设置】按钮后将一组数据加入,单击【取值】按钮,标签lb显示取值的结果。
4.2.5 列表框组件
列表框(List类)组件的用法和下拉框(Combo类)相似。
1.列表框(List类)的式样
SWT.NONE:默认式样。
SWT.V_SCROLL:带垂直滚动条。
SWT.MULTI:允许复选。
SWT.SINGLE:允许单选。
2.常用方法
列表框(List类)组件的方法和下拉框(Combo类)是一样的,但由于List可选择多项,而Combo只能选择一项,所以List没有getText()方法,List的取值是用getSelection()方法,返回一个所有选项组成的String数组。
例4.6 列表框示例。
package edu.ch4;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.List;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
public class Sample4_6 {
private static Label lb;
public static void main(String[] args) {
Display display=new Display();//创建一个display对象。
final Shell shell=new Shell(display);//shell是程序的主窗体
shell.setText("列表框示例");
final List list=new List(shell,SWT.MULTI|SWT.V_SCROLL|SWT.BORDER);
//声明一个可复选、带垂直滚动条、有边框的列表框。
list.setBounds(10,10,100,50);
lb=new Label(shell,SWT.WRAP);
lb.setBounds(120,10,90,50);
Button bt1=new Button(shell,SWT.NONE);
bt1.setBounds(20,60,100,25);
bt1.setText("设值");
bt1.addSelectionListener(new SelectionAdapter(){
public void widgetSelected(SelectionEvent e){
list.removeAll();
for(int i=1;i<=8;i++){
list.add("第"+i+"项"); //将选项循环加入到列表框中
}
list.select(0);
}
});
Button bt2=new Button(shell,SWT.NONE);
bt2.setBounds(130,60,100,25);
bt2.setText("取值");
bt2.addSelectionListener(new SelectionAdapter(){
public void widgetSelected(SelectionEvent e){
String[] selected=list.getSelection(); //声明字符串数组保存选项
String outStr=" ";
for(int j=0;j<selected.length;j++){
outStr=outStr+" "+selected[j]; //将数组中的选项加入到输出字符串
}
lb.setText("你选择的是:"+outStr);
}
});
shell.pack();
shell.open();
while(!shell.isDisposed()){ //如果主窗体没有关闭则一直循环
if(!display.readAndDispatch()){ //如果display不忙
display.sleep(); //休眠
}
}
display.dispose(); //销毁display
}
}
本例开始运行时,列表框是空的,单击【设置】按钮,将选项加入到列表框中,按【Ctrl】键加鼠标左键选项,再按【取值】按钮。运行结果如图4.8所示。

图4.8 列表框



ouyangjl 2007年03月24日 22:42
4.2.6 菜单
菜单(Menu类,MenuItem类)是常用的SWT组件,Menu是一个菜单栏,同时也是一个容器,可以容纳菜单项(MenuItem)。
1.Menu的式样
SWT.BAR:菜单栏,用于主菜单。
SWT.DROP_DOWN:下拉菜单,用于子菜单。
SWT.POP_UP:鼠标右键弹出式菜单。
2.MenuItem的式样
SWT.CASCADE:有子菜单的菜单项。
SWT.CHECK:选中后前面显示一个小勾。
SWT.PUSH:普通型菜单。
SWT.RADIO:选中后前面显示一个圆点。
SWT.SEPARATOR:分隔符。
3.建立菜单的一般步骤:
①首先建立一个菜单栏,需要使用SWT.BAR属性。
Menu mainMenu=new Menu(shell,SWT.BAR);
②在窗体中指定需要显示的菜单栏。
shell.setMenuBar(mainMenu);
③创建顶级菜单项,需要使用SWT.CASCADE属性。
MenuItem fileItem=new MenuItem(mainMenu,SWT.CASCADE);
fileItem.setText("文件&F");
④创建与顶级菜单项相关的下拉式菜单。
Menu fileMenu=new Menu(shell,SWT.DROP_DOWN);
⑤将顶级菜单项与下拉菜单关联。
fileItem.setMenu(fileMenu);
二级菜单的创建只需重复以上步骤③~⑤。注意:本例创建所有Menu对象的第一个参数都是shell;创建MenuItem对象的第一个参数是该 MenuItem所在的Menu对象;如果某Menu是某MenuItem的子菜单,则还要建立关联:MenuItem.setMenu(Menu)。源代码如下:
package edu.ch4;
import org.eclipse.swt.widgets.*;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.events.*;
import org.eclipse.swt.*;
public class Sample4_7 {
public static void main(String[] args) {
Display display=new Display();//创建一个display对象。
final Shell shell=new Shell(display);//shell是程序的主窗体
shell.setText("菜单示例");
Menu mainMenu=new Menu(shell,SWT.BAR);
shell.setMenuBar(mainMenu);
//Menu mainMenu=new Menu(shell,SWT.POP_UP); //创建弹出式菜单
//shell.setMenu(mainMenu); //创建弹出式菜单
{
//"文件"项
MenuItem fileItem=new MenuItem(mainMenu,SWT.CASCADE);
fileItem.setText("文件&F");
//"文件"菜单
Menu fileMenu=new Menu(shell,SWT.DROP_DOWN);
fileItem.setMenu(fileMenu);
{
//"新建"项
MenuItem newFileItem=new MenuItem(fileMenu,SWT.CASCADE);
newFileItem.setText("新建&N");
//"新建"菜单
Menu newFileMenu=new Menu(shell,SWT.DROP_DOWN);
newFileItem.setMenu(newFileMenu);
{
//"新建项目"项
MenuItem newProjectItem=new MenuItem(newFileMenu,SWT.PUSH);
newProjectItem.setText("项目\tCtrl+Shift+N");
//设置快捷键
newProjectItem.setAccelerator(SWT.CTRL+SWT.SHIFT+'N');
//添加事件监听
newProjectItem.addSelectionListener(new SelectionAdapter(){
public void widgetSelected(SelectionEvent e){
Text text=new Text(shell,SWT.MULTI|SWT.BORDER|SWT.WRAP);
text.setBounds(10,10,100,30);
text.setText("你选择了“新建项目”");
}
});
new MenuItem(newFileMenu,SWT.SEPARATOR);
new MenuItem(newFileMenu,SWT.PUSH).setText("包");
new MenuItem(newFileMenu,SWT.PUSH).setText("类");
}
MenuItem openFileItem=new MenuItem(fileMenu,SWT.CASCADE);
openFileItem.setText("打开&O");
MenuItem exitItem=new MenuItem(fileMenu,SWT.CASCADE);
exitItem.setText("退出&E");
}
MenuItem helpItem=new MenuItem(mainMenu,SWT.CASCADE);
helpItem.setText("帮助&H");
}
shell.pack();
shell.open();
while(!shell.isDisposed()){ //如果主窗体没有关闭则一直循环
if(!display.readAndDispatch()){ //如果display不忙
display.sleep(); //休眠
}
}
display.dispose(); //销毁display
}
}
程序运行结果如图4.9、4.10所示。当点击【文件】→【新建】→【项目Ctrl+Shift+N】时,文本框中显示“你选择了‘新建项目’”。


图4.9 选择菜单 图4.10 运行结果
创建弹出式菜单只需将①、②两步的代码改为以下两行即可。
Menu mainMenu=new Menu(shell,SWT.POP_UP); //创建弹出式菜单
shell.setMenu(mainMenu); //创建弹出式菜单


水狐 2007年03月25日 00:04
哈哈 支持原创! 不错

加油!


ouyangjl 2007年03月28日 21:55
4.3 容器类
通常,组件构建在容器类中,容器构建在主窗体(shell)中,主窗体也是容器,也就是说,容器不仅可以容纳组件,也可以容纳容器。有了容器,就可以通过它来对组件进行集体操作。例如,容器在界面上移动时,其上的组件也会随着容器移动,容器隐藏,其组件也会被隐藏,容器销毁(dispose),其组件也会被销毁。
4.3.1 面板
面板(Composite类)是最常用的容器。主窗体(shell)是面板(Composite)的子类。面板的构造方法格式如下:
Composite(Composite parent,int style)
第一个参数表示该容器创建在哪个容器上,第二个参数表示容器的式样。Composite的式样一般都是用SWT.NONE,这时 Composite在界面是不显示出来的,只是发挥着容器的作用。如果要让容器形成凹陷效果,可以用SWT.BORDER式样。例如,在主窗体中创建一个容器:
Composite composite=new Composite(shell,SWT.NONE);
Composite的常用方法:
getLayout():得到布局管理器。
getLayoutData():得到布局数据。
getParent():得到容纳该容器的父容器。
getShell():得到容纳该容器的Shell。
layout():将容器上的组件重新布局,相当于刷新。
例4.8 面板示例。
package edu.ch4;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
public class Sample4_8 {
public static void main(String[] args) {
Display display=new Display();//创建一个display对象。
final Shell shell=new Shell(display);//shell是程序的主窗体
shell.setText("容器示例");
Composite composite1=new Composite(shell,SWT.NONE);
composite1.setBounds(10,10,100,50);
Composite composite2=new Composite(shell,SWT.BORDER);
composite2.setBounds(120,10,100,50);
Label lb1=new Label(composite1,SWT.NONE);
lb1.setText("面板1");
lb1.pack();
Label lb2=new Label(composite2,SWT.NONE);
lb2.setText("面板2");
lb2.pack();
shell.pack();
shell.open();
while(!shell.isDisposed()){ //如果主窗体没有关闭则一直循环
if(!display.readAndDispatch()){ //如果display不忙
display.sleep(); //休眠
}
}
display.dispose(); //销毁display
}
}
运行结果如图4.11所示。

图4.11 面板 图4.12 分组框
4.3.2 分组框
分组框(Group类)是面板(Composite类)的子类,所以两者用法基本相同。主要区别是Group显示有一个方框,且方框线上还可以显示说明文字。
例4.9 分组框示例。
package edu.ch4;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.*;
public class Sample4_9 {
public static void main(String[] args) {
Display display=new Display();//创建一个display对象。
final Shell shell=new Shell(display);//shell是程序的主窗体
shell.setText("分组框示例");
Group group1=new Group(shell,SWT.NONE); //创建分组框
group1.setText("录入信息"); //设置分组框说明信息
group1.setBounds(10,20,200,100);
Label lb1=new Label(group1,SWT.NONE); //在分组框中加入组件
lb1.setText("姓名:");
lb1.setBounds(10,20,70,20);
Text text1=new Text(group1,SWT.BORDER);
text1.setBounds(90,20,70,20);
Label lb2=new Label(group1,SWT.NONE);
lb2.setText("地址:");
lb2.setBounds(10,50,70,20);
Text text2=new Text(group1,SWT.BORDER);
text2.setBounds(90,50,70,20);
shell.pack();
shell.open();
while(!shell.isDisposed()){ //如果主窗体没有关闭则一直循环
if(!display.readAndDispatch()){ //如果display不忙
display.sleep(); //休眠
}
}
display.dispose(); //销毁display
}
}
运行结果如图4.12所示。
4.3.3 选项卡
选项卡包括一个选项卡(TabFolder类)和一个选项页(TabItem类),TabFolder是容器,可以容纳其他容器和组件,但TabItem 不是容器,可以把它看成是一个选项标签,TabFolder通过TabItem来对其中的组件进行控制。每一个TabItem用setControl() 方法来控制一个界面组件。
例4.10 选项卡示例。
package edu.ch4;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.*;
public class Sample4_10 {
public static void main(String[] args) {
Display display=new Display();//创建一个display对象。
final Shell shell=new Shell(display);//shell是程序的主窗体
shell.setText("选项卡示例");
TabFolder tabFolder=new TabFolder(shell,SWT.NONE);//声明一个选项卡容器
tabFolder.setBounds(5,5,180,130); //设置选项卡的位置和大小
TabItem tabItem1=new TabItem(tabFolder,SWT.NONE);//声明第1个选项页
tabItem1.setText("选项1"); //设置选项页的标题
{
//创建第1个分组框,建立在tabFolder上
Group group1=new Group(tabFolder,SWT.NONE);
group1.setText("录入信息"); //设置分组框说明信息
tabItem1.setControl(group1); //让tabItem1控制group1
Label lb1=new Label(group1,SWT.NONE); //注意Label建立在group1上
lb1.setText("姓名:");
lb1.setBounds(10,20,70,20);
Text text1=new Text(group1,SWT.BORDER);
text1.setBounds(90,20,70,20);
Label lb2=new Label(group1,SWT.NONE);
lb2.setText("地址:");
lb2.setBounds(10,50,70,20);
Text text2=new Text(group1,SWT.BORDER);
text2.setBounds(90,50,70,20);
}
TabItem tabItem2=new TabItem(tabFolder,SWT.NONE); //声明第2个选项页
tabItem2.setText("选项2");
{
//创建第2个分组框,建立在tabFolder上
Group group2=new Group(tabFolder,SWT.NONE);
tabItem2.setControl(group2); //让tabItem2控制group2
group2.setText("兴趣爱好");
Button bt1=new Button(group2,SWT.CHECK);
bt1.setBounds(20,20,70,20);
bt1.setText("音乐");
Button bt2=new Button(group2,SWT.CHECK);
bt2.setBounds(20,50,70,20);
bt2.setText("美术");
Button bt3=new Button(group2,SWT.CHECK);
bt3.setBounds(20,80,70,20);
bt3.setText("体育");
}
shell.pack();
shell.open();
while(!shell.isDisposed()){ //如果主窗体没有关闭则一直循环
if(!display.readAndDispatch()){ //如果display不忙
display.sleep(); //休眠
}
}
display.dispose(); //销毁display
}
}
运行结果如图4.13、4.14所示。

图4.13 选项1 图4.14 选项2


ouyangjl 2007年03月28日 21:57
4.4 布局管理器
在 Java 中, GUI 程序开发的目标之一是跨平台,而每种类型操作系统对屏幕的定义不一样,所以 Swing 中引入了布局的概念,对子组件的位置和大小等信息进行定义。 SWT 中也采用了布局方式,用户可使用布局来控制组件中元素的位置和大小等信息。
组件可以用方法setBounds (int x, int y, int width, int height) 来指定该组件相对于父组件的位置和组件的大小。组件的这种定位方式称为绝对定位。当组件数量较多,布局较复杂时,则要使用布局管理器 LayoutManager来进行定位,这时,每个控件的坐标X、Y、宽度和高度都是通过 LayoutManager 设置的,这种定位方式称为托管定位。SWT 提供了一些常用的布局管理器供用户使用;在本章中,将介绍四种基本的布局管理器: FillLayout 、 RowLayout 、 GridLayout 和 FormLayout 。在布局管理器中,每当重新设置复合组件的大小,都需要进行定位。
布局管理器常常是专为某一个复合组件设计的。一些布局管理器只使用它们自身的参数就可以控制,而另一些布局管理器还需要其它参数( LayoutData ),该参数是在设置布局管理器的复合组件中的每个控件上指定的。 SWT 中常用的布局管理器有如下一些:
FillLayout :充满式布局,在容器中以相同的大小以单行或单列排列组件。
RowLayout :行列式布局,以单行或多行的方式定制组件的排列方式。
GridLayout :网格式布局,以网格的方式进行布局,组件可以占用指定的一个或几个网格。
FormLayout :表格式布局,通过定义组件四个边的距离来排列组件,被引用的相对的组件可以是父组件,也可以是同一容器中的其它组件。
4.4.1 充满式布局
充满式布局(FillLayout类)是最简单的布局管理器。它把组件按一行或一列充满整个容器,并强制组件的大小一致。一般,组件的高度与最高组件相同,宽度与最宽组件相同。FillLayout不能折行,不能设置边界距离和间距。如果容器中只有一个组件,则该组件会充满整个容器。
1.构造方法:
FillLayout() 创建按一行充满容器的对象。
FillLayout(int type) 创建按指定类型充满容器的对象,指定类型(type)有:SWT.HORIZONTAL 按一行充满容器。
SWT.VERTICAL 按一列充满容器。
2.常用属性:
int type 指定组件充满容器的类型。type的取值同上。
要将组件按一列充满容器,可以设置type属性,代码如下:
FillLayout filllayout=new FillLayout(); //创建FillLayout对象
Filllayout.type=SWT.VERTICAL; //设置type的值
shell.setLayout(filllayout); //将FillLayout对象用于shell上
new Button(shell,SWT.PUSH).setText("超宽按钮1");//在shell中创建按钮
new Button(shell,SWT.PUSH).setText("按钮2");
new Button(shell,SWT.PUSH).setText("按钮3");
new Button(shell,SWT.PUSH).setText("按钮4");

例4.11 充满式布局示例。
package edu.ch4;
import org.eclipse.swt.*;
import org.eclipse.swt.widgets.*;
import org.eclipse.swt.layout.*;
public class Sample4_11 {
public static void main(String[] args) {
Display display=new Display();//创建一个display对象。
final Shell shell=new Shell(display);//shell是程序的主窗体
shell.setText("FillLayout示例");
FillLayout filllayout=new FillLayout(); //创建FillLayout对象
shell.setLayout(filllayout); //将FillLayout对象用于shell上
new Button(shell,SWT.PUSH).setText("超宽按钮1");//在shell中创建按钮
new Button(shell,SWT.PUSH).setText("按钮2");
new Button(shell,SWT.PUSH).setText("按钮3");
new Button(shell,SWT.PUSH).setText("按钮4");
shell.pack();
shell.open();
while(!shell.isDisposed()){ //如果主窗体没有关闭则一直循环
if(!display.readAndDispatch()){ //如果display不忙
display.sleep(); //休眠
}
}
display.dispose(); //销毁display
}
}
运行结果如图4.15所示。

图4.15 FillLayout水平布局 图4.16 FillLayout垂直布局
如果要将按钮按竖直方向排列,也可以只修改以下一行语句:
Layout layout=new FillLayout(SWT.VERTICAL);
运行结果如图4.16所示。
4.4.2 行列式布局
行列式布局(RowLayout类)可以使组件折行显示,可以设置边界距离和间距。另外,还可以对每个组件通过setLayoutData()方法设置RowData对象。RowData用来设置组件的大小。
1.构造方法:
RowLayout() 创建按行放置组件的对象。
RowLayout(int type) 创建按指定类型放置组件的对象。指定类型(type)有:
SWT.VERTICAL 按列放置组件。
SWT.HORIZONTAL 按行放置组件。
2.常用属性:
int marginWidth:组件距容器边缘的宽度(像素),默认值为0。
int marginHeight:组件距容器边缘的高度(像素),默认值为0。
int marginTop:组件距容器上边缘的距离(像素),默认值为3。
int marginBottom:组件距容器下边缘的距离(像素),默认值为3。
int spacing:组件之间的距离,默认值为3。
boolean justify:如果该属性为true,则组件间的距离随容器的拉伸而变大。默认值为false。
boolean wrap:如果该属性为true,则当容器空间不足时会自动折行;如果该属性为false,不自动折行。默认值为true。
boolean pack:如果该属性为true,组件大小为设定值;如果该属性为false,则强制组件的大小相同。默认值为true。
int type:使组件按指定式样放置,(type=SWT.HORIZONTAL|SWT.VERTICAL),默认为按行放置,默认值为SWT.HORIZONTAL。
3.RowData类:
RowData称为RowLayout的布局数据类,可用于改变容器中组件的外观形状。其构造方法:
RowData(int width,int height);
例如:
Button bt1=new Button(shell,SWT.PUSH); //创建按钮
bt1.setText("按钮1");
RowData rowdata=new RowData(60,30); //创建布局数据类的对象
bt1.setLayoutData(rowdata); //设置按钮的布局数据
利用RowData对象设置按钮(bt1)的宽度是60像素,高度是30像素。
例4.12 行列式布局。
package edu.ch4;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.*;
import org.eclipse.swt.widgets.*;
public class Sample4_12 {
public static void main(String[] args) {
Display display=new Display();//创建一个display对象。
final Shell shell=new Shell(display);//shell是程序的主窗体
shell.setText("FillLayout示例");
RowLayout rowlayout=new RowLayout(); //创建按行放置组件的对象
rowlayout.pack=false; //强制组件大小相同
rowlayout.wrap=false; //不自动折行
rowlayout.marginWidth=20; //组件距容器边缘的宽度为20像素
rowlayout.marginHeight=20; //组件距容器边缘的高度为20像素
rowlayout.spacing=10; //组件之间的间距为10像素
shell.setLayout(rowlayout); //设置容器shell的布局方式为rowlayout
Button bt1=new Button(shell,SWT.PUSH); //创建按钮
bt1.setText("按钮1");
RowData rowdata=new RowData(80,30); //创建布局数据类的对象
bt1.setLayoutData(rowdata); //设置按钮的布局数据
new Button(shell,SWT.PUSH).setText("按钮2");
new Button(shell,SWT.PUSH).setText("按钮3");
new Button(shell,SWT.PUSH).setText("按钮4");
shell.pack(); //自动调整容器shell的大小
shell.open(); //打开主窗体
while(!shell.isDisposed()){ //如果主窗体没有关闭则一直循环
if(!display.readAndDispatch()){ //如果display不忙
display.sleep(); //休眠
}
}
display.dispose(); //销毁display
}
}
当rowlayout.pack=true时,各按钮为设定值,如图4.17所示;当rowlayout.pack=false时,各按钮被强制设定为相同大小,如图4.18所示;当rowlayout.justify=true时,将主窗体拉伸,各按钮间的距离也增大,但间隔均匀分布,如图 4.19所示;当rowlayout.justify=false时,将主窗体拉伸,各按钮间距不变,如图4.20所示;当 rowlayout.wrap=false时,当主窗体宽度收缩,按钮自动折行,如图4.21所示;当rowlayout.wrap=false时,主窗体宽度收缩,按钮不会折行,如图4.22所示。

图4.17 rowlayout.pack=true 图4.18 rowlayout.pack=false

图4.19 rowlayout.justify=true 图4.20 rowlayout.justify=false

图4.21 rowlayout.wrap=true 图4.22 rowlayout.wrap=false
4.4.3 网格式布局
网格式布局(GridLayout类)是实用而且功能强大的标准布局,也是较为复杂的一种布局。这种布局把容器分成网格,把组件放置在网格中。 GridLayout有很多可配置的属性,和RowLayout一样,也有专用的布局数据类GridData, GridLayout的强大之处在于它可以通过GridData来设置每一个组件的外观形状。GridLayout的构造方法无参数,但可以通过 GfidData和设置GridLayout的属性来设置组件的排列及组件的形状和位置。
1.GridLayout的属性
int numColumns:设置容器的列数,组件从左到右按列放置,当组件数大于列数时,下一个组件将自动添加新的一行。默认值为1列。
boolean makeColumnsEqualWidth:强制使列都具有相同的宽度,默认值为false。
int marginWidth:设置组件与容器边缘的水平距离,默认值为5。
int marginHeight:设置组件与容器边缘的垂直距离,默认值为5。
int horizontalSpacing:设置列与列之间的间隔,默认值为5。
int verticalSpacing:设置行与行之间的间隔,默认值为5。
例4.13 GridLayout的属性设置。
package edu.ch4;
import org.eclipse.swt.*;
import org.eclipse.swt.widgets.*;
import org.eclipse.swt.layout.*;
public class Sample4_13 {
public static void main(String[] args) {
Display display = new Display();
Shell shell = new Shell(display);
shell.setText("GridLayout示例");
GridLayout gridLayout = new GridLayout();
gridLayout.numColumns = 3;
gridLayout.horizontalSpacing=30;
gridLayout.makeColumnsEqualWidth=true;
shell.setLayout(gridLayout);
new Button(shell, SWT.PUSH).setText("B1");
new Button(shell, SWT.PUSH).setText("超宽按钮 2");
new Button(shell, SWT.PUSH).setText("按钮 3");
new Button(shell, SWT.PUSH).setText("B4");
new Button(shell, SWT.PUSH).setText("按钮 5");
shell.pack();
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) display.sleep();
}
display.dispose();
}
}
当gridLayout.numColumns分别为1、2、3时,按钮依次按1列、2列和3列排列,运行结果如图4.23~4.25所示;当 makeColumnsEqualWidth=true时,虽然按钮宽度不同,但列宽相同,如图4.26所示;当 horizontalSpacing=30时,列间距为30,如图4.27所示。

图4.23 numColumns = 1 图4.24 numColumns = 2 图4.25 numColumns = 3

图4.26 makeColumnsEqualWidth=true 图4.27 horizontalSpacing=30
2.布局数据类(GridData类)
GridData是GridLayout专用的布局数据类,用GridData可以构建很多复杂的布局方式。① GridData的构造方法如下:
GridData(); 创建一个属性值为默认值的对象。
GridData(int type); 创建一个指定类型(type)的对象。
② GridData常用类型如下:
GridData.FILL 通常与GridData类的对象属性horizontalAlignment和verticalAlignment配合使用,充满对象属性指定的空间。
GridData. FILL_HORIZONTAL 水平充满,组件充满网格水平方向的空间。
GridData. FILL_VERTICAL 垂直充满,组件充满网格垂直方向的空间。
GridData. FILL_BOTH 双向充满,组件充满水平和垂直方向的空间。
GridData.HORIZONTAL_ALIGN_BEGINNING 水平对齐靠左,组件在网格中靠左放置。
GridData.HORIZONTAL_ALIGN_CENTER 水平对齐居中,组件在网格中居中放置。
GridData.HORIZONTAL_ALIGN_END 水平对齐靠右,组件在网格中靠右放置。
③ GridData常用对象属性如下:
int horizontalSpan 设置组件占用的列数,默认值为1。
int verticalSpan 设置组件占用的行数,默认值为1。
horizontalAlignment 设置组件的对齐方式为水平方向。
verticalAlignment 设置组件的对齐方式为垂直方向。
grabExcessHorizontalSpace 抢占额外的水平空间。
grabExcessVerticalSpace 抢占额外的垂直空间。
horizontalAlignment和verticalAlignment可以取以下值:
BEGINNING 开始(水平对齐时居左;垂直对齐时居上)
CENTER 居中
END 结束(水平对齐时居右;垂直对齐时居下)
FILL 充满
默认的horizontalAlignment值是BEGINNING。默认的verticalAlignment值是CENTER。
例4.14 使用gridData布局。
package edu.ch4;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.*;
import org.eclipse.swt.widgets.*;
public class Sample4_14 {
public static void main(String[] args) {
Display display = new Display();
Shell shell = new Shell(display);
shell.setText("GridData示例");
GridLayout gridLayout = new GridLayout();//创建网格布局对象
gridLayout.numColumns = 3; //设置网格布局列数为3
gridLayout.makeColumnsEqualWidth=true; //强制列宽相等
shell.setLayout(gridLayout); //将shell设置为指定的网格布局式样
GridData gridData=new GridData(); //创建网格布局数据对象
gridData.horizontalSpan = 2; //水平方向跨2列
gridData.verticalSpan=2; //垂直方向跨2行
gridData.horizontalAlignment = GridData.CENTER; //水平方向居中
gridData.verticalAlignment = GridData.FILL; //垂直方向充满
Button b1=new Button(shell, SWT.PUSH); //创建按钮对象b1
b1.setText("B1");
b1.setLayoutData(gridData); //将设定的网格布局数据用于按钮对象b1
new Button(shell, SWT.PUSH).setText("超宽按钮 2");
new Button(shell, SWT.PUSH).setText("按钮 3");
Button b4=new Button(shell, SWT.PUSH);
b4.setText("B4");
//用带参数的构造方法创建gridData对象
gridData = new GridData(GridData.FILL_HORIZONTAL);
b4.setLayoutData(gridData); //将gridData用于b4,水平方向充满
Button b5=new Button(shell, SWT.PUSH);
b5.setText("按钮 5");
gridData = new GridData();
gridData.horizontalAlignment = GridData.FILL;//设置b5为水平方向充满
b5.setLayoutData(gridData);
new Button(shell, SWT.PUSH).setText("按钮 6");
Text t1=new Text(shell,SWT.BORDER);
t1.setText("文本框 1");
gridData = new GridData();
gridData.verticalSpan = 2; //跨两行
gridData.horizontalSpan=2; //跨两列
gridData.verticalAlignment = GridData.FILL; //垂直方向充满
gridData.grabExcessVerticalSpace = true; //抢占垂直方向额外空间
gridData.horizontalAlignment = GridData.FILL;//水平方向充满
gridData.grabExcessHorizontalSpace = true;//抢占水平方向额外空间
t1.setLayoutData(gridData); //gridData用于文本框t1
new Button(shell, SWT.PUSH).setText("按钮 7");
new Button(shell, SWT.PUSH).setText("按钮 8");
shell.pack();
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) display.sleep();
}
display.dispose();
}
}
运行结果如图4.28所示。虽然按钮b1和文本框t1都占两行两列,但由于t1水平方向和垂直方向的alignment属性都是FILL,因此文本框t1充满了两行和两列的空间,而按钮b1的horizontalalignment属性是CENTER,而verticalalignment属性是 FILL,所以水平方向居中放置,而垂直方向充满了两行。按钮b4和b5采用了不同的构造方法来创建gridData对象,但都充满了该列的水平空间。
当窗体变大时,由于设置了抢占水平方向和垂直方向额外的空间,即grabExcessVerticalSpace = true和grabExcessHorizontalSpace = true,所以文本框t1随窗体的拉伸而变大,反之,当窗体缩小时,t1也会缩小。按钮b4和b5设置了水平方向充满属性,所以窗体拉伸时水平方向也会随之拉伸。其余的组件大小不变。如图4.29所示。这说明,如果组件所在的行变宽或列变高,所有具有填充(FILL)属性的组件也会变宽或变高;而具有 BEGINNING、CENTER、END属性的组件不会改变其大小。

图4.28 GridData示例 图4.29 窗体拉伸时b4、b5和t1变化
4.4.4 表格式布局
表格式布局(FormLayout类)是一种非常灵活、精确的布局方式,这个布局是SWT2.0版新增的。FormLayout也有专用的布局数据类FormData,此外,还增加了一个FormAttachment类。FormAttachment定义了组件的四边与父容器(Shell、 Composite等)的边距,为保证组件在父容器中的相对位置不变,FormAttachment类用不同的构造方法来实现组件的定位,用 FormData和FormAttachment配合,可以创建复杂的界面,而且当主窗体大小改变时,组件的相对位置能保持相对不变。 FormLayout的构造方法:FormLayout()。
1.FormLayout的属性
int marginWidth:设置组件与容器边缘的水平距离,默认值为0。
int marginHeight:设置组件与容器边缘的垂直距离,默认值为0。
例如,以下代码把父容器(shell)的四周边距都设置成10像素。
Display display = new Display ();
Shell shell = new Shell (display);
FormLayout formlayout= new FormLayout ();
formlayout.marginHeight = 10;
formlayout.marginWidth = 10;
shell.setLayout (formlayout);
2.FormData类
① FormData的构造方法
FormData() 默认构造方法,组件的宽度和高度要用属性width和height设置。
FormData(int width,int height) 参数width和height设置组件的宽度和高度。
② FormData的属性
width 设置组件的宽度。
height 设置组件的高度。
top 和FormAttachment配合设置组件顶部和父容器顶部的边距。
bottom 和FormAttachment配合设置组件底部和父容器底部的边距。
left 和FormAttachment配合设置组件左边和父容器左边的边距。
right 和FormAttachment配合设置组件右边和父容器右边的边距。
如果FormData中的width和height设置的宽度和高度与FormAttachment设置的约束发生冲突,则按照FormAttachment设置,width和height的设定值就不起作用了。
3.FormAttachment类
Attachment的含义是附着、粘贴。FormAttachment类就是用来指定组件在父容器中的粘贴位置。FormAttachment计算组件粘贴位置和组件大小的方法是依据下面的表达式:
y = ax + b
表达式中y是纵坐标,从上往下是正方向;x是横坐标,从左至右是正方向;a是斜率(a=m/n,n≠0),b是偏移量,沿x、y轴正方向的偏移量为正,反之为负。.
① FormAttachment的构造方法
FormAttachment() 组件紧贴父容器的左边缘和上边缘,如果父容器设置了FormLayout属性marginWidth和marginHeight,则距父容器的上边缘和左边缘为marginHeight和marginWidth的设定值。
FormAttachment(Control control) 以指定的组件control为参照物。
FormAttachment(Control control, int offset) 以指定的组件control为参照物,相对指定组件的偏移量为offset。
FormAttachment(Control control, int offset,int alignment) 以指定的组件control为参照物,相对指定组件的偏移量为offset,对齐方式为alignment。alignment的取值如下:
SWT.TOP、SWT.BOTTOM、SWT.LEFT、SWT.RIGHT、SWT.CENTER
FormAttachment(int m,int n, int offset) 以组件相对于父容器宽度或高度的百分比(即斜率a)来给组件定位,m为a的分子,n为a的分母,offset是偏移量。
FormAttachment(int m, int offset) 以组件相对于父容器宽度或高度的百分比(即斜率a)来给组件定位,m为a的分子,a的分母为默认值100,offset是偏移量。
FormAttachment(int m) 以组件相对于父容器宽度或高度的百分比(即斜率a)来给组件定位,m为a的分子,a的分母为默认值100,偏移量为默认值0。
例4.15 FormData与FormAttachment的配合使用。
package edu.ch4;
import org.eclipse.swt.*;
import org.eclipse.swt.layout.*;
import org.eclipse.swt.widgets.*;
public class Sample4_15 {
public static void main(String[] args) {

Display display = new Display ();
Shell shell = new Shell (display);
shell.setText("FormLayout示例");

FormLayout formLayout= new FormLayout(); //创建表格布局对象formLayout
shell.setLayout(formLayout); //设置shell的布局方式为表格布局
formLayout.marginHeight = 10; //设置shell的上下边距为10像素
formLayout.marginWidth = 20; //设置shell的左右边距为10像素
Button b1=new Button(shell,SWT.PUSH);
b1.setText("B1");
FormData formData1=new FormData(); //创建布局数据对象formData1
formData1.width=100; //按钮b1的宽度为100像素
formData1.height=50; //按钮b1的高度为50像素
b1.setLayoutData(formData1); //设置b1的布局数据为formData1

Button b2=new Button(shell,SWT.PUSH);
b2.setText("B2");
//创建FormAttachment对象formAttachment,以b1为参照物
FormAttachment formAttachment=new FormAttachment(b1); //指定B1为参照物
FormData formData2=new FormData(50,30); //创建FormData对象,宽度50,高度30
formData2.left=formAttachment; //b2的左边紧贴与b1的右边
b2.setLayoutData(formData2); //设置b2的布局数据为formData2

Button b3=new Button(shell,SWT.PUSH);
b3.setText("B3");
FormData formData3=new FormData();//创建布局数据对象formData3
formData3.top=new FormAttachment(b2,10,SWT.BOTTOM);//b2的底边与b3的顶部距离为10
formData3.left=new FormAttachment(b2,0,SWT.LEFT);//b2的左边与b3左边位移为0,
//即左边对齐
formData3.right=new FormAttachment(b2,0,SWT.RIGHT); //b2的右边与b3右边对齐
b3.setLayoutData(formData3); //设置b3的布局数据为formData3

shell.pack();
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
display.dispose();
}
}
运行结果如图4.30所示。本例中,按钮B1的宽度和高度由FormData设置,按钮的位置为默认的位置,即shell的左上角,边距由 maginHeight和maginWidth设置。按钮B2以B1为参照物,位置紧靠B1右侧,B2的上部与shell的距离由maginHeight 设定,B2的右边与shell的边距由maginWidth设定。按钮B3以B2为参照物,FormData3.TOP设定了B3的顶部距离B2的底部位移为10像素、FormData3.LEFT设定了B3与B2左边对齐、FormData3.RIGHT设定了B3与B2右边对齐。如果要使B1右侧与 B2左侧相距20相素,可将FormAttachment的构造方法增加偏移量20,如:
FormAttachment formAttachment=new FormAttachment(b1,20);
运行结果如图4.31所示。

图4.30 FormAttachment(b1) 图4.31 FormAttachment(b1,20)
构造方法FormAttachment(int m,int n, int offset) 是以组件相对于父容器宽度或高度的百分比(即斜率a)来给组件定位的,当分子m=0时,组件以父容器的左边或上边为基准,偏移量为正数;当分子m=100 时,组件以父容器的右边或下边为基准,偏移量为负数。当父容器的大小改变时,组件与父容器的基准边保持设定的距离,组件的大小随父容器的改变而变化。
例4.16构造方法FormAttachment(int m,int n, int offset)的使用示例。
package edu.ch4;
import org.eclipse.swt.*;
import org.eclipse.swt.layout.*;
import org.eclipse.swt.widgets.*;
public class Sample4_16 {
public static void main(String[] args) {
Display display = new Display ();
Shell shell = new Shell (display);
shell.setText("FormLayout示例");

FormLayout formlayout= new FormLayout();
formlayout.marginHeight=10; //设置shell的上、下边缘和组件的距离为10像素
Button b1=new Button(shell,SWT.PUSH);
b1.setText("B1");
FormData formData1=new FormData(); //创建布局数据对象formData1
formData1.top=new FormAttachment(0,50); //设置组件B1的顶部离父容器
//shell上边缘的距离为50像素
formData1.bottom=new FormAttachment(100,-50);//设置组件B1的底部离shell的下
//边缘的距离为50像素
formData1.left=new FormAttachment(0,50); //设置组件B1的左边离shell的左
//边距离为50像素
formData1.right=new FormAttachment(100,-50); //设置组件B1的右边离shell的右
//边距离为50像素
formData1.width=100; //按钮b1的宽度为100像素
formData1.height=50; //按钮b1的高度为50像素
b1.setLayoutData(formData1); //设置b1的布局数据为formData1
Button b2=new Button(shell,SWT.PUSH);
b2.setText("B2");
FormAttachment formAttachment=new FormAttachment();//创建FormAttachment对象
FormData formData2=new FormData(50,30); //创建FormData对象,宽度50,高度30
formData2.left=formAttachment; //B2的左边与shell左边缘的距离为0
formData2.top=formAttachment; //B2的上边与shell上边缘的距离为
//marginHeight设定的值(10像素)
b2.setLayoutData(formData2); //设置b2的布局数据为formData2
shell.setLayout(formlayout);
shell.pack();
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
display.dispose();
}
}

图4.32 B1与shell四边的距离相等 图4.33 shell改变后B1与其四边的距离仍相等
例4.17 综合布局示例。
package edu.ch4;
import org.eclipse.swt.widgets.*;
import org.eclipse.swt.layout.*;
import org.eclipse.swt.SWT;
public class Sample4_17 {
public static void main(String[] args) {
Display display = new Display();
Shell shell = new Shell(display);
shell.setText("FormLayout示例");
FormLayout formlayout = new FormLayout(); //创建表格布局对象
shell.setLayout(formlayout);
Label label=new Label(shell,SWT.BORDER); //在shell中创建Label对象
label.setText("Label One");
FormData data = new FormData();
data.top = new FormAttachment(0, 5); //Label与shell上边框相距5象素
data.left = new FormAttachment(0, 5); // Label与shell左边框相距5象素
data.bottom = new FormAttachment(50, -5);//Label在shell水平中线上方5象素
data.right = new FormAttachment(50, -5); // Label在shell垂直中线左边5象素
label.setLayoutData(data);
Composite composite = new Composite(shell, SWT.NONE);//创建面板
GridLayout gridLayout = new GridLayout(); //创建网格布局对象
gridLayout.marginHeight = 0;
gridLayout.marginWidth = 0;
composite.setLayout(gridLayout); //设置面板布局方式为网格布局
Button b1 = new Button(composite, SWT.PUSH); //在composite上创建button B1
b1.setText("B1");
GridData gridData = new GridData(GridData.FILL_BOTH); //设置布局方式为双向填充
b1.setLayoutData(gridData);
Button b2 = new Button(composite, SWT.PUSH); //B2设置同B1
b2.setText("B2");
gridData = new GridData(GridData.FILL_BOTH);
b2.setLayoutData(gridData);
Button b3 = new Button(composite, SWT.PUSH); //B2设置同B1
b3.setText("B3");
gridData = new GridData(GridData.FILL_BOTH);
b3.setLayoutData(gridData);
data = new FormData(); //创建FormData对象
data.top = new FormAttachment(0, 5); //设置composite距shell上边框5象素
data.left = new FormAttachment(label, 5);//设置composite距label 5象素
data.bottom = new FormAttachment(50, -5);//设置composite在shell水平中线上方5象素
data.right = new FormAttachment(100, -5);//设置composite在shell右边框的左侧5象素
composite.setLayoutData(data); //设置composite的布局数据
Text text=new Text(shell,SWT.BORDER); //创建Text对象
text.setText("Text");
data = new FormData(); //创建表格布局数据
data.top = new FormAttachment(label, 5); //text上方离label 5象素
data.left = new FormAttachment(0, 5); // text左边离shell左边框5象素
data.bottom = new FormAttachment(100, -5); // text下边框离shell下边框5象素
data.right = new FormAttachment(100, -5); // text右边框离shell右边框5象素
text.setLayoutData(data); //设置text的布局数据
shell.pack();
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
display.dispose();
}
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值