前話
從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使用的文章,大家可以去找來看看。