阅读本文需要知道搭建swt的开发环境,对SWT有基本的了解,最好对Windows api也有所了解,还要稍微了解一下JNI。
HelloSWT是一个基本的SWT程序,当点击输入框的时候,会弹出一个MessageBox。
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
class HelloSWT {
public static void main(String[] args) {
Display display = new Display();// 创建一个display对象。
final Shell shell = new Shell(display);// shell是程序的主窗体
shell.setLayout(null); // 设置shell的布局方式
Text hello = new Text(shell, SWT.MULTI); // 声明一个可以显示多行信息的文本框
shell.setText("Java应用程序"); // 设置主窗体的标题
shell.setSize(200, 100); // 设置主窗体的大小
Color color = new Color(Display.getCurrent(), 255, 255, 255);// 声明颜色对象
shell.setBackground(color); // 设置窗体的背景颜色
hello.setText("Hello, SWT World!\n\n你好,SWT世界!");// 设置文本框信息
hello.pack(); // 自动调整文本框的大小
shell.pack(); //自动调整主窗体的大小
shell.open(); // 打开主窗体
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
}
});
while (!shell.isDisposed()) { // 如果主窗体没有关闭则一直循环
if (!display.readAndDispatch()) { // 如果display不忙
display.sleep(); // 休眠
}
}
display.dispose(); // 销毁display
}
}
运行效果:
这个程序也是我们分析SWT运行的一个介入点。程序中为hello这个Text增加了鼠标事件的监听器,在 MessageBox box = new MessageBox(shell);这一行加上一个断点,因为可以肯定,在点击鼠标时,会执行这段代码,可以通过断点观察出前后程序执行的顺序。当在Text上点击鼠标时,会在断点处暂停,此时运行的上下文为:
从这里就可以看出程序的执行过程了,先从main方法开始,HelloSWT的51行为 if (!display.readAndDispatch()):
while (!shell.isDisposed()) { // 如果主窗体没有关闭则一直循环
if (!display.readAndDispatch()) { // 如果display不忙
display.sleep(); // 休眠
}
}
display.dispose(); // 销毁display
readAndDispatch方法在API中的说明为:
Reads an event from the operating system's event queue, dispatches it
appropriately, and returns true
if there is potentially more work
to do, or false
if the caller can sleep until another event is
placed on the event queue.
In addition to checking the system event queue, this method also checks if
any inter-thread messages (created by syncExec()
or
asyncExec()
) are waiting to be processed, and if so handles them
before returning.
从操作系统的事件队列里面读取一个事件,并做适当的分发,返回true时表示有工作要做,返回false表示没有接受到事件。...
当点击鼠标时,程序接收到相应的事件,readAndDispatch()就会返回true。
readAndDispatch的实现为:
public boolean readAndDispatch () {
checkDevice ();
lpStartupInfo = null;
drawMenuBars ();
runSkin ();
runDeferredLayouts ();
runPopups ();
if (OS.PeekMessage (msg, 0, 0, 0, OS.PM_REMOVE)) {
if (!filterMessage (msg)) {
OS.TranslateMessage (msg);
OS.DispatchMessage (msg);
}
runDeferredEvents ();
return true;
}
return isDisposed () || (runMessages && runAsyncMessages (false));
}
方法开始调用了一些其他函数,从名称上来看是做了一些检查和界面显示、菜单的相关操作,我们现在不关心这些,重点看这里:
if (OS.PeekMessage (msg, 0, 0, 0, OS.PM_REMOVE)) {
if (!filterMessage (msg)) {
OS.TranslateMessage (msg);
OS.DispatchMessage (msg);
}
runDeferredEvents ();
return true;
}
这里出现一个OS类,OS类是SWT内部的一个类,里面定义了很多native方法,我们知道SWT底层通过JNI调用了很多本地的windows api,所以程序的界面和本地的windows程序几乎是一样的,而Swing做出来的界面和具体的平台没关系,和一般的windows程序风格不一样,总是让人感觉不习惯。
OS类如下:
public class OS extends C {
static {
Library.loadLibrary ("swt"); //$NON-NLS-1$
}
......
可见OS类中通过Library.loadLibrary ("swt")加载本地的dll,可以继续进入loafLibrary方法内部,最后得知
加载的是swt-win32-xxxx.dll 。xxxx是eclipse的版本号。在我的机器上是swt-win32-3650.dll。这个dll在eclipse安装目录下的plugins目录中的org.eclipse.swt.win32.win32.x86_3.6.0.v3650b.jar中。还有一个org.eclipse.swt.win32.win32.x86.source_3.6.0.v3650b.jar,里面是swt的源码。解压这个源码的jar之后,可以看到一个os.c文件,我猜测,OS类的native方法的实现就是在os.c中,并没有去验证。
os.c 的部分代码:
#include "swt.h"
#include "os_structs.h"
#include "os_stats.h"
#define OS_NATIVE(func) Java_org_eclipse_swt_internal_win32_OS_##func
......
#ifndef NO_PeekMessageA
JNIEXPORT jboolean JNICALL OS_NATIVE(PeekMessageA)
(JNIEnv *env, jclass that, jobject arg0, jintLong arg1, jint arg2, jint arg3, jint arg4)
{
MSG _arg0, *lparg0=NULL;
jboolean rc = 0;
OS_NATIVE_ENTER(env, that, PeekMessageA_FUNC);
if (arg0) if ((lparg0 = getMSGFields(env, arg0, &_arg0)) == NULL) goto fail;
rc = (jboolean)PeekMessageA(lparg0, (HWND)arg1, arg2, arg3, arg4);
fail:
if (arg0 && lparg0) setMSGFields(env, arg0, lparg0);
OS_NATIVE_EXIT(env, that, PeekMessageA_FUNC);
return rc;
}
#endif
不同函数的定义都是类似:
JNIEXPORT jboolean JNICALL OS_NATIVE(PeekMessageA)
(JNIEnv *env, jclass that, jobject arg0, jintLong arg1, jint arg2, jint arg3, jint arg4)
其中OS_NATIVE是一个宏,以上函数实际的定义为:
JNIEXPORT jboolean JNICALL Java_org_eclipse_swt_internal_win32_OS_PeekMessageA
(JNIEnv *env, jclass that, jobject arg0, jintLong arg1, jint arg2, jint arg3, jint arg4)
函数名为 :java中的包名_类名_方法名。这种格式是JNI要求的。
现在知道了,SWT调用OS类的static native方法就相当于直接调用了Windows SDK Api。
回到Display类中,OS.PeekMessage的作用是从系统的消息队列取消息,如果取到了消息就返回true。
OS.TranslateMessage (msg);将消息进行一些转化。
OS.DispatchMessage (msg);将消息发送给相应的窗口。
这几个都是windows api 函数,不清楚也不要紧,这些是每个windows程序都有的,后面我会贴出一个最简单的
windows c程序。
随后是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;
}
作用是从SWT的 eventQuene中取出一个事件(事件是怎么放入到eventQueue中的呢?后面说),找到事件对应的控件,让这个控件去处理这个事件。
到现在分析到前面断点那个图的第三步,后面的过程会继续分析。
未完待续。
- 大小: 16.4 KB
- 大小: 5.8 KB
分享到:
相关推荐
SWT源码的获取和分析对于开发者来说非常有价值,因为它可以深入理解其工作原理,自定义组件或优化应用程序。 "swt.jar"文件是SWT库的二进制版本,包含了运行SWT应用所需的类和资源。这个jar包通常会被Java项目引用...
在学习这个图书馆管理系统SWT源码的过程中,我们不仅可以掌握SWT的基本用法,还能了解到如何设计和实现一个完整的管理系统的流程,包括数据库操作、事件监听、界面布局等多个方面。同时,通过实际项目的实践,可以...
5. **源码分析与使用**: 源码中可能包含了如何初始化和控制SWT_Browser实例,如何加载和导航网页,以及如何处理JavaScript与Java之间的交互的示例代码。开发者可以通过学习和理解这些源码,了解如何在自己的项目中...
**源码分析** SWT 的源码是用Java编写的,通过JNI(Java Native Interface)与操作系统底层交互。通过阅读源码,开发者可以深入理解SWT的工作原理,学习如何与本地系统进行通信,以及如何优化GUI性能。源码中包含了...
源代码对于学习和理解SWT和JFace的工作原理极其有用,开发者可以通过阅读源码学习如何使用这些库,或者进行二次开发。 6. `about_files`:这个目录可能包含了Eclipse关于对话框显示的其他资源文件,如图标、语言...
通过分析这些源代码,开发者可以了解SWT如何与操作系统进行底层交互,实现高效、原生的GUI效果。这对于希望优化SWT性能、定制特定功能或者学习GUI编程原理的开发者来说,是非常宝贵的资料。如果你对SWT感兴趣,那么...
Java SWT(Standard Widget Toolkit)是Java编程环境中...通过学习和分析这个源码,你可以深入理解Java SWT的用法,以及如何结合算法实现一个完整的桌面应用程序。此外,对于游戏设计和用户交互也有一定的学习价值。
Kettle 4.4.2源码分析 Kettle 是一款功能强大且流行的数据 Integrator 工具,它提供了多种数据处理和Integration 功能。本文档将对 Kettle 4.4.2 的源码进行分析,从源码获取和编译到修改 Kettle 界面和启动测试等...
掌握它们的使用和源码分析能力,对于提升 Java GUI 开发技能和参与 Eclipse RCP 应用的开发具有重要意义。通过深入研究提供的源码,开发者可以更好地优化自己的代码,实现更加高效和用户友好的界面。
5. **源码分析**:在提供的压缩包中,`com.cxd.zxsj`、`com.cxd.zxsj.feature`和`com.cxd.zxsj.update`可能分别代表了项目的主代码包、功能描述文件和更新相关配置。`com.cxd.zxsj`可能是应用程序的主要代码结构,...
博客链接中的内容可能涉及对SWT源码的分析。SWT作为一个开源项目,其源码对于开发者来说是一个宝贵的资源,可以深入理解其内部工作机制,学习如何与操作系统进行交互,以及如何优化GUI性能。通过阅读源码,开发者...
通过分析这些源码,开发者可以学习到如何实际应用 SWT 和 JFace 创建高效、美观的 GUI 应用。例如,Chapter09可能介绍了布局管理,包括如何使用GridLayout、FillLayout等;Chapter13可能涉及事件处理和监听器;...
SWT(Standard Widget Toolkit)是Java中用于构建桌面应用程序的一个开源GUI库,它是Eclipse开发平台的基础。在SWT中,Tree组件用于展示层次结构的数据,类似于Windows资源管理器中的文件系统视图。本教程将通过一个...
源码分析** 对于SWT的深入学习,阅读源码是一个有效的途径。了解SWT如何与操作系统进行交互,以及如何实现各种控件和功能,可以帮助开发者更好地优化应用性能,解决特定问题。 在实际项目中,SWT常用于开发桌面...
通过分析和运行这些代码,你可以深入理解SWT的API和组件使用方式,以及如何将它们整合到Java应用程序中。 SWT提供了一系列的控件,包括按钮、文本框、列表、树、表格等,这些都可以用来构建各种复杂的用户界面。...
JAVA SWT 多标签浏览器是一种利用Java编程语言和SWT(Standard Widget Toolkit)库构建...通过分析源码,开发者可以学习到如何利用SWT创建原生外观的应用,以及如何实现复杂的用户交互功能,比如多标签导航和书签管理。
标题中的“以SWT为界面,用POI读取、修改excel文件(源码)”指的是一个Java编程项目,它利用了两种主要的技术:SWT(Standard Widget Toolkit)和Apache POI,来创建用户界面并处理Microsoft Excel文件。下面将详细...
7. **源码阅读**:了解SWT源码有助于深入理解其工作机制,解决性能问题或自定义组件。 8. **开发工具**:Eclipse是主要的SWT开发环境,提供代码补全、调试、布局编辑等功能。除此之外,还有SWTBot用于自动化测试,...
Kettle4.1 是该工具的一个版本,其源码分析有助于深入理解其内部工作原理,便于自定义开发或优化。 在开始源码分析之前,首先需要获取和编译 Kettle4.1 的源码。这可以通过 SVN 从官方仓库中下载,网址为 svn://...