當Abacus Research AG
一家商業軟件開發公司
決定將開發平台從 Borland 的 Delphi 轉向Java Swing時
它發現自己站在了軟件開發的十字路口
我們大量的應用程序開發團隊擁有多年的Delphi GUI開發經驗
卻沒有任何的Java/Swing 經驗
並且我們需要在極短的時間內將大量的Delphi應用程序轉換為Swing
在研究了當時可用的GUI工具後
我們覺得我們應該通過贊助一個GPL開源Java GUI編譯器來達到自己的目標
而且這個編譯器還可以幫助其他的應用程序開發者面對相同的挑戰
AbaGUIBuilder
Abacus Java GUI編譯器被設計用來實現輕松地從VB或Delphi開發轉向Java Swing
這一策略幫助Abacus Research實現了其Java版應用程序的交付
縮短了開發時間
使其開發人員把精力投向商業應用
而不是Swing框架的錯綜復雜
如圖
所示
AbaGUIBuilder有能夠在許多其他開發環境如VB和Delphi找到的要素
位於視窗左上角是活動對象樹
其下是Swing組件選擇區
位於視窗的中上部是開發面板
或者說是
畫布
在這裡放入Swing組件將其實例化
在右上部是屬性編輯器
下部是事件面板
包括兩個制表符頁
分別是事件代碼編輯器
為每個單獨的可視對象添加事件代碼
和消息面板
顯示AbaGUIBuilder的狀態消息
圖 Abacus GUI編譯器
為什麼做我們自己的GUI工具?
為什麼我們選擇寫自己的工具?開始我們決定我們的工具應該包括以下五個要求
容易使用
不需要布局管理器的使用經驗
不需要Swing的使用經驗
不需要輸出Swing代碼
實現商業邏輯與UI的分離
我們在評估當時可用的GUI開發工具時發現好的IDE都是手寫Swing代碼這就不符合我們的第一個和最關鍵要求
我們定義的容易使用是指任一開發者不管他/她的Java Swing經驗都具有在幾分鐘而不是幾小時內開發一個可運行的GUI表單因此就要是開發者的精力集中在商業邏輯上而不是框架的細節一開始我們的開發者就需要所見即所得的環境以便能夠真實地感知當應用程序發布的時候的情況這一功能的實現節省了開發者的大量時間但當時我們評估的工具沒有一個能夠實現這個功能設計的屏幕與輸出的屏幕並不一樣還有糟糕的調度算法對我們來說簡直就是巨大的倒退AbaGUIBuilder通過預覽模式來實現這一功能你可以在開發時看到它運行起來的樣子
為什麼Abacus Research要求UI和商業邏輯的分離?因為企業要處理不斷變換的政府規則例如稅收和工資計算我們需要在一個獨立的包裝模塊裡維護規則和公式時保持UI不變的能力使得當公式改變時應用程序JAR(UI)並不需要變化因此只有改變的公式需要測試使得發布的進程簡單化
為了滿足這個需求我們設計的GUI編譯器將應用程序和事件匯編到一個應用程序JARJAR隱藏了所有的GUI Swing 代碼並且通過一個renderer類(AdaRenderer)在運行時來執行應用程序
不需要Swing經驗
為了確保開發工具能夠做到真正的所見即所得我們決定采用類似Delphi和VB中用XY坐標來定位的布局管理方式采用這種方式Swing JFrame就是一個畫布開發者可以將Swing組件放入JFrame的XY布局中有了XY布局管理器我們的開發者不需要理解Swing中並不熟悉的復雜的布局管理器這樣我們的應用程序開發者就可以把精力集中到應用程序UI和它的商業邏輯中
事實上AbaGUIBuilder包含了大部分的Swing可視組件從面板到制表符頁還有對菜單﹑菜單項帶有Java數據庫連接的數據庫感知組件JFreeChart組件的支持和導入第三方可視類庫的能力所有這些組件都可以從組件選擇區拖入一個空框架來開發你的GUI應用程序
示例項目: 跟蹤開發商的聯絡信息
最佳的展示AbaGUIBuilder RAD(快速應用程序開發)的方式就是開發一個帶有菜單欄的多文本制表符面板的示例程序首先你必須通過在組件選擇區選擇JFrame將其拖入應用程序畫布中來實現將JFrame對象放入空的表單面板中然後將所有的可視組件托在JFrame上注意當你開始一個新的項目時必須先放入JFrame使其成為你的對象畫布見圖
圖 應用程序JFrame 作為畫布 點擊縮略圖查看完整圖
其次增加一個制表符格和兩個制表符頁在組件選擇區的容器區內選擇JTabbedPane將其拖入JFrame當JTabbedPane放置好後右鍵在彈出菜單中選擇 Add JATabPage在面板上增加兩個制表符頁如圖
圖 增機制表符頁: 右鍵制表符頁選擇Add JATabPage
然後在屬性欄中選擇TabTitle為每個制表符頁設置標題
圖可以放入Swing組件的空制表符頁
這時你已經有了兩個空的制表符頁你可以從組件選擇區選擇任意的Swing組件放入其中在我們的例子中開發者制表符頁中包含兩個屏面上面有一系列的JLabel和JTextField對象你能夠很快的開發出一個類似圖的應用程序作為一個可視化應用程序開發者你能夠體會到使用Abacus GUI編譯器能給你開發復雜的GUI應用程序所帶來的方便
圖 短時開發的應用程序
編譯器帶的透視圖模式是一個很有用的特征因為它能夠預覽運行時的應用程序通過選擇工具欄的Run選項或者按F鍵即可進入透視圖模式
圖 所見即所得: 開發時檢查視覺效果
這時保存你的工作按下CtrlS或者選擇Save選項給項目起名叫devteam將其保存到示例目錄中在你保存完項目後打開AbaGUIBuilder的示例目錄打開文件devteamprojproj文件是一個XML文件其中定義了應用程序中的所有類對象對象的性質甚至是代碼這是一個對你的可視項目的表達平台
增加事件句柄
為每個對象增加事件句柄是一個直截了當的過程你所要做的就是點擊對象從事件列表中選擇你希望中斷產生的事件並為事件填寫合適的Java代碼再一次證明AbaGUIBuilder的設計符合Delphi和VB的模式我們的目標是對應用程序開發者隱藏UI的實現例如事件監聽器等舉個例子如圖為了實現按下Exit(退出)按鈕時彈出一個確認對話框首先選擇Exit按鈕的actionPerformed事件然後填入如下Java代碼
圖 為可視化組件增加事件句柄
切記事件句柄在IDE透視圖模式下並不能使用只有在運行時才被激活所以你必須編譯運行應用程序才能檢查結果
可視化地增加一個菜單和菜單項是另一個強大的並節省時間的特征你所要做的就是從組件選擇區選擇JMenuBar並將其放在框架的任意地方JMenuBar一般放在頂部且XY坐標無關然後右鍵點擊JMenuBar彈出一個彈出框如圖為菜單增加JMenuJMenuItem(s)和事件句柄
圖 可視化增加菜單和菜單項
然後復制Exit按鈕的actionPerformed事件代碼到Exit菜單項中使得不管選擇Exit按鈕還是Exit菜單項都回彈出一樣的確認對話框最後點擊工具欄中的Save(With Compile)現在你完成了你的第一個AbaGUIBuilder應用程序
代碼到哪裡去了?
我們經常聽到這樣的問題代碼去哪了?AbaGUIBuilder並不是不創造Java代碼只不過是編譯器內部生成的Java代碼不被看到和用到而已GUI編譯器通過運行獨立的包裝程序(renderer)將內部代碼編譯到應用程序的jar文件中事實上你可以在\bin\output目錄下檢測AbaGUIBuilder產生的Java代碼但是切記這些代碼並使被外部使用的它只不過作為一個輔助工具當編譯器生成的代碼萬一有問題時使用
生成項目文件(proj)後GUI編譯器生成兩個文件你的應用程序jar文件和decl文件隨後當你寫包裝器文件時decl文件會有幫助它包含了所有的對象定義和一個通用入口函數getReferences()並且它將UI表單的所有可視元素寫為私有變量我們可以使用decl文件程序段中的這些私有變量實現商業邏輯和UI的分離
開發過程中我們推薦你使用例子文件夾中的runproz腳本來運行你的應用程序jar文件這個腳本文件設置了classpath填交了所有需要的JAR使用示例Java包裝器來運行應用程序JAR如圖當你運行devteam應用程序時命令如下runproz \abaguibuilder\samples\devteamjar
圖 部署應用程序
理解runproz的機制很重要雖然很簡單讓我們注意下行%JAVA_HOME%\bin\javaexe exec %
exec是示例包裝器AbaRenderer提供的默認加載機制參數%指的是AbaGUIBuilder應用程序JAR的名字當JAR的路徑和名字傳給execjava時它將加載和運行指定的應用程序JAR這就是應用程序JAR運行的機制
編寫自己的包裝器
AbaRenderer包裝器是一個用AbaRenderer 對象來加載應用程序jar的Java程序包裝器是一個僅僅需要幾行代碼的簡單程序
public class exec
{
public static AbaRenderer m_AbaRenderer ;
// Assignments for this user interface
public static void main(String[] args)
{
String docname = new String(args[]);
try
{
Systemoutprintln(Loading + docname);
m_AbaRenderer = new AbaRenderer(docname true null);
boolean bTestLoad = m_AbaRendererload();
if(bTestLoad)
m_AbaRendererrenderInterface(); }
catch(Exception e)
{eprintStackTrace();}
}
}
當部署應用程序時
你可以選擇使用runproz和示例包裝器來發布它
也可以使用你自己寫的包裝器和classpath
當你需要為你的包裝器增加其它的一些特征時我們推薦你編寫自己的包裝器
例如
使用第三方程序庫的監聽器
手工初始化對象
為組合框增加代碼
或者最後將UI從業務邏輯中分離出來等
將業務邏輯從UI中分離出來 為了將應用程序的UI和業務邏輯分離開
你必須寫自己的包裝器
一個分離的簡單例子就是在開發工具和項目以外
通過包裝器手工地初始化應用程序的可視組件
當你再次調用時
GUI編譯器生成一個聲明文件
這個文件有一個訪問方法可以初始化一系列私有變量
這些私有變量是表單上可視對象的引用
getReferences()方法允許開發者訪問和操作表單上的任一可視組件
下面的exec
程序在第一個制表符位置初始化了一個組合框
示范了一個簡單的應用程序UI和業務邏輯的分離
public class exec
{
public static AbaRenderer m_AbaRenderer ;
// Declarations of variables for this user interface
……
private JComboBox JStComboBox;
// Assignments for this user interface
public void getReferences()
{
…
//Loads the visual object JComboBox to private data JComboBox
JStComboBox= (JComboBox)m_AbaRenderergetObject(JComboBox);
…
}
// Assignments for this user interface
public static void main(String[] args)
{
String docname = new String(args[]);
try
{
Systemoutprintln(Loading + docname);
m_AbaRenderer = new AbaRenderer(docname true null);
boolean bTestLoad = m_AbaRendererload();
if(bTestLoad)
{
m_AbaRendererrenderInterface();
getReferences();
// Sample access to objects
JStComboBoxaddItem(FL);
JStComboBoxaddItem(CA);
JStComboBoxaddItem(WA);
JStComboBoxaddItem(MD);
JStComboBoxaddItem(PA);
}
}
catch(Exception e)
{
eprintStackTrace();
}
}
}
上面例子演示了一個簡單清晰的UI和業務邏輯的分離明顯的優勢就是你可以輕松地改變初始化例程而不需要改變應用程序UI你將發現當你的應用程序變得越來越大越來越復雜時這一特征越來越重要——對於所有的開發項目而言這將是一個值得效仿的做法
結論
AbaGUIBuilder最初是為了滿足我們的Delphi應用程序開發者的需要而設計的節省了很多開發時間而且是我們的GUI開發轉換變得容易對於其他的大多數Delphi和VB的開發者而言它也能做得很好
資源
·下載本文源代碼: /abacus/jwabacuszip
·下載AbaGUIBuilder:
·Screen shots和其他文章:
·Abacus 研究:
·更多關於GUI開發的文章請浏覽JavaWorld文章列表的用戶界面設計部分: _content/jwuiindexshtml
·GUI編程論壇:?forumId=
From:http://tw.wingwit.com/Article/program/Java/hx/201311/25630.html