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已经开发到了2.1版本,swt已经十分稳定。这里指的稳定应该包含两层意思:
一是指性能上的稳定,其中的关键是源于swt的设计理念。swt最大化了操作系统的图形构件api,就是说只要操作系统提供了相应图形的构件,那么swt只是简单应用jni技术调用它们,只有那些操作系统中不提供的构件,swt才自己去做一个模拟的实现。可以看出swt的性能上的稳定大多时候取决于相应操作系统图形构件的稳定性。
另一个稳定是指swt api包中的类、方法的名称和结构已经少有改变,程序员不用担心由于eclipse组织开发进度很快(eclipse ide每天都会有一个nightly版本的发布),而导致自己的程序代码变化过大。从一个版本的swt更新至另一版本,通常只需要简单将swt包换掉就可以了。
第一个swt程序
下面让我们开始一个swt程序。(注意:以下的例子和说明主要针对windows平台,其它的操作系统应该大同小异)。首先要在eclipse安装文件中找到swt包,eclipse组织并不提供单独的swt包下载,必须下载完整的eclipse开发环境才能得到swt包。swt是作为eclipse开发环境的一个插件形式存在,可以在${你的eclipse安装路径}\plugins路径下的众多子目录下去搜索swt.jar文件,在找到的jar文件中包含了swt全部的java类文件。因为swt应用了jni技术,因此同时也要找到相对应的jni本地化库文件,由于版本和操作平台的不同,本地化库文件的名称会有些差别,比如swt-win32-2116.dll是window平台下eclipse build 2116的动态库,而在unix平台相应版本的库文件的扩展名应该是.so,等等。注意的是,eclipse是一个开放源代码的项目,因此你也可以在这些目录中找到swt的源代码,相信这会对开发很有帮助。下面是一段打开空窗口的代码(只有main方法)。
import com.e2one.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();
}
}
确信在classpath中包括了swt.jar文件,先用javac编译例子程序。编译无错后可运行java -djava.library.path=${你的swt本地库文件所在路径} com.e2one.example.openshell,比如swt-win32-2116.dll件所在的路径是c:\swtlib,运行的命令应该是java -djava.library.path=c:\swtlib com.e2one.example.openshell。成功运行后,系统会打开了一个空的窗口。
剖析swt api
下面再让我们进一步分析swt api的组成。所有的swt类都用org.eclipse.swt做为包的前缀,下面为了简化说明,我们用*号代表前缀org.eclipse.swt,比如*.widgets包,代表的是org.eclipse.swt.widgets包。
我们最常用的图形构件基本都被包括在*.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布局方式。
swt对用户操作的响应,比如鼠标或键盘事件,也是采用了awt和swing中的observer模式,在*.event包中可以找到事件监听的listener接口和相应的事件对象,例如常用的鼠标事件监听接口mouselistener,mousemovelistener和mousetracklistener,及对应的事件对象mouseevent。
*.graphics包中可以找到针对图片、光标、字体或绘图的api。比如可通过image类调用系统中不同类型的图片文件。通过gc类实现对图片、构件或显示器的绘图功能。
对不同平台,eclipse还开发了一些富有针对性的api。例如,在windows平台,可以通过*.ole.win32包很容易的调用ole控件,这使java程序内嵌ie浏览器或word、excel等程序成为可能!
更复杂的程序
下面让我们展示一个比上面例子更加复杂一些的程序。这个程序拥有一个文本框和一个按键,当用户点击按键的时候,文本框显示一句欢迎信息。
为了文本框和按键有比较合理的大小和布局,这里采用了gradlayout布局方式。这种布局是swt中最常用也是最强大的布局方式,几乎所有的格式都可能通过gradlayout去达到。下面的程序也涉及到了如何应用系统资源(color),以及如何释放系统资源。
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_verticalgriddata.fill_both);
panel.setlayoutdata(gpaneldata);
//为panel也设置一个布局对象。文本框和按键将按这个布局对象来显示。
gridlayout gpanellay = new gridlayout();
panel.setlayout(gpanellay);
//为panel生成一个背景色
final color bkcolor = new color(display.getcurrent(),200,0,200);
panel.setbackground(bkcolor);
//生成文本框
final text text = new text(panel,swt.multiswt.wrap);
//为文本框指定一个布局结构对象,
这里让文本框尽可能的占满panel的空间。
griddata gtextdata = new griddata (griddata.grab_horizontal griddata.grab_verticalgriddata.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();
}
});
}
把这段代码中的方法initshell()加入到第一个打开空窗口的例子中,得到的是一段能成功运行的完整gui应用程序。运行方法可参考第一个例子。
Java Asp PHP .Net XML C/C++ CGI VB Jsp J2ee J2se J2me EJB Servlet Tomcat Resin Struts Weblogic Eclipse ANT GUI JMS Web servise IDEA Webphere Hibernate Spring Jboss Applet Swing Socket Javamail Perl Ajax P2P 安全 模式 框架 测试 开源 游戏
Windows XP Windows 2000 Windows 2003 Windows Me Windows 9.x Linux UNIX 注册表 操作系统 服务器 应用服务器