继续上次的。
上次程序中的部分代码:
Text hello = new Text(shell, SWT.MULTI); hello.addMouseListener(new MouseListener() { @Override public void mouseUp(MouseEvent e) { // TODO Auto-generated method stub MessageBox box = new MessageBox(shell); box.setMessage("内容"); box.setText("标题"); box.open(); } @Override public void mouseDown(MouseEvent e) { // TODO Auto-generated method stub } @Override public void mouseDoubleClick(MouseEvent e) { // TODO Auto-generated method stub } });
在Swing中也是这样,如果我们想对某个控件的事件进行相应,就在这个控件上加上一些listener。在listener中写具体的操作。按住Ctrl进入addMouseListener方法中:
public void addMouseListener (MouseListener listener) { checkWidget (); if (listener == null) error (SWT.ERROR_NULL_ARGUMENT); TypedListener typedListener = new TypedListener (listener); addListener (SWT.MouseDown,typedListener); addListener (SWT.MouseUp,typedListener); addListener (SWT.MouseDoubleClick,typedListener); }
这里创建了一个TypedListener 对象,然后将我们自定义的listener放入个eventListener 中:
public TypedListener (SWTEventListener listener) { eventListener = listener; }
可知AddMouseListener是Controll类中的方法,方法中有调用了Widget类中的addListener方法:
public void addListener (int eventType, Listener listener) { checkWidget(); if (listener == null) error (SWT.ERROR_NULL_ARGUMENT); _addListener (eventType, listener); }
addListener方法中又调用了本类中的_addListener方法:
void _addListener (int eventType, Listener listener) { if (eventTable == null) eventTable = new EventTable (); eventTable.hook (eventType, listener); }
可见,最后的操作是调用hook函数把事件类型和监听器listener放入了一个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 >= 0) { if (types [index] != 0) break; --index; } index++; 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; listeners [index] = listener; }
hook函数中前面是一些判断,确定本次要放入的index是最后一个放入的事件之后加1的位置,如果是数组的最后一个index,会扩充现有的数组,最后把事件类型和listener放入对应数组。
SWT的控件继承关系如下:
可见,本例子中的Text是Widget和子类,Text对象中也必然有一个eventTable。
恩,现在我已经知道了每当一个控件调用addXXXListener时,就是往自己的eventTable中注册了要监听的事件和对应的操作。
现在回到上一篇文章中停留的地方-----runDeferredEvents 方法:
boolean runDeferredEvents () { boolean run = false; /* * Run deferred events. This code is always * called in the Display's thread so it must * be re-enterant but need not be synchronized. */ while (eventQueue != null) { /* Take an event off the queue */ Event event = eventQueue [0]; if (event == null) break; int length = eventQueue.length; System.arraycopy (eventQueue, 1, eventQueue, 0, --length); eventQueue [length] = null; /* Run the event */ Widget widget = event.widget; if (widget != null && !widget.isDisposed ()) { Widget item = event.item; if (item == null || !item.isDisposed ()) { run = true; widget.sendEvent (event); } } /* * At this point, the event queue could * be null due to a recursive invocation * when running the event. */ } /* Clear the queue */ eventQueue = null; return run; }
在得到了event之后,会调用对应widget中的sendEvent方法,本程序中的widget就是Text。sendEvent 方法如下:
void sendEvent (Event event) { Display display = event.display; if (!display.filterEvent (event)) { if (eventTable != null) eventTable.sendEvent (event); } }
可见调用的是eventTable中的sendEvent方法:
public void sendEvent (Event event) { if (types == null) return; level += level >= 0 ? 1 : -1; try { for (int i=0; i<types.length; i++) { if (event.type == SWT.None) return; if (types [i] == event.type) { Listener listener = listeners [i]; if (listener != null) listener.handleEvent (event); } } } finally { boolean compact = level < 0; level -= level >= 0 ? 1 : -1; if (compact && level == 0) { int index = 0; for (int i=0; i<types.length; i++) { if (types [i] != 0) { types [index] = types [i]; listeners [index] = listeners [i]; index++; } } for (int i=index; i<types.length; i++) { types [i] = 0; listeners [i] = null; } } } }
其中的关键代码是:
if (types [i] == event.type) { Listener listener = listeners [i]; if (listener != null) listener.handleEvent (event); }
遍历eventTable,找到对应事件的listener,然后调用listener中的HandleEvent方法,方法的具体实现就在一开头见过的TypedListener中:
public void handleEvent (Event e) { switch (e.type) { ...... case SWT.MouseDown: { ((MouseListener) eventListener).mouseDown(new MouseEvent(e)); break; } case SWT.MouseDoubleClick: { ((MouseListener) eventListener).mouseDoubleClick(new MouseEvent(e)); break; } case SWT.MouseUp: { ((MouseListener) eventListener).mouseUp(new MouseEvent(e)); break; } case SWT.Move: { ((ControlListener) eventListener).controlMoved(new ControlEvent(e)); break; } case SWT.Paint: { /* Fields set by Control */ PaintEvent event = new PaintEvent (e); ((PaintListener) eventListener).paintControl (event); e.gc = event.gc; break; } ...... } }
switch里面的case语句很多,省略了一些。可见对于本程序中的mouseup事件,将一开始创建TypedListener传入的listener,又强制转换为了MouseListener,最后调用程序中定义的mouseup方法,调用程序员写的实际逻辑。
到此为止,对于这个基本的SWT程序,从头到尾的执行流程我们已经有了初步的认识!
未完待续。
相关推荐
SWT源码的获取和分析对于开发者来说非常有价值,因为它可以深入理解其工作原理,自定义组件或优化应用程序。 "swt.jar"文件是SWT库的二进制版本,包含了运行SWT应用所需的类和资源。这个jar包通常会被Java项目引用...
《图书馆管理系统SWT源码详解》 在信息技术领域,开发高效、用户友好的管理软件是提升工作效率的关键。本文将深入探讨一个特别的案例——“图书馆管理系统”,该系统采用SWT(Standard Widget Toolkit)进行设计,...
**源码分析** SWT 的源码是用Java编写的,通过JNI(Java Native Interface)与操作系统底层交互。通过阅读源码,开发者可以深入理解SWT的工作原理,学习如何与本地系统进行通信,以及如何优化GUI性能。源码中包含了...
5. **源码分析与使用**: 源码中可能包含了如何初始化和控制SWT_Browser实例,如何加载和导航网页,以及如何处理JavaScript与Java之间的交互的示例代码。开发者可以通过学习和理解这些源码,了解如何在自己的项目中...
源代码对于学习和理解SWT和JFace的工作原理极其有用,开发者可以通过阅读源码学习如何使用这些库,或者进行二次开发。 6. `about_files`:这个目录可能包含了Eclipse关于对话框显示的其他资源文件,如图标、语言...
Kettle 4.4.2源码分析 Kettle 是一款功能强大且流行的数据 Integrator 工具,它提供了多种数据处理和Integration 功能。本文档将对 Kettle 4.4.2 的源码进行分析,从源码获取和编译到修改 Kettle 界面和启动测试等...
通过分析这些源代码,开发者可以了解SWT如何与操作系统进行底层交互,实现高效、原生的GUI效果。这对于希望优化SWT性能、定制特定功能或者学习GUI编程原理的开发者来说,是非常宝贵的资料。如果你对SWT感兴趣,那么...
Java SWT(Standard Widget Toolkit)是Java编程环境中...通过学习和分析这个源码,你可以深入理解Java SWT的用法,以及如何结合算法实现一个完整的桌面应用程序。此外,对于游戏设计和用户交互也有一定的学习价值。
掌握它们的使用和源码分析能力,对于提升 Java GUI 开发技能和参与 Eclipse RCP 应用的开发具有重要意义。通过深入研究提供的源码,开发者可以更好地优化自己的代码,实现更加高效和用户友好的界面。
5. **源码分析**:在提供的压缩包中,`com.cxd.zxsj`、`com.cxd.zxsj.feature`和`com.cxd.zxsj.update`可能分别代表了项目的主代码包、功能描述文件和更新相关配置。`com.cxd.zxsj`可能是应用程序的主要代码结构,...
通过分析这些源码,开发者可以学习到如何实际应用 SWT 和 JFace 创建高效、美观的 GUI 应用。例如,Chapter09可能介绍了布局管理,包括如何使用GridLayout、FillLayout等;Chapter13可能涉及事件处理和监听器;...
首先,我们来分析给定的文件列表: 1. `otree.css`: 这个文件是CSS样式表,用于定义SWT Tree的外观和布局,如字体、颜色、边框等。在创建树形结构时,可以利用CSS定制节点的样式,使其更具视觉吸引力。 2. `otree....
源码分析** 对于SWT的深入学习,阅读源码是一个有效的途径。了解SWT如何与操作系统进行交互,以及如何实现各种控件和功能,可以帮助开发者更好地优化应用性能,解决特定问题。 在实际项目中,SWT常用于开发桌面...
7. **源码阅读**:了解SWT源码有助于深入理解其工作机制,解决性能问题或自定义组件。 8. **开发工具**:Eclipse是主要的SWT开发环境,提供代码补全、调试、布局编辑等功能。除此之外,还有SWTBot用于自动化测试,...
博客链接中的内容可能涉及对SWT源码的分析。SWT作为一个开源项目,其源码对于开发者来说是一个宝贵的资源,可以深入理解其内部工作机制,学习如何与操作系统进行交互,以及如何优化GUI性能。通过阅读源码,开发者...
通过分析和运行这些代码,你可以深入理解SWT的API和组件使用方式,以及如何将它们整合到Java应用程序中。 SWT提供了一系列的控件,包括按钮、文本框、列表、树、表格等,这些都可以用来构建各种复杂的用户界面。...
Kettle4.1 是该工具的一个版本,其源码分析有助于深入理解其内部工作原理,便于自定义开发或优化。 在开始源码分析之前,首先需要获取和编译 Kettle4.1 的源码。这可以通过 SVN 从官方仓库中下载,网址为 svn://...
JAVA SWT 多标签浏览器是一种利用Java编程语言和SWT(Standard Widget Toolkit)库构建...通过分析源码,开发者可以学习到如何利用SWT创建原生外观的应用,以及如何实现复杂的用户交互功能,比如多标签导航和书签管理。
标题中的“以SWT为界面,用POI读取、修改excel文件(源码)”指的是一个Java编程项目,它利用了两种主要的技术:SWT(Standard Widget Toolkit)和Apache POI,来创建用户界面并处理Microsoft Excel文件。下面将详细...