JAVA.SWT/JFace: SWT中的事件模型/SWT常见的事件/SWT类所代表的事件常量/按键与其对应的常量表、KeyEvent事件比较、VerifyEvent事件比较
2016-06-13 08:37
561 查看
《Eclipse SWT/JFACE 核心应用》 清华大学出版社 8 SWT中的事件模型
8.1 事件模型概述
1. 监听器(Listener)
所谓监听器,也就是接收事件发生的对象,负责处理事件到达后响应事件的代码。监听器对象是一个接口,要响应一个事件就要实现该接口中的方法。监听器类的形式为XXXListener。例如,常用的监听器有选择监听器(SelectionListener)、鼠标监听器(MouseListener)、键盘监听器(KeyListener)等。
一个类型的监听器中有不同的响应事件的方法。例如,SelectionListener中要实现widgetSelected好widgetDefaultSelected两个方法。widgetSelected表示选中事件,对于列表来说,就是单击列表中的一项所调用的方法。但对于按钮来说,就是单击这个按钮所调用的方法。不同控件对事件的发布是不一样的。widgetDefaultSelected事件对列表来说,就是双击列表中的一个事件所调用的方法。所以说同样是选中监听器,单击和双击所触发的事件是不一样的,因此要区别监听器中的方法是响应何种类型的事件。
2. 事件(Event)
当一个事件到达事件监听对象时,要携带一些该事件所附加的一些信息。比如,事件发生的时间,事件由哪些控件发生的等。这些信息都是通过XXXEvent形式来表示的。例如:
public void widgetSelected(SelectionEvent e) {
List i = (List)e.widget;
}
MouseListener对应的事件为MouseEvent,键盘监听器对应的事件为KeyEvent等,每种事件携带的信息稍有不同,但不论什么事件,都可以从事件中获得以下信息:
◆ e.display:事件发生时的Display对象
◆ e.data:保存系统使用的数据,一般不常用。
◆ e.widget:事件发生的控件对象,通常要进行强制的类型转换,因为所有的控件都继承自widget类。
◆ e.time:事件发生时的时间
这是因为所有的XXXEvent类都继承自TypedEvent类。TypedEvent类中的属性就是以上所列举的这些属性。对于具体的某一类型的事件,所携带类型的信息也稍有不同。
3. 注册监听器
注册监听器:addXXXListener(…)
移除监听器:removeXXXListener(…)
4. 适配器
XXXAdapter。适配器可以简化事件处理的代码。
list.addSelectionListener(new SelectionAdapter(){
public void widgetSelected(SelectionEvent e) {
}
});
使用适配器类后,通过覆盖父类中的方法也可以达到与实现Listener接口同样的效果。道理很简单,适配器类只是实现了Listener接口的抽象类。如下所示的是SelectionListener所对应的SelectionAdapter类的源代码:
public abstract class SelectionAdapter implements SelectionListener{
public void widgetSelected(SelectionEvent e){}
public void widgetDefaultSelected(SelectionEvent e){}
}
并不是每个监听器都对应一个适配器类,只有监听器类中响应事件的方法有多个时,才有必要使用监听器类。监听器的实现是选择适配器类还是实现接口的方式要根据不同的情况而定。综上所述,为控件响应事件的方法有以下几个步骤:
(1)创建监听器对象,实现监听器中的方法(XXXListener)。
(2)为控件注册监听器(addXXXListener)。
(3)控件与监听器之间的桥梁是事件对象(XXXEvent)。
(4)对于监听器的接口中有多个事件响应方法的,也可以使用相应的适配器(XXXAdapter),通过覆盖父类中的方法来创建监听器对象。
5. 常见的事件
参考:Java.SWT: SWT常见的事件
8.2 事件处理的常用写法
1. 内部匿名类
适用于对简单的事件处理。如下:
list.addSelectionListener( new SelectionListener() {
// 程序代码
});
内部类
SelectionListener listener = new SelectionListener() {
public void widgetSelected(SelectionEvent e) {
}
public void widgetDefaultSelected(SelectionEvent e) {
}
};
list.addSelectionListener(listener);
list.removeSelectionListener(listener);
实现接口的类
监听器对象本质上是一个接口,就可以利用接口的一般方法来处理。如下:
public class MyListener implements SelectionListener {
public void widgetSelected(SelectionEvent e) {
}
public void widgetDefaultSelected(SelectionEvent e) {
}
}
注册该监听器的对象的代码如下:
Button button = new Button(shell, SWT.NONE);
button.addSelectionListener(new MyListener());
内部类的方法适用于在一个类中处理各种事件,而在实际的项目中往往是将所有的事件集中到一个类中,这样其他类中也能重用该事件处理的代码,所以这种方式在项目中是经常使用的。
继承的类的方法
对应有对应的适配器类,还可以通过继承适配器类,然后覆盖适配器类中的方法来实现。例如:
public class MyAdapter extends SelectionAdapter {
public void widgetSelected(SelectionEvent e) {
}
public void widgetDefaultSelected(SelectionEvent e) {
}
}
Button button = new Button(shell, SWT.NONE);
button.addSelectionListener(new MyAdapter());
通过继承的方式确保该类没有继承自其他类。如果此时该类继承自其他的类,那么只能采用实现接口的方法,如果该类没有继承自其他类,那么两种方法都可以使用。
总的来说,实现接口的方法更具有通用性,但继承的方法有一定局限性,而继承的方法简化了代码量。
8.3 键盘事件
package www.swt.com.ch8;
import org.eclipse.swt.SWT;
public class MovingButton {
public static void main(String[] args) {
Display display = new Display();
Shell shell = new Shell(display);
shell.setText(“可移动的按钮”);
Button button = new Button(shell, SWT.NONE);
button.setBounds(5, 5, 50, 25);
button.setText(“移动我”);
// 注册键盘事件监听器
button.addKeyListener(new KeyListener() {
// 键盘按下后
public void keyPressed(KeyEvent e) {
int bits = SWT.CTRL | SWT.ALT | SWT.SHIFT;
if ((e.stateMask & bits) != 0) {
e.doit = false;// 取消该事件
return;//并返回
}
// 获得触发该事件的控件对象
Control control = (Control) e.widget;
// 获得该控件的位置和大小
Rectangle current = control.getBounds();
if (e.keyCode == SWT.ARROW_DOWN)// 如果按下了“下”按键
current.y++;// 下移一个像素
else if (e.keyCode == SWT.ARROW_UP)// 如果按下了“上”按键
current.y–;// 上移一个像素
else if (e.keyCode == SWT.ARROW_LEFT)// 如果按下了“左”按键
current.x–;// 左移一个像素
else if (e.keyCode == SWT.ARROW_RIGHT)// 如果按下了“右”按键
current.x++;// 右移一个像素
// 重新设置控件的位置
control.setBounds(current);
}
public void keyReleased(KeyEvent e) {
}
});
shell.setSize(200, 150);
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch())
display.sleep();
}
display.dispose();
}
}
8.1 事件模型概述
1. 监听器(Listener)
所谓监听器,也就是接收事件发生的对象,负责处理事件到达后响应事件的代码。监听器对象是一个接口,要响应一个事件就要实现该接口中的方法。监听器类的形式为XXXListener。例如,常用的监听器有选择监听器(SelectionListener)、鼠标监听器(MouseListener)、键盘监听器(KeyListener)等。
一个类型的监听器中有不同的响应事件的方法。例如,SelectionListener中要实现widgetSelected好widgetDefaultSelected两个方法。widgetSelected表示选中事件,对于列表来说,就是单击列表中的一项所调用的方法。但对于按钮来说,就是单击这个按钮所调用的方法。不同控件对事件的发布是不一样的。widgetDefaultSelected事件对列表来说,就是双击列表中的一个事件所调用的方法。所以说同样是选中监听器,单击和双击所触发的事件是不一样的,因此要区别监听器中的方法是响应何种类型的事件。
2. 事件(Event)
当一个事件到达事件监听对象时,要携带一些该事件所附加的一些信息。比如,事件发生的时间,事件由哪些控件发生的等。这些信息都是通过XXXEvent形式来表示的。例如:
public void widgetSelected(SelectionEvent e) {
List i = (List)e.widget;
}
MouseListener对应的事件为MouseEvent,键盘监听器对应的事件为KeyEvent等,每种事件携带的信息稍有不同,但不论什么事件,都可以从事件中获得以下信息:
◆ e.display:事件发生时的Display对象
◆ e.data:保存系统使用的数据,一般不常用。
◆ e.widget:事件发生的控件对象,通常要进行强制的类型转换,因为所有的控件都继承自widget类。
◆ e.time:事件发生时的时间
这是因为所有的XXXEvent类都继承自TypedEvent类。TypedEvent类中的属性就是以上所列举的这些属性。对于具体的某一类型的事件,所携带类型的信息也稍有不同。
3. 注册监听器
注册监听器:addXXXListener(…)
移除监听器:removeXXXListener(…)
4. 适配器
XXXAdapter。适配器可以简化事件处理的代码。
list.addSelectionListener(new SelectionAdapter(){
public void widgetSelected(SelectionEvent e) {
}
});
使用适配器类后,通过覆盖父类中的方法也可以达到与实现Listener接口同样的效果。道理很简单,适配器类只是实现了Listener接口的抽象类。如下所示的是SelectionListener所对应的SelectionAdapter类的源代码:
public abstract class SelectionAdapter implements SelectionListener{
public void widgetSelected(SelectionEvent e){}
public void widgetDefaultSelected(SelectionEvent e){}
}
并不是每个监听器都对应一个适配器类,只有监听器类中响应事件的方法有多个时,才有必要使用监听器类。监听器的实现是选择适配器类还是实现接口的方式要根据不同的情况而定。综上所述,为控件响应事件的方法有以下几个步骤:
(1)创建监听器对象,实现监听器中的方法(XXXListener)。
(2)为控件注册监听器(addXXXListener)。
(3)控件与监听器之间的桥梁是事件对象(XXXEvent)。
(4)对于监听器的接口中有多个事件响应方法的,也可以使用相应的适配器(XXXAdapter),通过覆盖父类中的方法来创建监听器对象。
5. 常见的事件
参考:Java.SWT: SWT常见的事件
8.2 事件处理的常用写法
1. 内部匿名类
适用于对简单的事件处理。如下:
list.addSelectionListener( new SelectionListener() {
// 程序代码
});
内部类
SelectionListener listener = new SelectionListener() {
public void widgetSelected(SelectionEvent e) {
}
public void widgetDefaultSelected(SelectionEvent e) {
}
};
list.addSelectionListener(listener);
list.removeSelectionListener(listener);
实现接口的类
监听器对象本质上是一个接口,就可以利用接口的一般方法来处理。如下:
public class MyListener implements SelectionListener {
public void widgetSelected(SelectionEvent e) {
}
public void widgetDefaultSelected(SelectionEvent e) {
}
}
注册该监听器的对象的代码如下:
Button button = new Button(shell, SWT.NONE);
button.addSelectionListener(new MyListener());
内部类的方法适用于在一个类中处理各种事件,而在实际的项目中往往是将所有的事件集中到一个类中,这样其他类中也能重用该事件处理的代码,所以这种方式在项目中是经常使用的。
继承的类的方法
对应有对应的适配器类,还可以通过继承适配器类,然后覆盖适配器类中的方法来实现。例如:
public class MyAdapter extends SelectionAdapter {
public void widgetSelected(SelectionEvent e) {
}
public void widgetDefaultSelected(SelectionEvent e) {
}
}
Button button = new Button(shell, SWT.NONE);
button.addSelectionListener(new MyAdapter());
通过继承的方式确保该类没有继承自其他类。如果此时该类继承自其他的类,那么只能采用实现接口的方法,如果该类没有继承自其他类,那么两种方法都可以使用。
总的来说,实现接口的方法更具有通用性,但继承的方法有一定局限性,而继承的方法简化了代码量。
8.3 键盘事件
package www.swt.com.ch8;
import org.eclipse.swt.SWT;
public class MovingButton {
public static void main(String[] args) {
Display display = new Display();
Shell shell = new Shell(display);
shell.setText(“可移动的按钮”);
Button button = new Button(shell, SWT.NONE);
button.setBounds(5, 5, 50, 25);
button.setText(“移动我”);
// 注册键盘事件监听器
button.addKeyListener(new KeyListener() {
// 键盘按下后
public void keyPressed(KeyEvent e) {
int bits = SWT.CTRL | SWT.ALT | SWT.SHIFT;
if ((e.stateMask & bits) != 0) {
e.doit = false;// 取消该事件
return;//并返回
}
// 获得触发该事件的控件对象
Control control = (Control) e.widget;
// 获得该控件的位置和大小
Rectangle current = control.getBounds();
if (e.keyCode == SWT.ARROW_DOWN)// 如果按下了“下”按键
current.y++;// 下移一个像素
else if (e.keyCode == SWT.ARROW_UP)// 如果按下了“上”按键
current.y–;// 上移一个像素
else if (e.keyCode == SWT.ARROW_LEFT)// 如果按下了“左”按键
current.x–;// 左移一个像素
else if (e.keyCode == SWT.ARROW_RIGHT)// 如果按下了“右”按键
current.x++;// 右移一个像素
// 重新设置控件的位置
control.setBounds(current);
}
public void keyReleased(KeyEvent e) {
}
});
shell.setSize(200, 150);
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch())
display.sleep();
}
display.dispose();
}
}
相关文章推荐
- GEF 和 eclipse 视图对象
- eclipse 查询结果 在新窗口中打开
- java中堆和栈的区别,递归和迭代的区别
- JAVA中calendar,date,string 的相互转换和详细用法
- struts2 action以及页面跳转
- 当我们说线程安全时,到底在说什么——Java进阶系列(二)
- Dubbo分布式服务+Springmvc容器+Maven项目整合,分布式,kakfka消息中间件整合
- 当我们说线程安全时,到底在说什么——Java进阶系列(二)
- org.xml.sax.SAXParseException: Failed to read schema document错误的完美解决方法 以及 Spring如何加载XSD文件
- 16_AOP入门准备_Jdk动态代理模式
- org.springframework.dao.DataIntegrityViolationException: Data truncation: Data too long for column '
- java实现裴波那契堆
- 浅谈附属类,内部类,匿名内部类,静态内部类
- RxJava操作符(03-变换操作)
- RxJava操作符(03-变换操作)
- 线程执行器
- 关于Java中的final
- 梳理struts2-面试题
- 在Eclipse下使用Maven创建SpringMVC样例项目
- JAVA运行时数据区域