SWT概述二

SWT技术是第一套基于java的第三方的图形工具库。它的设计思想是提供一套通用的API,使得开发出的图形程序不仅可以不加修改地在平台间移植,而且在外观上和速度上能与使用C/C++等语言在操纵系统平台上开发出来的本地图形程序毫无差别。


当一个布局管理器被安装到窗口上时,它就负责安排窗口中各个控件的位置和尺寸。当窗口尺寸发生变化时,布局管理器会根据一定的策略重新计算这些数据,并将控件安排在变化后的位置上。不同的布局管理器就代表不同的计算策略。


事件是图形界面程序与用户交互的核心。

事件源:即被用户操作的控件,它负责维护一个事件监听器的队列。当某个特定事件在事件源上发生时,事件源会从监听器队列中找出对此事件感兴趣的监听器,并通知它有事件发生。


widget类直接继承自Object类,是swt中所有窗口和控件的父类,主要是为其提供了申请资源、释放资源、监听事件等功能。widget类有两个比较重要的子类,control是所有控件的父类。另一个类是Item,它代表复杂控件中的某一项。

composite是容器控件,


当父窗口关闭时,其上所有的控件资源也都会被释放,因此不需要调用代码去释放控件资源。(释放资源,一般调用dispose方法)

当一个控件的dispose方法被调用后,它所占的资源被释放了,但是这个控件所对应的Java对象仍然存在,如果对这个已经被释放资源的控件进行操作,就会得到“控件已释放”的异常。因此最好不要手动去释放控件的资源。


TypedEvent是所有事件类的父类,该类有两个字段比较有用,如下:
public int time
the time that the event occurred.
NOTE: This field is an unsigned integer and should be AND'ed with 0xFFFFFFFFL so that it can be treated as a signed long.


public Widget widget
the widget that issued the event


SelectionAdapter是SelectionListener的空实现,如果只对监听器接口中某一事件感兴趣,可以继承这个空实现,并重载感兴趣的方法。对于拥有多个方法的监听器接口,swt都提供了类似的Adapter,如MouseListener有MouseAdapter。


与Button不同,Lable控件不能同时显示图像和文字,对于Lable如果先设置图像后设置文字,只会显示文字;反之亦然。

SWT.WRAP,对多行文本有效,它可以使文本超过控件宽度时,自动换行。

Text控件可以响应的事件有DefaultSeletion,Modify和Verify。当用户在文本框中输入回车时,就会触发DefaultSelection事件,通常意味的用户输入完毕。程序可以利用SelectionListener的widgetDefaultSelection方法去监听这个事件并处理它。

每当在Text控件中输入内容时,都会触发VerifyEvent事件。可以使用VerifyListener监听器去监听,在verifyText方法中写业务处理
verifyEvent对象的text属性,表示每次输入到文本框中的值,doit属性表示是否允许新值输入,false不允许。使用setText()方法同样也会触发VerifyEvent事件。
例如:
final Text upperText;


final Text numberText = new Text(shell, SWT.BORDER);
numberText.addVerifyListener(new VerifyListener() {
public void verifyText(final VerifyEvent e) {
try {
System.out.println(e.text);
Integer.parseInt(e.text);

} catch (Exception exce) {
e.doit = false;
}
}
});
numberText.setBounds(22, 10, 138, 21);

upperText = new Text(shell, SWT.BORDER);
upperText.addVerifyListener(new VerifyListener() {
public void verifyText(final VerifyEvent e) {
e.text = e.text.toUpperCase();
}
});
upperText.setBounds(22, 40, 138, 20);

当文本框中的内容发生改变时(包括删除),就会触发ModifyEvent事件,例如:
numberText.addModifyListener(new ModifyListener() {

@Override
public void modifyText(ModifyEvent arg0) {
System.out.println(arg0.getSource());

}
});


List控件是用列表的形式向用户展示一组数据,当单击List中的某一项时,会触发SelectionEvent事件
list.addSelectionListener(new SelectionListener() {

private int oldIndex = -1;

private String oldContent = null;

public void widgetSelected(final SelectionEvent e) {
if (oldIndex != -1)
list.setItem(oldIndex, oldContent);
int index = list.getSelectionIndex();
System.out.println(index);
oldIndex = index;
oldContent = list.getItem(index);
list.setItem(index, oldContent + " selected");
}

List对象方法声明:
public void setItem(int index,
java.lang.String string)
Sets the text of the item in the receiver's list at the given zero-relative index to the string argument.
This is equivalent to remove'ing the old item at the index, and then add'ing the new item at that index.


public int getSelectionIndex()
Returns the zero-relative index of the item which is currently selected in the receiver, or -1 if no item is selected.
Returns:
the index of the selected item


public java.lang.String getItem(int index)
Returns the item at the given, zero-relative index in the receiver. Throws an exception if the index is out of range.
Parameters:
index - the index of the item to return
Returns:
the item at the given index


Combo当从下拉框中选择预先定义的项时,会同时触发SelectionEvent事件和ModifyEvent事件。
当直接编辑Combo中的内容时,只会触发ModifyEvent。当不支持verifyEvent事件。


ToolBar工具栏,ToolItem是工具栏上的按钮,和Button一样,可以同时设置图像和文字,默认文字在图像的下方。如果设置ToolBar为SWT.RIGHT,那么文字就会跑到图像的右边。默认情况下当ToolItem占用的长度超过ToolBar的长度的,ToolItem就会不显示。如果把ToolBar设置为SWT.WRAP,那么超出的部分就会自动换行显示。
ToolItem仅支持一种事件SelectionEvent,当有单击事件发生时,要实现SelectionAdapter类中的WidgetSelected方法,来添加处理逻辑。

final ToolBar horToolBar = new ToolBar(shell, SWT.HORIZONTAL);
horToolBar.setBounds(0, 0, 265,50);

Image toolBarImage1 = new Image(display, "F:\\toolbar1.gif");
Image toolBarImage2 = new Image(display, "F:\\toolbar2.gif");
Image toolBarImage3 = new Image(display, "F:\\toolbar3.gif");
Image toolBarImage4 = new Image(display, "F:\\toolbar4.gif");

final ToolItem toolItem1 = new ToolItem(horToolBar, SWT.NONE);
toolItem1.setImage(toolBarImage1);
toolItem1.setToolTipText("提示");
toolItem1.setText("Item 1");

final ToolItem toolItem2 = new ToolItem(horToolBar, SWT.CHECK);
toolItem2.setImage(toolBarImage2);
toolItem2.setText("Item 2");

final ToolItem toolItem3 = new ToolItem(horToolBar, SWT.RADIO);
toolItem3.setImage(toolBarImage3);
toolItem3.setText("Item 3");

final ToolItem toolItem4 = new ToolItem(horToolBar, SWT.RADIO);
toolItem4.setImage(toolBarImage4);
toolItem4.setText("Item 4");


如果普通的工具栏按钮不能满足要求,也可以将其他控件,如Text、Combo等放置在工具栏上。
例如:

final ToolBar horToolBar = new ToolBar(shell, SWT.SHADOW_OUT | SWT.RIGHT);
horToolBar.setBounds(0, 0, 500, 50);

Image toolBarImage1 = new Image(display, "F:\\toolbar1.gif");


//在工具栏上创建其他控件时,首先要设置ToolItem为SWT.SEPARATOR
final ToolItem toolItem1 = new ToolItem(horToolBar, SWT.SEPARATOR);
Text text = new Text(horToolBar,SWT.BORDER);
text.setSize(120,20);
toolItem1.setControl(text);
toolItem1.setWidth(120);
toolItem1.setText("DROP DOWN");


final ToolItem toolItem2 = new ToolItem(horToolBar, SWT.NONE);
toolItem2.setImage(toolBarImage1);
toolItem2.setToolTipText("提示");
toolItem2.setText("Item 1");


Menu菜单栏,添加菜单是要设置Menu的样式为SWT.BAR。与可以任意摆放的ToolBar不同,Menu只能处于窗口的顶部,无法调整其位置。
创建Menu的语法和其他控件没什么区别,但是多了个shell.setMenuBar(bar)。SWT是不允许在一个窗口中显示多个菜单栏的,程序可以创建多个Menu实例,但只有一个可以作为窗口的菜单。

Image menu1 = new Image(Display.getDefault(), "F:\\menu1.gif");
Image menu2 = new Image(Display.getDefault(), "F:\\menu2.gif");

Menu bar = new Menu(shell, SWT.BAR);
shell.setMenuBar(bar);

//添加下拉菜单,必须设置MenuItem的样式为SWT.CASCADE
//下拉菜单由菜单项MenuItem和菜单Menu组成(menu不包含任何样式)
//MenuItem负责在菜单栏上显示下拉菜单的文字或图像,Menu负责显示下拉菜单的内容
MenuItem fileMenuItem = new MenuItem(bar, SWT.CASCADE);
fileMenuItem.setImage(menu1);
fileMenuItem.setText("File");

MenuItem otherMenuItem = new MenuItem(bar, SWT.PUSH);
otherMenuItem.setText("Other");

final Menu fileMenu = new Menu(fileMenuItem);
fileMenuItem.setMenu(fileMenu);

//如果此菜单项是个二级菜单,必须设置样式为WT.CASCADE
final MenuItem openMenuItem = new MenuItem(fileMenu, SWT.CASCADE);
openMenuItem.setText("Open");
openMenuItem.setImage(menu1);

//建立二级菜单,并把该新建的二级菜单设置到openMenu中去
final Menu openMenu = new Menu(openMenuItem);
openMenuItem.setMenu(openMenu);

final MenuItem openDirMenuItem = new MenuItem(openMenu,SWT.PUSH);
openDirMenuItem.setText("Directory");

final MenuItem openFileMenuItem = new MenuItem(openMenu,SWT.PUSH);
openFileMenuItem.setText("File");


final MenuItem exitMenuItem = new MenuItem(fileMenu, SWT.NONE);
exitMenuItem.setText("Exit");
exitMenuItem.setImage(menu2);

还可以对MenuItem使用CHECK和RADIO样式,check表示点击该菜单项后会在前面打勾,再次单击会取消这个勾。radio表示点击该菜单项后会在前面显示一个黑心圆,再次单击同样的菜单项,该黑心圆不会去掉,必须单击其他同样的Radio菜单项,原来菜单项上的黑心圆才会去掉(只能选择一个)。这两个样式只适用于下拉菜单中的MenuItem,不适用于MenuBar中的MenuItem。


MenuItem除支持SelectionEvent事件之外,还支持HelpEvent事件,即光标停留在某个MenuItem上时,用户按下F1帮助键,就会触发HelpEvent事件。

Menu bar = new Menu(shell, SWT.BAR);
shell.setMenuBar(bar);

MenuItem fileMenuItem = new MenuItem(bar, SWT.CASCADE);
fileMenuItem.setText("File");

final Menu fileMenu = new Menu(fileMenuItem);
fileMenuItem.setMenu(fileMenu);

final MenuItem openMenuItem = new MenuItem(fileMenu, SWT.PUSH);

openMenuItem.addHelpListener(new HelpListener() {
public void helpRequested(final HelpEvent e) {
MessageBox msgBox = new MessageBox(shell, SWT.ICON_INFORMATION
| SWT.OK);
msgBox.setText("Help Message");
msgBox.setMessage("Choose this to open a new file");
msgBox.open();
}
});
openMenuItem.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(final SelectionEvent e) {
FileDialog fd = new FileDialog(shell,SWT.OPEN);
fd.open();
}
});
openMenuItem.setText("Open");

final MenuItem exitMenuItem = new MenuItem(fileMenu, SWT.NONE);
exitMenuItem.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(final SelectionEvent e) {
shell.close();
}
});
exitMenuItem.setText("Exit");


Composite容器时SWT控件体系中最基本的容器类型,是其他所有容器类型的父类。
一个Composite容器中可以包含任意多的基本控件或子容器控件,父容器像处理控件一样对子容器发送各种消息,而子容器接受这些消息后,再负责把消息发送给其中的控件。


包含在同一个composite中的radio button默认提供了排他性,最多只能有一个处于被选中状态。可以通过样式NO_RADIO_GROUP改变这一默认的行为。
Composite composite = new Composite(shell,SWT.NO_RADIO_GROUP | SWT.BORDER);
composite.setBounds(10,10,236,158);

final Composite composite_1 = new Composite(composite, SWT.BORDER);
composite_1.setBounds(15, 65, 133, 75);

final Button button = new Button(composite_1, SWT.RADIO);
button.setText("Radio Button");
button.setBounds(15, 5, 116, 25);

final Button button_1 = new Button(composite_1, SWT.RADIO);
button_1.setBounds(15, 36, 112, 25);
button_1.setText("Radio Button");

final Button button_2 = new Button(composite, SWT.RADIO);
button_2.setBounds(5, 20, 99, 25);
button_2.setText("Radio Button");

final Button button_3 = new Button(composite, SWT.RADIO);
button_3.setBounds(110, 20, 116, 25);
button_3.setText("Radio Button");

EMBEDDED样式的用法与其他不同,它是用来显示非SWT控件的(如AWT,SWTING),这中样式的composite在SWT与其他GUI内容中起到了桥梁的作用。


如果有一组相关的控件,它们之间有复杂的相互控制逻辑,而且这组控件在系统中又会被频繁地使用到,推荐的解决方案是创建一个Composite的子类,将这些控件添加进去,例如:
package com.cxm;

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.Composite;
import org.eclipse.swt.widgets.Text;

public class MyControl extends Composite {
private Button button;

private Text text;

private int count = 0;

public MyControl(Composite parent, int style) {
super(parent, style);
setLayout(null);
// 在Composite中创建Text
text = new Text(this, SWT.READ_ONLY | SWT.BORDER);
text.setBounds(5, 5, 50, 20);
text.setText(String.valueOf(count));
// 在Composite中创建Button
button = new Button(this, SWT.NONE);
button.setBounds(60, 5, 50, 20);
button.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(final SelectionEvent e) {
/*
* 当Button被点击时,将计数器增加1, 并将Text的文本设成计数器的值
*/
text.setText(String.valueOf(++count));
}
});
button.setText("button");
}
}


使用上面这个容器和使用其他容器一样(注意:容器的显示根布局管理器有关,如果没设置布局管理器,那么容器就一个要设置setBounds,否则显示出来),例如:
Composite com=new MyControl(shell, SWT.BORDER);

group是composite的直接子类,它为包含在其中的控件提供了默认的边框,并且支持在边框左上角显示一个文本标记。

无论是group容器还是其他容器,都是创建在一个父容器里面,那么必然会有一个顶层容器可以不需要父容器而存在。这个就是shell,虽然shell是composite的子类,但是它只能最为顶层容器存在。


SWT.ON_TOP样式可以附加到任何样式的窗口上,它唯一的作用就是使窗口永远处于用户桌面的最上层,例如:
final Shell shell = new Shell(display,SWT.SHELL_TRIM|SWT.ON_TOP);


shell容器支持5种事件,分别为Activate、Close、Deactivate、Deiconify、Iconify。在一个shell窗口成为活动窗口后,会触发Activate事件,Activate事件可以在窗口被创建出来时触发,也可以在用户的输入焦点落到shell窗口时触发。
当shell窗口被关闭时,触发close事件;
当shell窗口从活动状态变为非活动状态时,会触发Deactivate事件;
当shell窗口从最小化状态恢复时,会触发Deiconify事件;
当shell窗口最小化时,会触发Iconify事件

final Text text = new Text(shell, SWT.READ_ONLY | SWT.MULTI
| SWT.BORDER | SWT.V_SCROLL);
text.setBounds(10, 10, 380, 150);
shell.addShellListener(new ShellListener() {
public void shellActivated(ShellEvent e) {
text.append("Shell has been activated\n");
}

public void shellClosed(ShellEvent e) {
System.out.println("Shell has been closed");
}

public void shellDeactivated(ShellEvent e) {
text.append("Shell has been deactivated\n");
}

public void shellDeiconified(ShellEvent e) {
text.append("Shell has been deiconified\n");
}

public void shellIconified(ShellEvent e) {
text.append("Shell has been iconified\n");
}
});


容器的上下午菜单
指在容器上单击鼠标右键时弹出的菜单,这个菜单的内容通常与当前的位置有关,单击不同的容器,会弹出不同的菜单,因此被称为上下文菜单。

在创建上下文菜单时,首先要以shell为父容器创建一个样式为POP_UP的Menu,然后在调用相关子容器的setMenu方法让该容器和菜单想关联。例如:
Composite container = new Composite(shell, SWT.BORDER);
container.setBounds(10, 10, 80, 80);

Menu menu = new Menu(shell, SWT.POP_UP);
/*
* 在创建Menu的时候,我们也可以直接调用Menu(Control control)的构造函数
* 这个构造函数会自己寻找Control实例最上层的Shell容器, 并以POP_UP为默认style参数调用 Menu(Shell
* shell, int style)的构造函数. 因此上面的构造函数也可以这样写:Menu menu = new
* Menu(container); 效果完全一样,setMenu方法都必须设置
*/
container.setMenu(menu);

MenuItem menuItem1 = new MenuItem(menu, SWT.NONE);
menuItem1.setText("Menu item1");
menuItem1.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent event) {
MessageBox mb = new MessageBox(shell,SWT.ICON_INFORMATION|SWT.OK);
mb.setText("Notification");
mb.setMessage("Item 1 has been selected!");
mb.open();
}
});

MenuItem menuItem2 = new MenuItem(menu, SWT.NONE);
menuItem2.setText("Menu item2");
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值