本文主要討論Java中的GUI圖形庫之一SWT/JFace在本文的第一部分將解釋什麼是SWT/JFace以及如何安裝SWT/JFace在本文的第二部分將以實例的方式討論如何使用SWT/JFace編寫GUI程序
一 進入SWT/JFace世界
什麼是SWT/JFace
Java是一種強大的編程語言但強大就意味復雜尤其是和Java相關的名詞就象天上的星星一樣數都數不過來在本文中就涉及到兩個比較常用的名詞SWT和JFace在標題中將SWT和JFace放到一起並不是說SWT和JFace是一個意思而是說它們的關系非常緊密
基於Java的圖形庫最主要的有三種它們分別是SwingAWT和SWT其中前兩個是Sun隨JDK一起發布的而SWT則是由IBM領導的開源項目(現在已經脫離IBM了)Eclipse的一個子項目SWT的執行效率非常高這是由於SWT的底層是由C編寫的由於SWT通過C直接調用系統層的GUI API因此使用SWT編寫GUI程序在外觀上就和使用C++Delphi(在Windows下)編寫的程序完全一樣它的這一點和AWT類似AWT在底層也是使用C直接調用系統層的GUI API但它們是有區別的最大的區別可能就是一個是Sun提供的一個是Eclipse自帶的這就意味著如果使用AWT只要機器上安裝了JDK或JRE發布軟件時無需帶其它的庫而如何使用SWT在發布時必須要自帶上SWT的*dll(Windows版)或*so(Linux/Unix版)文件以及相關的*jar包還有就是它們所提供的圖形接口有一些差異SWT可能更豐富一些我們可以看看Eclipse的界面就知道了但隨著Sun對AWT庫的不斷更新AWT的圖形表現能力也在不斷地提高
雖然SWT很強大但它比較底層也就是說它的一些功能在使用上還比較低級不太符合面向對象的特征因此在SWT的基礎上又開發了JFaceJFace在SWT上進行了一定的擴展因此也可說JFace是基於SWT的就象在VC中使用MFC來包裝Win API一樣
SWT/Face的安裝
在發布使用SWT/JFace編寫的GUI程序時要隨程序帶上相應的庫文件對於Windows版的SWT來說SWT包含有個dll文件和一個jar文件它們是swtawtwindllswtgdipwindllswtwglwindllswtwindll和swtjar在發布時要將個dll文件放到path路徑中或者使用Djavalibrarypath設置相應的路徑將swtjar放到classpath路徑中或使用classpath設置相應的jar包而對於JFace除了上述的個文件外還要帶上個jar包在點擊提交按鈕後將顯示如圖所示的頁面
reruntime_jar
orgeclipsejface_jar
orgeclipsejfacetext_jar
orgeclipseosgi_jar
orgeclipsetext_jar
這個jar包都可以在eclipse的plugins目錄中找到在這個文件後面的版本號可能會因為eclipse的版本號不同而不同但前面的部分都是一樣的讀者在找這些jar包時應注意這一點
SWT的開發包可以從單獨下載也可以從eclipse的plugins目錄復制而JFace的開發包並未提供單獨的下載因此JFace的開發包必須要從plugins目錄得到
二 讓我們編寫第一個程序吧
學習一種新技術的最好方法就是去使用它下面就讓我們來使用SWT和JFace來分別實現同一個程序這個程序是一個簡單的記事本程序在上面有三個按紐分別是新鍵打開保存下面是一個文本框用於編輯文本信息下面讓我們先來看一下使用SWT實現的程序界面
圖
使用SWT實現的記事本程序界面
怎麼樣看看上面的界面是不是和用DelphiVC做的界面完全一樣!!
用SWT實現
不論一個程序帶不帶GUI都必須有一個入口點對於Java來說這個入口點就是main函數因此在編寫程序之前我們必須定義一個類並且這個類中必須有個main函數
import orgeclipseswtwidgets*;
import orgeclipseswt*;
import orgeclipseswtevents*;
import javaio*;
public class FirstSWT
{
// 用於記錄是否已經打開或保存了一個文件如果已經打開或保存了一個文件
// 這個變量就是這個文件的名子
private static String fn = ;
public static void main(String[] args)
{
… …
}
}
上面四個import將導入一些在本程序中要用到的jar包前三個是SWT的包最後一個是Java的標准輸入輸出包
建立窗體
任何一個GUI程序都至少有一個窗體(在本程序中只有一個窗體)因此下面我們就在main函數中建立這個窗體
display = new Display();
shell = new Shell(display SWTDIALOG_TRIM);
shellsetText(第一個SWT程序);
shellsetSize( );
在上面行代碼中涉及到了兩個類Display和Shell這兩個類都是在FirstSWT中定義的私有靜態類之所以定義成全局的是因為在以後的按鈕事件類中要使用它們下面是它們的定義
private static Display display;
private static Shell shell;
後面條語句通過調用Shell類的setText和setSize方法設置了窗口的標題和尺寸
下面解釋一下Display和Shell類是什麼
SWT在底層實現上分為兩層系統層和用戶層系統層就是直接和操作系統平台打交道系統層的存在依賴於操作系統平台在這裡系統層就是Display類Display的功能就是在系統和用戶之間架起一座橋梁也就是說使用戶訪問系統資源透明化而Shell類是直接和用戶打交道因此它屬於用戶層通過Shell類可以控制窗體中的控件窗體本身的屬性等而Shell通過Display這座橋梁訪問系統級API
l 向窗體中添加控件
接下來我們先在這個窗體上建立三個按鈕代碼如下
Button newButton = new Button(shell SWTPUSH);
newButtonsetLocation( );
newButtonsetSize( );
newButtonsetText(新建);
Button openButton = new Button(shell SWTPUSH);
openButtonsetLocation( );
openButtonsetSize( );
openButtonsetText(打開);
Button saveButton = new Button(shell SWTPUSH);
saveButtonsetLocation( );
saveButtonsetSize( );
saveButtonsetText(保存);
按鈕類是Button在建立時Button需要兩個參數一個是Shell對象另外一個是按鈕的類型在本例中我們使用SWTPUSH類型(一般的按鈕類型)
注和SWT相關的常量都定義在了SWT 中
後面條語句分別設置了三個按鈕的位置尺寸和按鈕標題
最後在個按鈕下方建立一個文本框
text = new Text(shell SWTMULTI | SWTBORDER | SWTV_SCROLL | SWTWRAP);
textsetLocation( );
textsetSize(shellgetClientArea()width shellgetClientArea()height );
文本框的類是Text和按鈕不同的是由於文本框需要在按鈕事件中被訪問因此文本對象必須定義成全局的
private static Text text;
添加控件事件代碼
現在讓我們為三個按鈕控件中加入事件代碼和大多數語言不同的是按鈕的單擊事件不叫Click而叫Selection一般需要將Selection事件代碼放到一個從SelectionAdapter類繼承的子類中然後通過按鈕類的addSelectionListener方法將這個事件類的實例傳入按鈕類的實例中但為了簡便起見我們使用隱式建立對象的方法來建立事件類的對象下面是新建按鈕的事件代碼
newButtonaddSelectionListener(new SelectionAdapter()
{
public void widgetSelected(SelectionEvent event)
{
fn = ;
shellsetText(第一個SWT程序);
textsetText();
}
});
由於SelectionAdapter是一個抽象類它有一個抽象方法widgetSelected在上述代碼被override了在新建按鈕中將全局文件名賦成空串並將窗體的標題賦成初始狀態最後將文本框清空
接下來讓我們看看打開按鈕的事件代碼
openButtonaddSelectionListener(new SelectionAdapter()
{
public void widgetSelected(SelectionEvent event)
{
FileDialog dlg = new FileDialog(shell SWTOPEN);
String fileName = dlgopen();
try
{
if (fileName != null)
{
// 打開指定的文件
FileInputStream fis = new FileInputStream(fileName);
textsetText();
BufferedReader in = new BufferedReader(new InputStreamReader(fis));
String s = null;
// 將指定的文件一行一行地加到文本框中
while ((s = inreadLine()) != null)
textappend(s + \r\n);
}
if (fileName != null)
{
fn = fileName;
shellsetText(fn);
MessageBox successBox = new MessageBox(shell);
successBoxsetText(信息);
successBoxsetMessage(打開文件成功!);
successBoxopen();
}
}
catch (Exception e)
{
MessageBox errorBox = new MessageBox(shell SWTICON_ERROR);
errorBoxsetText(錯誤);
errorBoxsetMessage(打開文件失敗!);
errorBoxopen();
}
}
});
上面代碼的基本邏輯是使用打開對話框選擇一個文件使用FileInputStream將這個文件打開並且將文件中的內容一行一行地加入到文本框中如果這個過程失敗顯示錯識對話框如果成功將fn變量和窗體的標題欄都賦成這個文件名
最後讓我們實現保存按鈕事件的代碼
saveButtonaddSelectionListener(new SelectionAdapter()
{
public void widgetSelected(SelectionEvent event)
{
try
{
String fileName = null;
if (fnequals())
{
FileDialog dlg = new FileDialog(shell SWTSAVE);
fileName = dlgopen();
if(fileName != null)
fn = fileName;
}
if (fn != )
{
FileOutputStream fos = new FileOutputStream(fn);
OutputStreamWriter out = new OutputStreamWriter(fos);
outwrite(textgetText());
outclose();
shellsetText(fn);
MessageBox successBox = new MessageBox(shell);
successBoxsetText(信息);
successBoxsetMessage(保存文件成功!);
successBoxopen();
}
}
catch (Exception e)
{
MessageBox errorBox = new MessageBox(shell SWTICON_ERROR);
errorBoxsetText(錯誤);
errorBoxsetMessage(保存文件失敗!);
errorBoxopen();
}
}
});
這段代碼的基本邏輯是如果當前已經打開一個文件或已經將當前的新建文件保存過了在點擊保存按鈕時不再顯示保存對話框而直接將文件保存否則將顯示一個保存對話框通過這個對話框可以選擇一個文件名然後再保存
讓我們最後畫龍點睛吧
程序到這已經基本完成了但還需要進行最後一步就是對事件進行監聽在main函數的最後可以加上如下的代碼實現這個功能
shellopen(); // 顯示窗體
while (!shellisDisposed()) // 當窗體未被關閉時執行循環體內的代碼
{
// 如果未發生事件通過sleep方法進行監視事件隊列
if (!displayreadAndDispatch())
{
displaysleep();
}
}
displaydispose(); // 釋放底層的資源
看看上面的代碼是不是有點象MFC的監聽事件代碼!!
用JFace實現
使用JFace實現GUI程序和SWT的最大的區別就是JFace的窗體類必須從ApplicationWindow繼承
import orgeclipsejfacewindowApplicationWindow;
public class FirstJFace extends ApplicationWindow
{
public static void main(String[] args)
{
… …
}
}
另外一個不同是在設置窗體上JFace通過ApplicationWindow類提供一系列的事件函數通過在這些函數中編寫代碼可以很方便地對窗體進行操作如可以在createContents函數中向窗體中加入控件
protected Control createContents(Composite parent)
{
// 這裡邊的代碼就是上述的建立控件的代碼只是要將shell換成parent
}
由於使用JFace操作控件的方式和SWT類似本文將不再詳細討論感性趣的讀者可以參考本文提供的源代碼使用JFace的程序界面和SWT完全一樣界面如圖所示
圖
使用JFace實現的記事本程序界面
From:http://tw.wingwit.com/Article/program/Java/hx/201311/25617.html