一個用于構建圖形接口的圖形化工具
David Gallardo
軟件顧問
2004 年 5 月
與許多 Eclipse.org 項目類似,Visual Editor 項目的目標是構建一個用于構建工具(在這里是用于構建圖形用戶接口的工具)的工具。關于 Visual Editor 項目最有趣的事情是它已經發(fā)布了一個參考實現(xiàn)。Visual Editor 版本 0.5 是用于構建 AWT/Swing 應用程序的 GUI 構建器,這是一個期待已久的 Eclipse 特性。在很快就要發(fā)布的、預定在 2004 年中期提交的 1.0 版中,將增加對于 SWT 的支持。在本文中,您將獲得關于 Visual Editor 及其背后技術的概覽,以及 Visual Editor 0.5 用于構建 AWT/Swing 應用程序的特性的一個簡短示范,以及關于 Visual Editor 1.0 中的 SWT 支持的預覽。
Eclipse Visual Editor 項目介紹
仔細閱讀關于 Eclipse 及其競爭者的優(yōu)缺點的任何討論線索,您將會發(fā)現(xiàn)關于各種特性的提示信息,這些特性在其中各方互有優(yōu)劣,或者完全缺乏。直到最近,對于 Eclipse,似乎經常被提起的事情是它缺少 GUI 構建器:一個用于構建圖形用戶接口的圖形化工具。值得高興的是,通過 2003 年 11 月發(fā)起的 Eclipse Visual Editor 項目以及隨后 Visual Editor 0.5 的迅速發(fā)布,這種情況已經得到彌補。Visual Editor 0.5 允許您通過一個完全的 WYSIWYG(所見即所得)圖形化編輯器來創(chuàng)建 AWT/Swing 應用程序。
與 Eclipse 自身類似,Visual Editor 也基于 IBM 的代碼貢獻。熟悉 Websphere Studio Application Developer 5.x 中的 Visual Editor 的開發(fā)人員將會發(fā)現(xiàn) Eclipse 的 Visual Editor 幾乎與之完全相同。要想了解如何使用 Visual Editor,請參閱 Websphere Studio Visual Editor 文檔,該文檔在本文末尾的 參考資料一節(jié)中列出。
與 Eclipse.org 組織下的許多其他項目(包括 Eclipse)類似,Visual Editor 項目所確定的目標是非常宏偉的:構建一個用于構建圖形化編輯工具的工具。盡管最初發(fā)行版中對于 AWT/Swing 的支持已經完成,但是 Visual Editor 的計劃遠不止于此。技術基礎正在進行重新設計,從而使得它對于編程語言和所支持的圖形工具集來說是不相關的。
在將來,您會看到除了 AWT/Swing 以外的其他的 Visual Editor 實現(xiàn)(比如 SWT),以及潛在的除了 Java 語言以外的其他語言的實現(xiàn)(比如 C++)。有關增加 SWT 支持的工作已經在進行之中,事實上,這將會包括在 Visual Editor 版本 1.0 中,預定在 2004 年中期,大概與 Eclipse 3.0 同期完成。
Visual Editor 的內幕
Visual Editor 的第一個具體實現(xiàn),作為一個針對 AWT/Swing 的 GUI 構建器,對于 GUI 開發(fā)人員來說已經是足夠令人滿意的了,但是如果您是那種希望了解內幕的開發(fā)人員,那么還可以看到許多東西:Visual Editor 利用一些非常有趣的技術,這些技術本身都是有用的。如果您對于構建自己的圖形化編輯器或者對工具建模感興趣的話,那么現(xiàn)有的 Visual Editor 實現(xiàn)對于您可以完成的事物來說只是一個線索。
Visual Editor 所利用的最為明顯的工具是 GEF,即圖形化編輯框架(Graphical Editing Framework)。GEF 建立于本地 Eclipse 圖形化工具集 SWT 之上,以使得開發(fā)一個圖形化編輯器或者所見即所得文本編輯器更為容易。如果您熟悉 SWT (或者 AWT/Swing,在這方面它們是類似的)中的圖形原語,那么您會知道繪制和處理任意的形狀(比如矩形、箭頭和橢圓)是比較困難的,更不用說管理它們之間的關系以及它們所代表的數(shù)據模型了。
GEF 被劃分為兩個部分:第一部分是 Draw2D 插件,這是一個輕量級的繪圖和呈現(xiàn)包,用于幫助您繪制圖形。第二部分是 GEF 插件,除了其他工具以外,這一部分中還增加了選擇和創(chuàng)建工具、工具選項板,以及用于在數(shù)據模型和視圖之間進行映射的控制器框架。
GEF 是一個模型無關的框架,但是作為 Visual Editor (以及其他生成代碼的圖形化工具)的一部分,它在后臺使用 Eclipse 建模框架(Eclipse Modeling Framework, EMF),以在模型、Java 類和圖形化表示之間進行映射,其中模型是使用 XML 元數(shù)據交換(XML Metadata Interchange, XMI)在內部存儲的。EMF 的重要特性之一是它確保所有這些映射都是一對一的;所以盡管 XMI 可以被認為是模型的標準表示,但是在代碼和圖形之間來回切換并不會丟失任何信息。這就是為什么 Visual Editor 只需要保存模型的一種表示(即 Java 源代碼),以及開發(fā)人員可以自由地在圖形化編輯器之外編輯該源代碼的原因。
要更多地了解 GEF 和 EMF,請參閱本文 參考資料小節(jié)中的鏈接。
利用 Visual Editor 開發(fā) AWT/Swing 應用程序
正如前面所提到的,目前可用的版本 0.5 是一個完全的 AWT/Swing GUI 構建器。它與 Eclipse 2.1.x 共同工作,并且與其他 IDE 中的 GUI 構建器相比毫不遜色。首先,它生成高質量的代碼,可以與一個有經驗的 GUI 開發(fā)人員通過手工開發(fā)的代碼相媲美,并且不帶有使得修改變得困難的特殊工件(artifact)。其次,它強大的分析能力允許完全的代碼來回轉換,因此對源代碼的修改幾乎立即反映在圖形化編輯器中。
在手工構建 Swing 應用程序時,最為乏味的任務之一就是使用布局管理器來管理組件的位置。因為 Visual Editor 是一個所見即所得圖形化編輯器,所以利用它很容易在用戶接口中獲得您想要的外觀和行為。而且,因為它可以在不同的布局管理器之間自動映射,所以您可以使用一個 null 布局來創(chuàng)建您的應用程序外觀,然后切換到一個柵格單元(grid-bag)布局。使用 null 布局能夠容易地準確獲取您想要的布局,柵格單元布局則允許布局在窗口尺寸改變時能夠運行良好。
在下面幾節(jié)中,我們將快速地瀏覽 Visual Editor 0.5 以及它的一些最有趣的特性。如果您想隨同實踐的話,需要安裝 Eclipse 2.1.x 和 Visual Editor 0.5。而且,Visual Editor 還需要另外兩個插件,即 EMF 和 GEF。關于下載鏈接和安裝信息,請參閱 參考資料小節(jié)。
Visual Editor 工具
在安裝完 Visual Editor 之后,下次創(chuàng)建新的 Java 項目時,您將會發(fā)現(xiàn)一些新的特性。假設您已經創(chuàng)建了一個名為 VEPExample 的項目。如果在 Package Explorer 中右擊該項目名并且從上下文菜單中選擇 New,您將會看見一個新的用于創(chuàng)建 Visual Class 的選項。單擊該選項將彈出一個熟悉的對話框,但是具有新的名字:“Create a new Java Class using the Visual Editor”。您還會注意到的另一個差別是有多個單選按鈕和一個用于選擇父類的復選框。一般情況下,您將創(chuàng)建一個 JPanel 來包含應用程序的 UI 元素,然后將該面板添加到 JFrame。為了簡短起見,這里將創(chuàng)建一個框架并且直接向它添加元素。關于開發(fā) Swing 應用程序的更多信息,請參閱 參考資料小節(jié)中列出的系列教程。
為該類輸入一個名字,比如 Test
,并且確保在“Which visual class would you like to extend?”區(qū)域中選中“frame”和“swing”。另外,還在“Which method stubs would you like to create?”下選中 main()
(如圖 1 所示)。
圖 1. 創(chuàng)建新的可視類
選擇完之后,按 Finish創(chuàng)建可視類并使用 Visual Editor 打開它。您將會注意到,與常規(guī)的 Java 編輯器不同,Visual Editor 具有三個不同的部分。頂部是一個圖形化編輯器,其中顯示您的可視類在運行時的可能形狀。左邊是窗口部件的一個列表,這些窗口部件可以被拖放到您的應用程序中。底部是源代碼(見圖 2)。
圖 2. 利用 Visual Editor 編輯 Swing 類
通過向下滾動源代碼并找到 initialize()
方法,您可以看到源代碼和圖形化視圖之間的交互 initialize()
。 方法用于設置應用程序窗口的初始尺寸:
private void initialize() {
this.setSize(300, 200);
this.setContentPane(getJContentPane());
}
|
如果將第一個數(shù)字(即寬度)改變?yōu)橐粋€新值,比如 600,您將看到上面的圖形化表示馬上會改變寬度以反映這個新值。如果您在做大量源代碼的改動,那么可以單擊 Eclipse 狀態(tài)欄中的 Stop Round Tripping按鈕來關閉同步;否則,編輯器有可能會變得沒有您所希望的那樣反應迅速。
除了 Visual Editor 之外,您會注意到 Java 透視圖中還有兩個新的視圖:位于左下部的 Java Beans 視圖和位于右上部的 Properties 視圖。您可能知道,Swing 的設計特性之一是,每個組件,比如您剛才創(chuàng)建的框架類以及添加到它之上的任何其他窗口部件,都是一個 Java Bean。Java Beans 視圖允許您容易地在類中導航到這些組件。最初,在“this”(指當前在 Visual Editor 中的類)之下的惟一入口是 jContentPanel。您可能知道,并不直接向 JFrame 添加組件,而是將組件添加到它的內容面板。單擊 jContentPanel 將指向框架類中的 getJContentPanel()
方法(見圖 3)。
圖 3. Java Beans 視圖
Visual Editor 所增加的另一個視圖是 Properties 視圖,它顯示一個 Java Bean 的屬性。在這里,例如在 JavaBeans 視圖中選擇 jContentPane 之后,您可以改變它所使用的布局管理器。(在這樣做之前,您可能希望在 Editor 窗口中瀏覽一下源代碼,查看它是通過調用帶有一個 java.awt.BorderLayout
對象的 jContentPane.setLayout()
方法來設置布局管理器的。) 一些屬性允許您隨意地輸入文本,但是其他屬性則提供一個更為合適的接口;針對布局管理的屬性使用一個下拉列表,使您只能在有效的布局管理器中進行選擇。單擊缺省值 BorderLAyout,然后向上滾動所顯示的列表并選擇 null 布局管理器(見圖 4)。
圖 4. 選擇 null 布局管理器
在做出該改動之后,您將看到在源代碼中, jContentPane.setLayout()
現(xiàn)在通過一個 null 值被調用。如果您希望自己證實 Properties 視圖和 Editor 之間的交互在兩個方向上都能夠工作,您可以嘗試在源代碼中將 null 改回為新的 java.awt.BorderLayout()
,并且確認在 Properties 視圖中該值自動改變。
創(chuàng)建和啟用用戶接口
一旦已經為您的應用程序創(chuàng)建了一個框架,就可以開始添加窗口部件以允許用戶與您的應用程序進行交互。讓我們添加一個復選框用于開關消息。首先,單擊 JCheckbox 窗口部件,然后在圖形化編輯器中的框架內單擊。如果您使用的是 null 布局管理器,您會注意到可以將它放置在內容面板的任何地方;如果您使用的是 BorderLayout,您可以選擇將它放置在北部、南部、東部、西部或者中部。
接著,單擊 JLabel 窗口部件并在前面所添加的復選框中單擊 Next。使用 Properties 視圖,將文本改為“Unchecked”,然后調整文本框的尺寸使得文本能夠恰好適中。(另一個方法是,首先擴展該框然后單擊左上角;這將打開一個文本域,在這里您可以鍵入文本。)
現(xiàn)在,如果您愿意的話,可以使用調整工具(alignment tool)來整理窗口部件。通過按下 Control 鍵并且依次單擊每個組件來選擇它們,然后單擊 Show Alignment Window按鈕和 Align Top按鈕,如圖 5 所示。
圖 5. 使用調整工具來對齊組件
現(xiàn)在,您的框架看起來應該類似于圖 6 所示。
圖 6. 具有兩個窗口部件的框架
如果您現(xiàn)在開始運行該應用程序,當然不會發(fā)生太多的事情。您可以將該復選框單擊為打開或者關閉,因為 Swing 會為您負責這件事情,但是要想讓它實際做某些事情,您還需要添加一些代碼。如果熟悉 Swing 事件模型,您就知道需要為復選框添加一個活動監(jiān)聽器,從而每當用戶改變它時,監(jiān)聽器都可以執(zhí)行某個動作。要使用 Visual Editor 添加一個監(jiān)聽器,可在圖形化編輯器中右擊該復選框,并且從顯示的上下文菜單中選擇 Events > Action Performed。這將把實現(xiàn)為匿名類的活動監(jiān)聽器的代碼添加到復選框的初始化代碼中:
private javax.swing.JCheckBox getJCheckBox() {
if (jCheckBox == null) {
jCheckBox = new javax.swing.JCheckBox();
jCheckBox.setBounds(45, 75, 21, 21);
jCheckBox
.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent e) {
System.out.println("actionPerformed()");
// TODO Auto-generated Event stub actionPerformed()
}
});
}
return jCheckBox;
}
|
您可以看到,在需要添加代碼的地方已經利用一個 TODO 注釋進行標識。讓我們改動代碼,以便每當復選框發(fā)生變化時,它旁邊的標簽也會發(fā)生變化以反映該復選框的狀態(tài)。在您做出改動之后,新的代碼看起來應該是這樣的:
jCheckBox
.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent e) {
jLabel.setText(
jCheckBox.isSelected() ? "Checked" : "Unchecked");
}
});
|
現(xiàn)在到了測試應用程序的時候了。
運行 Visual Class
Visual Editor 可以讓您方便地啟動 Java Bean,而不需要一個 main()
類。當您正在測試一個組件(比如 JPanel),而該組件與最終將要包含它的應用程序相分離的時候,這會特別方便。要以這種方式啟動您創(chuàng)建的簡單測試應用程序,請確保在 Editor 中已經選中 Test.java
,然后從 Eclipse 主菜單中選擇 Run > Run As > Java Bean。
另一個方法是,由于這是一個 JFrame,您還可以通過像下面這樣完成 main()
方法,來將 Test 作為一個 Java 應用程序運行:
public static void main(String[] args) {
Test test = new Test();
test.setDefaultCloseOperation(EXIT_ON_CLOSE);
test.setVisible(true);
}
|
從主菜單中選擇 Run > Run As > Java Application來運行它。無論以哪種方式運行它,您都應該看到,每當單擊該復選框時,標簽就會相應地發(fā)生變化。
如果您并沒有在 Eclipse 中跟著實踐,但是希望看到代碼的樣子,您可以使用 參考資料中提供的鏈接下載它。
了解 Visual Editor 1.0 中的 SWT 支持
在撰寫本文的時候,Visual Editor 1.0 的初步版本(preliminary build)提供對于 SWT 支持的預覽,盡管最終的版本有可能是不同的。這里我們將快速地來了解一下,但是注意如果您使用的是一個更新的版本,您可能需要做出調整。
當您下載一個非發(fā)布版本(non-release build)的 Visual Editor 1.0 時,例如我們這里所使用的 I20040325 集成版本(integration build),則還需要下載相應的 Eclipse、EMF 和 GEG 版本(build)。這些并不一定要是發(fā)布版本(release build),并且您不能混合和匹配版本。VEP 下載頁面(請參閱 參考資料)將指定需要哪些版本并且包含指向這些版本的鏈接。
當安裝完 Eclipse、Visual Editor、EMF 和 GEF 之后,啟動 Eclipse,并創(chuàng)建一個新的 Java 項目。為了使用 SWT,您需要將 SWT 庫添加到項目的 Java 構建路徑。右擊該項目并選擇 Properties > Java Build Path。單擊 Libraries 選項卡,單擊 Add Library按鈕,選中 Standard Widget Toolkit (SWT),然后單擊 Next。在下一個對話框中,接受缺省的“Use Platform SWT Level”并單擊 Finish。單擊 OK關閉屬性對話框。
與前面一樣,通過右擊該項目并選擇 New > Visual Class來創(chuàng)建一個新的 Visual Class。為該類輸入名字,比如 SWTTest
。然而,在這里并不選擇“frame”作為要擴展的可視類,而是選擇“other”。另外,還必須確保父類是 java.lang.Object
,并且在“Which method stubs would you like to create?”下面選中 main()
方法旁邊的復選框(見圖 7)。
圖 7. 創(chuàng)建 SWT 可視類
開始,圖形化編輯器的畫布是空的。為了創(chuàng)建應用程序,您需要添加一個 SWT shell。您應該發(fā)現(xiàn)在 Visual Editor 左側的窗口部件選項板中包含一個 SWT 窗口部件的選擇項(除了 AWT 和 Swing 窗口部件之外)。單擊 Shell,然后在畫布上單擊并拖動以創(chuàng)建應用程序窗口(見圖 8)。
圖 8. 將 SWT shell 添加到圖形化編輯器
現(xiàn)在,您可以給 shell 添加窗口部件了。這里我只是添加單個文本域。單擊 Text,然后在 shell 中單擊并拖動以放置該文本域。單擊該域的左上角以添加一些文本,比如“Hello, SWT!”。
圖 9. Hello, SWT!
在完成這些步驟之后,您將發(fā)現(xiàn) Visual Editor 已經創(chuàng)建了一個 createSSHell()
方法,該方法按照如下方式初始化 shell:
private void createSShell() {
sShell = new org.eclipse.swt.widgets.Shell();
text = new org.eclipse.swt.widgets.Text(sShell,
org.eclipse.swt.SWT.NONE);
sShell.setSize(new org.eclipse.swt.graphics.Point(209, 85));
text.setBounds(new org.eclipse.swt.graphics.Rectangle(23,
9, 153, 27));
text.setText("Hello, SWT!");
}
|
接著,我們需要向 main()
方法添加一些代碼,以便實例化該類并且運行 SWT 代碼:
public static void main(String[] args) {
SWTTest test = new SWTTest();
Display display = new Display();
test.createSShell();
test.sShell.open();
while (!test.sShell.isDisposed()) {
if (!display.readAndDispatch())
display.sleep();
}
System.out.println("finishing...");
display.dispose();
}
|
在鍵入這些代碼之后,您可以在源代碼窗口中右擊并選擇 Source > Reorganize Imports,以解析對 Display 的引用。
為了運行該應用程序,您需要添加一個平臺特定的 SWT 共享庫或者 DLL 到您的路徑。一種方式是使用啟動配置。從 Eclipse 主菜單中選擇 Run > Run...,然后在所顯示的對話框中單擊 Arguments 選項卡。在 VM arguments 框中,添加一個帶有庫路徑的 -D 參數(shù);在 Windows 中,如果您已經將 Eclipse 安裝到 C:\eclipse
,那么完整的參數(shù)將是: -Djava.library.path=C:\eclipse\plugins\org.eclipse.swt.win32_3.0.0\os\win32\x86
。見圖 10。
圖 10. 將到 Windows SWT DLL 的路徑添加到啟動配置
在輸入該參數(shù)之后,單擊 Run啟動 SWT 應用程序。如果一切都正確的話,應用程序窗口將打開并且?guī)в小癏ello, SWT!”消息,如圖 11 所示。
圖 11. “Hello, SWT!”應用程序窗口
結束語
Visual Editor 項目將期待已久的 GUI 構造器添加到 Eclipse。最初的 0.5 版本包括對于 AWT/Swing 的支持,在 GUI 開發(fā)方面它甚至使 Eclipse 與其他 IDE 具有同等的地位。下一個版本 1.0,預期很快就會推出并且將會包括熱切期盼的 SWT 支持。除了這些之外,其他還是不確定的,但是由于它的可靠的技術基礎,許多事情,包括對于其他編程語言和工具集的支持,都是有可能的。
參考資料
關于作者 David Gallardo 是 Studio B 的作者,他是一名獨立軟件顧問和作家,擅長于軟件國際化、Java Web 應用程序和數(shù)據庫開發(fā)。他成為專業(yè)軟件工程師已經有 15 年多了,他擁有許多操作系統(tǒng)、編程語言和網絡協(xié)議的經驗。他最近在一家 B2B 電子商務公司 TradeAccess, Inc.從事先進的數(shù)據庫和國際化開發(fā)。在這之前,他是 Lotus Development Corporation 國際產品開發(fā)部的高級工程師,負責開發(fā),用于為 Lotus 產品(包括 Domino)提供 Unicode 和國際化語言支持的跨平臺庫。David 還與人合著了 Eclipse In Action: A Guide for Java Developers (Manning, 2003)。可以通過 david@gallardo.org 與他聯(lián)系。 |
轉自:
http://www-128.ibm.com/developerworks/cn/linux/opensource/os-ecvisual/