Java桌面应用程序设计:SWT简介
发布时间:2025-05-23 07:12:01 发布人:远客网络
一、Java桌面应用程序设计:SWT简介
1、Java语言的声望和它在桌面应用程序(GUI程序)所取得的成就显然极不相符至今仍然很少能看到非常成功Java桌面程序虽然有JBuilder Netbean JProbe等大型软件作为代表但这仍不能证明Java的GUI程序是成功的它们的外观总是和同一操作系统平台下的其它软件显得格格不入对机器配置的需求也似乎永无止境这使得它们只能被一些总是拥有当前最高性能PC的程序员们所容忍或是那些不在乎金钱和时间的专业用户所接受对绝大多数计算机使用者来说 AWT或SWING代表着怪异的界面和无法接受的速度 Standard Widget Toolkit(SWT)或许是Java这一噩梦的终结者广大Java程序员终于可以开发出高效率的GUI程序它们拥有标准的外观几乎没有人能看出你的程序是用Java写出来的更为重要的是这些程序是跨平台的
SWT本身仅仅是Eclipse组织为了开发Eclipse IDE环境所编写的一组底层图形界面 API或许是无心插柳或是有意为之至今为止 SWT无论是在性能和外观上都超越了SUN公司提供的AWT和SWING目前Eclipse IDE已经开发到了版本 SWT已经十分稳定这里指的稳定应该包含两层意思
2、 SWT本身仅仅是Eclipse组织为了开发Eclipse IDE环境所编写的一组底层图形界面 API或许是无心插柳或是有意为之至今为止 SWT无论是在性能和外观上都超越了SUN公司提供的AWT和SWING目前Eclipse IDE已经开发到了版本 SWT已经十分稳定这里指的稳定应该包含两层意思
3、一是指性能上的稳定其中的关键是源于SWT的设计理念 SWT最大化了操作系统的图形构件API就是说只要操作系统提供了相应图形的构件那么SWT只是简单应用JNI技术调用它们只有那些操作系统中不提供的构件 SWT才自己去做一个模拟的实现可以看出SWT的性能上的稳定大多时候取决于相应操作系统图形构件的稳定性
4、另一个稳定是指SWT API包中的类方法的名称和结构已经少有改变程序员不用担心由于Eclipse组织开发进度很快(Eclipse IDE每天都会有一个Nightly版本的发布)而导致自己的程序代码变化过大从一个版本的SWT更新至另一版本通常只需要简单将SWT包换掉就可以了
5、下面让我们开始一个SWT程序(注意以下的例子和说明主要针对Windows平台其它的操作系统应该大同小异)首先要在Eclipse安装文件中找到SWT包 Eclipse组织并不提供单独的SWT包下载必须下载完整的Eclipse开发环境才能得到SWT包 SWT是作为Eclipse开发环境的一个插件形式存在可以在${你的eclipse安装路径}\plugins路径下的众多子目录下去搜索SWT JAR文件在找到的JAR文件中包含了SWT全部的Java类文件因为SWT应用了JNI技术因此同时也要找到相对应的JNI本地化库文件由于版本和操作平台的不同本地化库文件的名称会有些差别比如SWT WIN DLL是Window平台下Eclipse Build的动态库而在Unix平台相应版本的库文件的扩展名应该是 so等等注意的是 Eclipse是一个开放源代码的项目因此你也可以在这些目录中找到SWT的源代码相信这会对开发很有帮助下面是一段打开空窗口的代码(只有main方法)
6、 import e one example;public class OpenShell{public static void main(String [] args){Display display= new Display();Shell shell= new Shell(display);shell open();//开始事件处理循环直到用户关闭窗口while(!shell isDisposed()){if(!display readAndDispatch())display sleep();}display dispose();}}
7、确信在CLASSPATH中包括了SWT JAR文件先用Javac编译例子程序编译无错后可运行java Djava library path=${你的SWT本地库文件所在路径} e one example OpenShell比如SWT WIN DLL件所在的路径是C:\swtlib运行的命令应该是java Djava library path=c:\swtlib e one example OpenShell成功运行后系统会打开了一个空的窗口
8、下面再让我们进一步分析SWT API的组成所有的SWT类都用 eclipse swt做为包的前缀下面为了简化说明我们用*号代表前缀 eclipse swt比如* widgets包代表的是 eclipse swt widgets包
9、我们最常用的图形构件基本都被包括在* widgets包中比如Button Combo Text Label Sash Table等等其中两个最重要的构件当数Shell和Composite Shell相当于应用程序的主窗口框架上面的例子代码中就是应用Shell构件打开一个空窗口 Composite相当于SWING中的Panel对象充当着构件容器的角色当我们想在一个窗口中加入一些构件时最好到使用Composite作为其它构件的容器然后再去* layout包找出一种合适的布局方式 SWT对构件的布局也采用了SWING或AWT中Layout和Layout Data结合的方式在* layout包中可以找到四种Layout和与它们相对应的布局结构对象(Layout Data)在* custom包中包含了对一些基本图形构件的扩展比如其中的CLabel就是对标准Label构件的扩展上面可以同时加入文字和图片也可以加边框 StyledText是Text构件的扩展它提供了丰富的文本功能比如对某段文字的背景色前景色或字体的设置在* custom包中也可找到一个新的StackLayout布局方式
10、 SWT对用户操作的响应比如鼠标或键盘事件也是采用了AWT和SWING中的Observer模式在* event包中可以找到事件监听的Listener接口和相应的事件对象例如常用的鼠标事件监听接口MouseListener MouseMoveListener和MouseTrackListener及对应的事件对象MouseEvent
11、* graphics包中可以找到针对图片光标字体或绘图的API比如可通过Image类调用系统中不同类型的图片文件通过GC类实现对图片构件或显示器的绘图功能
12、对不同平台 Eclipse还开发了一些富有针对性的API例如在Windows平台可以通过* ole win包很容易的调用ole控件这使Java程序内嵌IE浏览器或Word Excel等程序成为可能!
13、下面让我们展示一个比上面例子更加复杂一些的程序这个程序拥有一个文本框和一个按键当用户点击按键的时候文本框显示一句欢迎信息
14、为了文本框和按键有比较合理的大小和布局这里采用了GridLayout布局方式这种布局是SWT中最常用也是最强大的布局方式几乎所有的格式都可能通过GridLayout去达到下面的程序也涉及到了如何应用系统资源(Color)以及如何释放系统资源
15、 private void initShell(Shell shell){//为Shell设置布局对象GridLayout gShellLay= new GridLayout();shell setLayout(gShellLay);//构造一个Composite构件作为文本框和按键的容器Composite panel= new Composite(shell SWT NONE);//为Panel指定一个布局结构对象这里让Panel尽可能的占满Shell也就是全部应用程序窗口的空间 GridData gPanelData= new GridData(GridData GRAB_HORIZONTAL| GridData GRAB_VERTICAL|GridData FILL_BOTH);panel setLayoutData(gPanelData);//为Panel也设置一个布局对象文本框和按键将按这个布局对象来显示 GridLayout gPanelLay= new GridLayout();panel setLayout(gPanelLay);//为Panel生成一个背景色final Color bkColor= new Color(Display getCurrent());panel setBackground(bkColor);//生成文本框final Text text= new Text(panel SWT MULTI|SWT WRAP);//为文本框指定一个布局结构对象这里让文本框尽可能的占满Panel的空间 GridData gTextData= new GridData(GridData GRAB_HORIZONTAL| GridData GRAB_VERTICAL|GridData FILL_BOTH);text setLayoutData(gTextData);//生成按键Button butt= new Button(panel SWT PUSH);butt setText( Push);//为按键指定鼠标事件butt addMouseListener(new MouseAdapter(){public void mouseDown(MouseEvent e){//当用户点击按键的时候显示信息text setText( Hello SWT);}};//当主窗口关闭时会触发DisposeListener这里用来释放Panel的背景色 shell addDisposeListener(new DisposeListener(){public void widgetDisposed(DisposeEvent e){bkColor dispose();}};}
16、把这段代码中的方法initShell()加入到第一个打开空窗口的例子中得到的是一段能成功运行的完整GUI应用程序运行方法可参考第一个例子
17、在一个图形化的操作系统中开发程序都要调用系统中的资源如图片字体颜色等通常这些资源都是有限的程序员务必非常小心的使用这些资源当不再使用它们时就请尽快释放不然操作系统迟早会油尽灯枯不得不重新启动更严重的会导致系统崩溃 SWT是用Java开发的 Java语言本身的一大优势就是JVM的垃圾回收机制程序员通常不用理会变量的释放内存的回收等问题那么对SWT而言系统资源的操作是不是也是如此?答案是一个坏消息一个好消息
18、坏消息是SWT并没采用JVM的垃圾回收机制去处理操作系统的资源回收问题一个关键的因素是因为JVM的垃圾回收机制是不可控的也就是说程序员不能知道也不可能做到在某一时刻让JVM回收资源!这对系统资源的处理是致命的试想你的程序希望在一个循环语句中去查看数万张图片常规的处理方式是每次调入一张查看然后就立即释放该图片资源而后在循环调入下一张图片这对操作系统而言任何时刻程序占用的仅仅是一张图片的资源但如果这个过程完全交给JVM去处理也许会是在循环语句结束后 JVM才会去释放图片资源其结果可能是你的程序还没有运行结束操作系统已经宕掉
19、但下面的好消息也许会让这个坏消息变得无关紧要对于SWT只需了解两条简单的黄金法则就可以放心的使用系统资源!之所以称为黄金法则一是因为少只有两条二是因为它们出奇的简单第一条是谁占用谁释放第二条是父构件被销毁子构件也同时被销毁第一条原则是一个无任何例外的原则只要程序调用了系统资源类的构造函数程序就应该关心在某一时刻要释放这个系统资源比如调用了
20、 Font font= new Font(display Courier SWT NORMAL);
21、那么就应该在不在需要这个Font的时候调用
22、对于第二个原则是指如果程序调用某一构件的dispose()方法那么所有这个构件的子构件也会被自动调用dispose()方法而销毁通常这里指的子构件与父构件的关系是在调用构件的构造函数时形成的比如
23、 Shell shell= new Shell();Composite parent= new Composite(shell SWT NULL);Composite child= new Composite(parent SWT NULL);
24、其中parent的父构件是shell而shell则是程序的主窗口所以没有相应的父构件同时parent又包括了child子构件如果调用shell dispose()方法应用第二条法则那么parent和child构件的dispose()方法也会被SWT API自动调用它们也随之销毁
25、在任何操作平台的GUI系统中对构件或一些图形API的访问操作都要被严格同步并串行化例如在一个图形界面中的按键构件可被设成可用状态(enable)或禁用状态(disable)正常的处理方式是用户对按键状态设置操作都要被放入到GUI系统的事件处理队列中(这意味着访问操作被串行化)然后依次处理(这意味着访问操作被同步)想象当按键可用状态的设置函数还没有执行结束的时候程序就希望再设置该按键为禁用状态势必会引起冲突实际上这种操作在任何GUI系统都会触发异常
26、 Java语言本身就提供了多线程机制这种机制对GUI编程来说是不利的它不能保证图形构件操作的同步与串行化 SWT采用了一种简单而直接的方式去适应本地GUI系统对线程的要求在SWT中通常存在一个被称为用户线程的唯一线程只有在这个线程中才能调用对构件或某些图形API的访问操作如果在非用户线程中程序直接调用这些访问操作那么SWTExcepiton异常会被抛出但是SWT也在* widget Display类中提供了两个方法可以间接的在非用户线程的进行图形构件的访问操作这是通过syncExec(Runnable)和asyncExec(Runnable)这两个方法去实现例如
27、//此时程序运行在一个非用户线程中并且希望在构件panel上加入一个按键
28、 Display getCurrent() asyncExec(new Runnable(){public void run(){Button butt= new Button(panel SWT PUSH);butt setText( Push);}});
29、方法syncExec()和asyncExec()的区别在于前者要在指定的线程执行结束后才返回而后者则无论指定的线程是否执行都会立即返回到当前线程
30、 JFace与SWT的关系好比Microsoft的MFC与SDK的关系 JFace是基于SWT开发其API比SWT更加易于使用但功能却没SWT来的直接比如下面的代码应用JFace中的MessageDialog打开一个警告对话框
31、 MessageDialog openWarning(parent Warning Warning message);
32、如果只用SWT完成以上功能语句不会少于行!
33、 JFace原本是为更加方便的使用SWT而编写的一组API其主要目的是为了开发Eclipse IDE环境而不是为了应用到其它的独立应用程序因此在Eclipse版本之前很难将JFace API完整的从Eclipse的内核API中剥离出来总是要多多少少导入一些非JFace以外的Eclipse核心代码类或接口才能得到一个没有任何编译错误的JFace开发包但目前Eclipse组织似乎已经逐渐意识到了JFace在开发独立应用程序起到的重要作用在开发的版本中 JFace也开始变成了和SWT一样的完整独立的开发包只是这个开发包还在变动中(笔者写本文时应用的Eclipse M版本) JFace开发包的包前缀是以 eclipse jface开头 JAR包的源代码也和SWT一样也在${你的eclipse安装路径}\plugins路径下去找
34、对开发人员来说在开发一个图形构件的时候比较好的方式是先到JFace包去找一找看是不是有更简洁的实现方法如果没有再用SWT包去自己实现比如JFace为对话框提供了很好的支持除了各种类型的对话框(比如上面用的MessageDialog或是带有Title栏的对话框)如要实现一个自定义的对话框也最好从JFace中的Dialog类继承而不是从SWT中的* widget Dialog继承
35、应用JFace中的Preference包中的类很容易为自己的软件做出一个很专业的配置对话框对于Tree Table等图形构件它们在显示的同时也要和数据关联例如Table中显示的数据在JFace中的View包中为此类构件提供了Model View方式的编程方法这种方法使显示与数据分开更加利于开发与维护 JFace中提供最多的功能就是对文本内容的处理可以在 eclipse jface text*包中找到数十个与文本处理相关类
36、 Java程序通常是以class文件的方式发布的运行class需要JRE或JDK的支持这又是Java GUI程序的另一个致命的弱点想象对一个面向广大用户的应用程序来说无论你的程序功能有多简单或是你的代码十分的精简你都不得不让用户去下载一个 M的JRE那是多么令人沮丧的一件事而且对程序员来说 Class通常意味着源代码的暴露反编译的工具让那些居心叵测的人轻易得到你的源代码虽然有很多对Class的加密方法但那总是以牺牲性能为代价的好在我们还有其它的方式可用把Class编译成exe文件!
二、java是什么语言
语言我们说的普通话、英语都是语言,语言是一种交流的工具,语言具有创造性和结构性,并且代表一定的意义。比如我说下课了,大家都明白什么意思,证明这个语句的意思表达清楚了,正规的语言在交流上是不能有歧义的。计算机编程计算机编程就是:把程序员的要求和设想,按照能够让计算机看得懂的规则和约定,编写出来的过程,就是编程。编程的结果就是一些计算机能够看懂并能够执行和处理的东西,我们把它叫做软件或者程序。事实上,程序就是我们对计算机发出的命令集(指令集)。Java是一种计算机编程语言首先,Java是一种语言,也就是 Java是用来交流的,那么用来谁和谁交流呢?很明显就是程序员和计算机交流,换句话说把我们的要求和设想用Java语言表达出来,那么计算机能看懂,就能够按照我们要求运行,而这个过程就是我们所说的使用Java编程,所以我们讲 Java是一种计算机编程语言。为了让计算机看懂,Java会有一系列的规则和约定,这些就是 Java的语法。
2、Java是一种软件开发平台什么是软件开发可以简单地理解为:编程的结果是软件或者程序,而编程的过程就是软件开发。软件开发的基本步骤包括:需求分析、概要设计、详细设计、编码、测试、维护等阶段。需求分析:这里指的需求不仅仅是用户需求,应该是开发中遇到的所有的需求。比如,你首先要知道做这个项目是为了解决什么问题;测试案例中应该输入什么数据……为了清楚地知道这些需求,你经常要和客户、项目经理以及项目伙伴调查研究,这就是需求分析。概要设计、详细设计:根据软件系统需求完成对系统的设计,确定强壮的系统架构,设计模块层次、用户界面和数据库表结构。编码:开发代码,完成设计的具体实现。测试:利用测试工具按照测试方案和业务流程对产品进行功能和性能测试,对测试方案可能出现的问题进行分析和评估,并修改代码。维护:根据用户需求的变化或硬件环境的变化,对应用程序进行部分或全部的修改。用以下的流程图来表达这个过程:
什么是开发平台?在软件开发的过程中,我们需要很多的工具来辅助我们的工作,不可能什么都从头自己做。我们把编程的环境和相应的辅助工具统称为开发环境,开发平台就是用来提供这个开发环境的。车床工人需要一个车床才能工作一样。
Java是一种开发平台Java不单纯是一个编程的语言,它自身提供了一系列开发 Java所需要的环境和工具,来进行编译、解释、文档生成、打包等,比如:javac.exe、javadoc.exe等等,这些我们后面会讲到,所以我们讲 Java是一个开发平台。3、Java是一种软件运行平台什么是软件的运行平台如同人类需要阳光、空气、水和食物才能正常存活一样,软件最终要能够运行,也需要一系列的外部环境,来为软件的运行提供支持,而提供这些支持的就是运行平台。Java是一种软件运行平台Java本身提供 Java软件所需要的运行环境,Java应用可运行在安装了 JRE(Java Runtime Environment)的机器上,所以我们说 Java是一个运行平台。JRE:Java Runtime Environment,Java运行环境。4、Java是一种软件部署环境什么是软件的部署简单地讲,部署就是安装,就是把软件放置到相应的地方,并且进行相应的配置(一般称作部署描述)让软件能够正常运行起来。Java是一种软件部署环境Java本身是一个开发的平台,开发后的Java程序也是运行在Java平台上的。也就是说,开发后的Java程序也是部署在Java平台上的,这个尤其在后面学习JEE(Java的企业版)的时候,体现更为明显。
三、大学生程序员必备的十款工具
1、优点:功能强大、高度可定制,Vi编辑器中最好的一个。
2、Vim是vi发展出来的一个文本编辑器。代码补全、编译及错误跳转等方便编程的功能特别丰富,在程序员中被广泛使用,和Emacs并列成为类Unix系统用户最喜欢的文本编辑器。
3、优点:简洁美观、插件化,能够节约时间。uTools是一个极简、插件化的现代桌面软件,通过自由选配丰富的插件,打造得心应手的工具集合。
4、优点:分布式开发、速度快、灵活。Git是一个开源的分布式版本控制系统,可以有效、高速地处理从很小到非常大的项目版本管理。也是LinusTorvalds为了帮助管理Linux内核开发而开发的一个开放源码的版本控制软件。
5、优点:高效、安全,是最好用的数据库管理工具。“Navicat”是一套可创建多个连接的数据库管理工具,用以方便管理 MySQL、Oracle、PostgreSQL、SQLite、SQL Server、MariaDB和 MongoDB等不同类型的数据库,它与阿里云、腾讯云、华为云、Amazon RDS、Amazon Aurora、AmazonRedshift、Microsoft Azure、Oracle Cloud和MongoDB Atlas等云数据库兼容
6、优点:业界排名第一的java开发工具。IintelliJIDEA,是java编程语言的集成开发环境。IntelliJ在业界被公认为最好的Java开发工具,尤其在智能代码助手、代码自动提示、重构、JavaEE支持各类版本工具(git、svn等)、JUnit、CVS整合、代码分析、创新的GUI设计等方面的功能可以说是超常的。
7、优点:功能强大,一款终端神器。Term2 Mac版可以说是Mac下最好的终端工具。iTerm2拥有多标签、中键复制粘贴、命令记忆、高亮指针、迅捷重复、全屏切换等功能,提升操作效率。
8、Alfred是 Mac系统上一款专注于效率提升的著名应用,它能帮你快速打开网页、快速进行自定义搜索查看剪贴板历史、快速查询单词等等。Alfred提供的功能虽然很多,但目的只有一个-那就是减少我们工作中的一些重复动作,提升我们的工作效率。
9、08·Beyond Compare代码比较工具
10、优点:高效,适用于用于文档、源代码和HTMLoBeyond Compare可以很方便地对比出两份源代码文件之间的不同之处,相差的每一个字节用颜色加以表示,查看方便,支持多种规则对比。
11、优点:跨平台,跨服务器,实现应用程序跨平台间的无缝衔接。
12、Docker其中包括,镜像、容器、仓库,很简单,目的就是通过对应用组件的封装、分发、部署、运行等生命周期的管理,使用户的产品(可以是 web应用或者数据库应用)及其环境能够做到“一次封装,到处运行”。
13、优点:功能强大,使用简单且易用性好。Postman是一个简单好用的网页调试软件,很适合开发人员使用,性能稳定流畅,提供接口测试、并发测试等功能,还支持编写测试脚本,快速处理各种HTTP请求,测试数据精准高效。