前话
从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使用的文章,大家可以去找来看看。