前话 从Java诞生至今,已经在太多的领域取得成功,然而它却很少在图形界面程序上崭露头角。究其原因,Java语言缺省的图形界面开发包AWT和SWING实在是难脱其究, 无论速度和外观,它们都难以让人接受。 如今,Eclipse组织编写的SWT开发包,为Java程序员提供了AWT和SWING之外的一个更佳的选择。也越来越多受到广大程序员的亲睐,已经有不少程序员用它开发出美观、高效、实用的桌面应用程序。 SWT在外观和性能上都超过了awt/swing。(引用) 感想 在接触SWT/JFace这套GUI前,我并没有使用过AWT/SWING。所以不知道它们到底谁好谁坏,但是在尝试用SWT/JFace时候,发现原来开发UI也是一件很有意思的事。 首先讲讲个人对它的一些领悟,它有优点,美观、快速。但是也有缺点,那就是不能在一个界面上放太多组件,否则可能会引起占有大量内存甚至导致死机。到底支持不支持跨平台,不知道怎么说,要看你的概念中的跨平台是一个什么样的概念。SWT/JFace是跨平台的。可能旧版本不支持(因为没用过,我也不知道),现在支持了。SWT/JFace和AWT/SWING在实现上有很大的不同,SWT/JFace是直接调用本机窗口组件,当本机没有所需要组件时才进行模拟;而AWT/SWING是模拟本机窗口组件。所以,我把为什么SWT/JFace比AWT/SWING跑的快归因于此。 HelloWorld 接下来就是做事了,先做一些准备工作。需要用到的是SWT Designer,SWT Designer是一个很好的Eclipse的SWT界面开发插件,支持界面组件的拖拉操作。安装它就像安装其它Eclipse插件那么简单。SWT Designer的下载地址:www.swt-designer.com。 做好简单的准备工作,开始第一个项目:HelloWorld。建立项目就像建立Java项目一样。然后输出以下代码: package com.swtdesigner; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.Text; public class HelloWorld { public static void main(String[] args) { final Display display = Display.getDefault(); final Shell shell = new Shell(); shell.setSize(327, 253); shell.setText("SWT Application"); //------------------新插入的界面核心代码------------------------ Text text = new Text(shell, SWT.BORDER); //新建一个text对象 text.setText("HelloWorld"); //给text文本框设置初始文字HelloWorld text.setBounds(88, 94, 100, 25); //设置文本框的位置和大小,(x轴坐标,y轴坐标,宽度,高度) //------------------END--------------------------------------------- shell.layout(); shell.open(); while (!shell.isDisposed()) { if (!display.readAndDispatch()) display.sleep(); } } } 要注意的地方是,在运行项目之前,必须导入SWT的原生库,否则会报异常。好像新版本解决了这个问题。【略】 这样一个简单的HelloWorld程序就搞定了,是不是很简单呢?创建一个典型的SWT应用程序需要以下的步骤: 1)创建一个Display 2)创建一个或多个shell 3)设置shell的布局 4)创建shell中的组件 5)用open()方法打开shell窗口 6)写一个事件转发循环 7)销毁Display 组件 HelloWorld太简单了,继续做一些组件,比如说Button或者是Text,Menu等等。步骤是一样的,只不过代码不一样而已。 一个简单的Button package com.swtdesigner; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Button; public class Button1 { public static void main(String[] args) { final Display display = Display.getDefault(); final Shell shell = new Shell(); final Button button = new Button(shell,SWT.BORDER); //SWT.NONE SWT.BORDER SWT.FLAT. shell.setSize(500, 375); shell.setText("SWT Application"); //-------------------------------- button.addSelectionListener(new SelectionAdapter(){ public void widgetSelected(SelectionEvent e){ MessageDialog.openInformation(null,"","你单击了"+button.getText()+"按钮"); } }); button.setBounds(50,51,100,25); button.setText("确定"); button.setToolTipText("哇哈哈,终于成功了,一个小错误而已!"); button.setImage(new Image(display,"icons/refresh.gif")); //-------------------------------- shell.open(); shell.layout(); while (!shell.isDisposed()) { if (!display.readAndDispatch()) display.sleep(); } } } 一个简单的Text //------------------------------- final Text text = new Text(shell,SWT.BORDER); text.setBounds(18,20,153,25); text.setTextLimit(10); text.addVerifyListener(new VerifyListener(){ public void verifyText(VerifyEvent e){ //检查输入的字符(e.text是否在0123456789这个字符串当中,不在indexOf会返回一个-1) boolean b=("0123456789".indexOf(e.text)>=0); e.doit = b; //doit属性如果为true,则字符允许输入.反之不允许 } }); final Button button = new Button(shell,SWT.NONE); button.setText("确定"); button.addSelectionListener(new SelectionAdapter(){ public void widgetSelected(SelectionEvent e){//按钮的单击事件 //如果文本框没有输入,则出现一个警告窗,否则出现一个信息提示窗 String str = text.getText(); if(str == null || str.equals("")) MessageDialog.openWarning(null,"","请输入一个字符"); else MessageDialog.openInformation(shell,"","输入值通过检证"); } }); button.setBounds(21,55,100,25); //------------------------------- 一个简单的Menu组件。效果图和代码如下。 //------------------新插入的界面核心代码------------------------ //主菜单 Menu mainMenu = new Menu(shell, SWT.BAR); shell.setMenuBar(mainMenu); { //“文件”项。 MenuItem fileItem = new MenuItem(mainMenu, SWT.CASCADE); fileItem.setText("文件(&F)"); //“文件”菜单 Menu fileMenu = new Menu(shell, SWT.DROP_DOWN); fileItem.setMenu(fileMenu); { //“新建”项。 MenuItem newFileItem = new MenuItem(fileMenu, SWT.CASCADE); newFileItem.setText("新建(&F)"); //“新建”菜单 Menu newFileMenu = new Menu(shell, SWT.DROP_DOWN); newFileItem.setMenu(newFileMenu); { //“新建项目”项 MenuItem newProjectItem = new MenuItem(newFileMenu, SWT.PUSH); //“\t”相当于间隔tab键的空间 newProjectItem.setText("项目\tCtrl+Shift+N"); //定义快捷键Ctrl+Shift+N newProjectItem.setAccelerator(SWT.CTRL + SWT.SHIFT + 'N'); //设置菜单项的图标 newProjectItem.setImage(new Image(null, "icons/project.gif")); //菜单项的单击事件 newProjectItem.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { MessageDialog.openInformation(null, "", "新建项目"); } }); //建立其他菜单项 new MenuItem(newFileMenu, SWT.SEPARATOR); new MenuItem(newFileMenu, SWT.PUSH).setText("包"); new MenuItem(newFileMenu, SWT.PUSH).setText("类"); new MenuItem(newFileMenu, SWT.PUSH).setText("接口"); new MenuItem(newFileMenu, SWT.SEPARATOR);//分隔符 new MenuItem(newFileMenu, SWT.PUSH).setText("其他(&O)"); } } new MenuItem(fileMenu, SWT.CASCADE).setText("退出"); } MenuItem menuItem2 = new MenuItem(mainMenu, SWT.CASCADE); menuItem2.setText("帮助(&H)"); //------------------END--------------------------------------------- 还有Tree,toolbar等等很多组件,这里就不一一介绍了。大家可以都去试试看。 布局 SWT/JFace的成功之一就是它的强大布局功能,它有5种布局方式,分别是:充满式,行列式,网格式,堆栈式,表格式。其中网格式和堆栈式用的最多,网格式最为复杂。 下面图是仿照QQ的个人资料界面做的一个布局,要把它们排列好真的不是件简单的事。 后续->Eclipse插件 下一步将进行的工作将是做一个简单的Eclipse插件,届时会用到更多的UI设计。将这些零散的知识点凝聚起来做成一个小成品。^^... 对于文中可能很多地方都描述不清,是因为我懒得写那些繁琐的过程,现在在网上很多介绍SWT/JFace使用的文章,大家可以去找来看看。