`

深入JAVA事件触发二

 
阅读更多
接着上一篇的介绍,本文重点介绍当我们向一个控件添加监听器的主要过程和相应源码解析。
本文以向一个Button按钮添加listener为例。详细介绍listener是如何存储的。

		
Button b = new Button(shell, SWT.CENTER);
b.setText("I am Button");
b.addSelectionListener(new SelectionListener() {
	
	@Override
	public void widgetSelected(SelectionEvent e) {
		System.out.println("widgetSelected------------");
		
	}
	
	@Override
	public void widgetDefaultSelected(SelectionEvent e) {
		// TODO Auto-generated method stub
		System.out.println("widgetDefaultSelected----------");
	}
});


//Button类的addSelectionListener方法

public void addSelectionListener (SelectionListener listener) {
	checkWidget ();//检查当前控件的Display对象是否为空,当前线程是否为创建该控件的线程
	//如果listener为空,抛出IllegalArgumentException异常
	if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
	//封装为SWT内部的TypedListener对象,用来区别有类型的listener和无类型的listener。
	TypedListener typedListener = new TypedListener (listener);
	addListener (SWT.Selection,typedListener);//Widget的addListener方法
	addListener (SWT.DefaultSelection,typedListener);//Widget的addListener方法
}


//Widget的addListener方法
public void addListener (int eventType, Listener listener) {
	checkWidget ();
	if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
	_addListener (eventType, listener);
}
////Widget内部的_addListener方法,注意包访问权限,包外无法访问。
void _addListener (int eventType, Listener listener) {
	if (eventTable == null) eventTable = new EventTable ();
	eventTable.hook (eventType, listener);
}

//EventTable的hook方法
//EventTable使用数组存储listener类型和listener对象,GROW_SIZE为数组增量大小4

public void hook (int eventType, Listener listener) {
	if (types == null) types = new int [GROW_SIZE];
	if (listeners == null) listeners = new Listener [GROW_SIZE];
	int length = types.length, index = length - 1;//数组最后一个元素下标
	//从后向前找到数组中最后一个非空位置,那么下一个位置为空
	while (index >= 0) {
		if (types [index] != 0) break;
		--index;
	}
	//找到下一个空位置放入listener
	index++;
	//如果数组已满,对数组进行扩充,size+4
	if (index == length) {
		int [] newTypes = new int [length + GROW_SIZE];
		System.arraycopy (types, 0, newTypes, 0, length);
		types = newTypes;
		Listener [] newListeners = new Listener [length + GROW_SIZE];
		System.arraycopy (listeners, 0, newListeners, 0, length);
		listeners = newListeners;
	}
	types [index] = eventType;//将listener加入数组中
	listeners [index] = listener;
}





总结:(1)对于数组的复制,建议使用System.arraycopy,当然二维数组的复制一定要小心,二维数组复制的是内部数组的引用。
一个详细讲解System.arraycopy的文章:http://xiaooman07.iteye.com/blog/451843
(2)SWT抛出异常的机制是通过错误代码(error code)找到对应的message字符串,将message封装为exception并抛出。
分享到:
评论

相关推荐

    深入Java Servlet网络编程

    9. 2 触发Servlet链 第10章 服务器端包含 10. 1 服务器端包含的编写 10. 2 服务器端包含的参数传递 10. 3 服务器端包含的实例 第11章 Applet和Servlet通信 11. 1 Applet和Servlet通信概述 11. 2 Applet和...

    深入理解_Java_虚拟机 JVM_高级特性与最佳实践

    前 言 致 谢 第一部分 走近Java 第1章 走近Java / 2 1.1 概述 / 2 1.2 Java技术体系 / 3 1.3 Java发展史 / 5 1.4 展望Java技术的未来 / 9 1.4.1 模块化 / 9 1.4.2 混合语言 / 9 1.4.3 多核并行 / 11 ...

    计算器--Java程序

    面向初学Java程序设计的人群,通过AWT完成的一个计算器程序。通过这个程序可以将Java的事件触发过程进行深入的了解。

    Handler机制及原理探究.pdf

    Handler使用简单功能强大,常被用作线程间传递消息的组件,而且还可以用于跨进程。 消息机制背后有包括Looper ,MessageQueue管理和分发消息的实现,...这里从Java层开始深入探究下Handler和消息机制背后实现的原理

    Java虚拟机

    第2章 Java内存区域与内存溢出异常 2.1 概述 2.2 运行时数据区域 2.2.1 程序计数器 2.2.2 Java虚拟机栈 2.2.3 本地方法栈 2.2.4 Java堆 2.2.5 方法区 2.2.6 运行时常量池 2.2.7 直接内存 2.3 HotSpot...

    封装一套简单易于使用的流式异步通信框架,追求易于理解,方便使用.rar

    具体通信流程 1.客户端连接服务端,服务端通过Selector接收到连接请求,将其socketChannel通道保存到通道集合,并触发客户端连接事件 2.客户端发送数据包请求到服务端,服务端将...若要深入了解,请先了解Java NIO技术

    Java 虚拟机面试题全面解析(干货)

    Java 虚拟机面试题全面解析,《深入理解Java虚拟机》干货版,自己总结,希望能够帮助大家,免费下载~什么是类加载机制? 虚拟机和物理机的区别是什么? 运行时栈帧结构 Java方法调用 什么是方法调用? Java的方法调用,...

    深入理解javaScript中的事件驱动

    ) 通常用于如下控件:button 按钮对象checkbox 复选框或检查列表 –配合onclick单击事件,通常用于全选效果radio 单选按纽reset 重置按钮submit提交按钮 2、内容改变事件 onchange 如:(<input type=”text” ...

    臂架::building_construction:为Java应用程序构建容器映像

    Jib无需Docker守护程序即可为Java应用程序构建优化的Docker和映像-无需深入掌握Docker最佳实践。 它可以作为和插件以及Java库使用。 :请参阅文档 。 :请参阅文档 。 :Java的通用容器构建库。 :使用Jib Core构建...

    Jib:容器化您的Java应用程序-开源

    Jib为您的Java应用程序构建了优化的Docker和OCI映像-无需Docker守护程序或对Docker最佳实践的深入了解。 Jib的构建是通过将传统的单个图像层Java应用程序分成多层,以获得更细致的增量构建。 这样只会导致对要重建...

    Spring AOP源码深度解析:掌握Java高级编程核心技术

    Spring AOP(面向切面编程)是Java高级编程中的重要组成部分,它允许程序员以声明的方式处理关注点(例如日志、事务管理等),而不是通过硬编码。本文深入分析了Spring AOP的实现机制,让读者能够更好地理解和应用这...

    分布式专题-04分布式协调服务之Zookeeper实践及与原理分析

    事务的实现原理深入分析Watcher机制的实现原理ClientCnxn 初始化客户端通过 exists 注册监听cnxn.submitRequestSendThread 的发送过程client 和 server 的网络交互服务端接收请求处理流程处理客户端传送过来的数据包...

    java简易版开心农场源码-DE-Grid:德格

    java简易版开心农场源码 结构说明 设计概要 Meteor-0.8.0的很多东西都是比较新的,对于我来说,是一个比较大的挑战。但是这个新版本同时又是比较诱人的,其中很多功能上的细节让编程变的更加灵活,同时性能上也得到...

    JavaScript基础教程第8版

    1.2 JavaScript不是Java 2 1.3 JavaScript的起源 3 1.4 JavaScript可以做什么 3 1.5 JavaScript不能做什么 3 1.6 Ajax是什么 4 1.7 组合式(snap-together)语言 5 1.7.1 对象 5 1.7.2 属性 6 1.7.3 ...

    jib::building_construction:为Java应用程序构建容器映像

    Jib无需Docker守护程序即可为Java应用程序构建优化的Docker和映像-无需深入掌握Docker最佳实践。 它可以作为和插件以及Java库使用。 :请参阅有关文档。 :请参阅有关文档。 :Java的通用容器构建库。 :使用Jib ...

    嵌入式系统/ARM技术中的深入浅出:什么是基于Java的责任链模式

    一、引言  初看责任链模式,心里不禁想起了一个...当一个请求触发后,请求将在这些对象组成的链条中传递,直到找到最合适的“责任”对象,并进行处理。  《设计模式》中给它的定义如下:使多个对象都有机会处理请

    ARM Cortex-A8和Android 4.x联动报警系统

    第一部分课程从最基础的Android应用开发环境搭建开始,简单讲解了Android界面及事件处理之后,深入剖析Android Handler多线程机制,重点讲解Android NDK应用层与驱动的通信; 第二部分内容,先简单讲解Android系统...

    javascript结合Cookies实现浏览记录历史第1/3页

    由于以前对javascript了解不够深入,一时间手足无措。 后来经过两位高手同事的指点(对这两位同事的敬仰犹如滔滔江水连绵不绝…),恍然大悟,豁然开朗 成功地完成了此功能的添加。 首先来介绍一下javascript中关于...

    JSTL详细标签库介绍

    <!...<HTML><HEAD>关于java异常处理(讲义)--JSP中文网 ...第二步:处理对象与方法:声明4个GUI组件对象和1个用于存储计算结果(double)的和2个被除数与除数基本类型(int)<BR><BR>A、 初始化对象方法init()<BR>B...

    Android高级编程.pdf

    第2章 开始入手 2.1 Android开发 2.1.1 开始前的准备工作 2.1.2 创建第一个Android活动 2.1.3 Android应用程序的类型 2.2 面向移动设备的开发 2.2.1 关于硬件设计的考虑事项 2.2.2 考虑用户环境 2.2.3 Android开发 ...

Global site tag (gtag.js) - Google Analytics