一個用於構建圖形介面的圖形化工具
與許多 Eclipse.org 項目類似,Visual Editor 項目的目標是構建一個用於構建工具(在這裡是用於構建圖形使用者介面的工具)的工具。關於 Visual Editor 項目最有趣的事情是它已經發布了一個參考實現。Visual Editor 版本 0.5 是用於構建 AWT/Swing 應用程式的 GUI 構建器,這是一個期待已久的 Eclipse 特性。在很快就要發布的、預定在 2004 年中期提交的 1.0 版中,將增加對於 SWT 的支援。在本文中,您將獲得關於 Visual Editor 及其背後技術的概覽,以及 Visual Editor 0.5 用於構建 AWT/Swing 應用程式的特性的一個簡短示範,以及關於 Visual Editor 1.0 中的 SWT 支援的預覽。
Eclipse Visual Editor 項目介紹
仔細閱讀關於 Eclipse 及其競爭者的優缺點的任何討論線索,您將會發現關於各種特性的提示資訊,這些特性在其中各方互有優劣,或者完全缺乏。直到最近,對於 Eclipse,似乎經常被提起的事情是它缺少 GUI 構建器:一個用於構建圖形使用者介面的圖形化工具。值得高興的是,通過 2003 年 11 月發起的 Eclipse Visual Editor 項目以及隨後 Visual Editor 0.5 的迅速發布,這種情況已經得到彌補。Visual Editor 0.5 允許您通過一個完全的 WYSIWYG(所見即所得 (WYSIWYG))圖形化編輯器來建立 AWT/Swing 應用程式。
與 Eclipse 自身類似,Visual Editor 也基於 IBM 的代碼貢獻。熟悉 Websphere Studio Application Developer 5.x 中的 Visual Editor 的開發人員將會發現 Eclipse 的 Visual Editor 幾乎與之完全相同。要想瞭解如何使用 Visual Editor,請參閱 Websphere Studio Visual Editor 文檔,該文檔在本文末尾的 參考資料一節中列出。
與 Eclipse.org 組織下的許多其他項目(包括 Eclipse)類似,Visual Editor 項目所確定的目標是非常宏偉的:構建一個用於構建圖形化編輯工具的工具。儘管最初發行版中對於 AWT/Swing 的支援已經完成,但是 Visual Editor 的計劃遠不止於此。技術基礎進行中重新設計,從而使得它對於程式設計語言和所支援的圖形工具集來說是不相關的。
在將來,您會看到除了 AWT/Swing 以外的其他的 Visual Editor 實現(比如 SWT),以及潛在的除了 Java 語言以外的其他語言的實現(比如 C++)。有關增加 SWT 支援的工作已經在進行之中,事實上,這將會包括在 Visual Editor 版本 1.0 中,預定在 2004 年中期,大概與 Eclipse 3.0 同期完成。
回頁首 Visual Editor 的內幕
Visual Editor 的第一個具體實現,作為一個針對 AWT/Swing 的 GUI 構建器,對於 GUI 開發人員來說已經是足夠令人滿意的了,但是如果您是那種希望瞭解內幕的開發人員,那麼還可以看到許多東西:Visual Editor 利用一些非常有趣的技術,這些技術本身都是有用的。如果您對於構建自己的圖形化編輯器或者對工具建模感興趣的話,那麼現有的 Visual Editor 實現對於您可以完成的事物來說只是一個線索。
Visual Editor 所利用的最為明顯的工具是 GEF,即圖形化編輯架構(Graphical Editing Framework)。GEF 建立於本地 Eclipse 圖形化工具集 SWT 之上,以使得開發一個圖形化編輯器或者所見即所得 (WYSIWYG)文字編輯器更為容易。如果您熟悉 SWT (或者 AWT/Swing,在這方面它們是類似的)中的圖形原語,那麼您會知道繪製和處理任意的形狀(比如矩形、箭頭和橢圓)是比較困難的,更不用說管理它們之間的關係以及它們所代表的資料模型了。
GEF 被劃分為兩個部分:第一部分是 Draw2D 外掛程式,這是一個輕量級的繪圖和呈現包,用於協助您繪製圖形。第二部分是 GEF 外掛程式,除了其他工具以外,這一部分中還增加了選擇和建立工具、工具選項板,以及用於在資料模型和視圖之間進行映射的控制器架構。
GEF 是一個模型無關的架構,但是作為 Visual Editor (以及其他產生代碼的圖形化工具)的一部分,它在後台使用 Eclipse 建模架構(Eclipse Modeling Framework, EMF),以在模型、Java 類和圖形化表示之間進行映射,其中模型是使用 XML 中繼資料交換(XML Metadata Interchange, XMI)在內部儲存的。EMF 的重要特性之一是它確保所有這些映射都是一對一的;所以儘管 XMI 可以被認為是模型的標準表示,但是在代碼和圖形之間來回切換並不會丟失任何資訊。這就是為什麼 Visual Editor 只需要儲存模型的一種表示(即 Java 原始碼),以及開發人員可以自由地在圖形化編輯器之外編輯該原始碼的原因。
要更多地瞭解 GEF 和 EMF,請參閱本文 參考資料小節中的連結。
回頁首 利用 Visual Editor 開發 AWT/Swing 應用程式
正如前面所提到的,目前可用的版本 0.5 是一個完全的 AWT/Swing GUI 構建器。它與 Eclipse 2.1.x 共同工作,並且與其他 IDE 中的 GUI 構建器相比毫不遜色。首先,它產生高品質的代碼,可以與一個有經驗的 GUI 開發人員通過手工開發的代碼相媲美,並且不帶有使得修改變得困難的特殊工件(artifact)。其次,它強大的分析能力允許完全的代碼來迴轉換,因此對原始碼的修改幾乎立即反映在圖形化編輯器中。
在手工構建 Swing 應用程式時,最為乏味的任務之一就是使用布局管理器來管理組件的位置。因為 Visual Editor 是一個所見即所得 (WYSIWYG)圖形化編輯器,所以利用它很容易在使用者介面中獲得您想要的外觀和行為。而且,因為它可以在不同的布局管理器之間自動對應,所以您可以使用一個 null 布局來建立您的應用程式外觀,然後切換到一個柵格單元(grid-bag)布局。使用 null 布局能夠容易地準確擷取您想要的布局,柵格單元布局則允許布局在視窗尺寸改變時能夠運行良好。
在下面幾節中,我們將快速地瀏覽 Visual Editor 0.5 以及它的一些最有趣的特性。如果您想隨同實踐的話,需要安裝 Eclipse 2.1.x 和 Visual Editor 0.5。而且,Visual Editor 還需要另外兩個外掛程式,即 EMF 和 GEF。關於下載連結和安裝資訊,請參閱 參考資料小節。
回頁首 Visual Editor 工具
在安裝完 Visual Editor 之後,下次建立新的 Java 項目時,您將會發現一些新的特性。假設您已經建立了一個名為 VEPExample 的項目。如果在 Package Explorer 中右擊該項目名並且從操作功能表中選擇 New,您將會看見一個新的用於建立 Visual Class 的選項。單擊該選項將彈出一個熟悉的對話方塊,但是具有新的名字:“Create a new Java Class using the Visual Editor”。您還會注意到的另一個差別是有多個選項按鈕和一個用於選擇父類的複選框。一般情況下,您將建立一個 JPanel 來包含應用程式的 UI 元素,然後將該面板添加到 JFrame。為了簡短起見,這裡將建立一個架構並且直接向它添加元素。關於開發 Swing 應用程式的更多資訊,請參閱 參考資料小節中列出的系列教程。
為該類輸入一個名字,比如 Test ,並且確保在“Which visual class would you like to extend?”地區中選中“frame”和“swing”。另外,還在“Which method stubs would you like to create?”下選中 main() (如圖 1 所示)。 圖 1. 建立新的可視類
選擇完之後,按 Finish建立可視類並使用 Visual Editor 開啟它。您將會注意到,與常規的 Java 編輯器不同,Visual Editor 具有三個不同的部分。頂部是一個圖形化編輯器,其中顯示您的可視類在運行時的可能形狀。左邊是視窗組件的一個列表,這些視窗組件可以被拖放到您的應用程式中。底部是原始碼(見圖 2)。 圖 2. 利用 Visual Editor 編輯 Swing 類
通過向下滾動原始碼並找到 initialize() 方法,您可以看到原始碼和圖形化視圖之間的互動 initialize() 。 方法用於設定應用程式視窗的初始尺寸:
private void initialize() { this.setSize(300, 200); this.setContentPane(getJContentPane()); }
如果將第一個數字(即寬度)改變為一個新值,比如 600,您將看到上面的圖形化表示馬上會改變寬度以反映這個新值。如果您在做大量原始碼的改動,那麼可以單擊 Eclipse 狀態列中的 Stop Round Tripping按鈕來關閉同步;否則,編輯器有可能會變得沒有您所希望的那樣反應迅速。
除了 Visual Editor 之外,您會注意到 Java 透視圖中還有兩個新的視圖:位於左下部的 Java Beans 視圖和位於右上部的 Properties 視圖。您可能知道,Swing 的設計特性之一是,每個組件,比如您剛才建立的架構類以及添加到它之上的任何其他視窗組件,都是一個 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() 現在通過一個 null 值被調用。如果您希望自己證實 Properties 視圖和 Editor 之間的互動在兩個方向上都能夠工作,您可以嘗試在原始碼中將 null 改回為新的 java.awt.BorderLayout() ,並且確認在 Properties 視圖中該值自動改變。
回頁首 建立和啟用使用者介面
一旦已經為您的應用程式建立了一個架構,就可以開始添加視窗組件以允許使用者與您的應用程式進行互動。讓我們添加一個複選框用於開關訊息。首先,單擊 JCheckbox 視窗組件,然後在圖形化編輯器中的架構內單擊。如果您使用的是 null 布局管理器,您會注意到可以將它放置在內容面板的任何地方;如果您使用的是 BorderLayout,您可以選擇將它放置在北部、南部、東部、西部或者中部。
接著,單擊 JLabel 視窗組件並在前面所添加的複選框中單擊 Next。使用 Properties 視圖,將文本改為“Unchecked”,然後調整文字框的尺寸使得文本能夠恰好適中。(另一個方法是,首先擴充該框然後單擊左上方;這將開啟一個文本域,在這裡您可以鍵入文本。)
現在,如果您願意的話,可以使用調整工具(alignment tool)來整理視窗組件。通過按下 Control 鍵並且依次單擊每個組件來選擇它們,然後單擊 Show Alignment Window按鈕和 Align Top按鈕,如圖 5 所示。 圖 5. 使用調整工具來對齊組件
現在,您的架構看起來應該類似於圖 6 所示。 圖 6. 具有兩個視窗組件的架構
如果您現在開始運行該應用程式,當然不會發生太多的事情。您可以將該複選框單擊為開啟或者關閉,因為 Swing 會為您負責這件事情,但是要想讓它實際做某些事情,您還需要添加一些代碼。如果熟悉 Swing 事件模型,您就知道需要為複選框添加一個活動監聽器,從而每當使用者改變它時,監聽器都可以執行某個動作。要使用 Visual Editor 添加一個監聽器,可在圖形化編輯器中右擊該複選框,並且從顯示的操作功能表中選擇 Events > Action Performed。這將把實現為匿名類的活動監聽器的代碼添加到複選框的初始化代碼中:
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 注釋進行標識。讓我們改動代碼,以便每當複選框發生變化時,它旁邊的標籤也會發生變化以反映該複選框的狀態。在您做出改動之後,新的代碼看起來應該是這樣的:
jCheckBox .addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent e) { jLabel.setText( jCheckBox.isSelected() ? "Checked" : "Unchecked"); } });
現在到了測試應用程式的時候了。
回頁首 運行 Visual Class
Visual Editor 可以讓您方便地啟動 Java Bean,而不需要一個 main() 類。當您正在測試一個組件(比如 JPanel),而該組件與最終將要包含它的應用程式相分離的時候,這會特別方便。要以這種方式啟動您建立的簡單測試應用程式,請確保在 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來運行它。無論以哪種方式運行它,您都應該看到,每當單擊該複選框時,標籤就會相應地發生變化。
如果您並沒有在 Eclipse 中跟著實踐,但是希望看到代碼的樣子,您可以使用 參考資料中提供的連結下載它。
回頁首 瞭解 Visual Editor 1.0 中的 SWT 支援
在撰寫本文的時候,Visual Editor 1.0 的初步版本(preliminary build)提供對於 SWT 支援的預覽,儘管最終的版本有可能是不同的。這裡我們將快速地來瞭解一下,但是注意如果您使用的是一個更新的版本,您可能需要做出調整。
當您下載一個非發布版本(non-release build)的 Visual Editor 1.0 時,例如我們這裡所使用的 I20040325 整合版本(integration build),則還需要下載相應的 Eclipse、EMF 和 GEG 版本(build)。這些並不一定要是發布版本(release build),並且您不能混合和匹配版本。VEP 下載頁面(請參閱 參考資料)將指定需要哪些版本並且包含指向這些版本的連結。
當安裝完 Eclipse、Visual Editor、EMF 和 GEF 之後,啟動 Eclipse,並建立一個新的 Java 項目。為了使用 SWT,您需要將 SWT 庫添加到項目的 Java 構建路徑。右擊該項目並選擇 Properties > Java Build Path。單擊 Libraries 選項卡,單擊 Add Library按鈕,選中 Standard Widget Toolkit (SWT),然後單擊