论坛首页 编程语言技术论坛

深入JAVA事件触发二

浏览 1250 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2013-11-05  
<pre name="code" class="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
//同时EventTable也是使用数组实现的先进先出队列。
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 &gt;= 0) {
if (types [index] != 0) break;
--index;
}
//找到下一个需要入队的位置
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;
}</pre>




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

跳转论坛:
Global site tag (gtag.js) - Google Analytics