實例詳解NetBeans和Swing平臺開發(fā)
筆者和很早就開始使用 Java 的大多數(shù)人一樣,我最初接觸這項技術(shù)是使用(小型)桌面應(yīng)用程序的時候:它們是我讀博士期間的一些研究素材和一個衛(wèi)生保健呼叫中心的簡單控制面板。那時是 AWT 時代,能做的事有限。因此我很快就轉(zhuǎn)到了服務(wù)器這邊,這邊的系統(tǒng)似乎更強健、更有發(fā)展。事實確實如此。我在這次領(lǐng)域工作了很長時間,并且成為一名 J2EE 架構(gòu)師。
幾年之后,由于對數(shù)字?jǐn)z影熱情的不斷高漲,我又重新被吸引到桌面。我仍然遇到了許多問題,但是就在我即將放棄的時候,Sun 和開發(fā)人員社區(qū)推出的 SwingLabs、java.net 和新版本的 NetBeans 把我從困難中解救出來。現(xiàn)在,我正在熱衷于使用一個(可能是)富有前途的開放源碼應(yīng)用程序 blueMarine,這個程序基于 NetBeans 平臺。
在本文中,我將告訴您有關(guān) blueMarine 的更多故事,并且回顧一些主要的 NetBeans 擴展 API。我將介紹如何使用和自定義這些 API,同時指出我曾經(jīng)面臨的問題以及解決這些問題的方法。如果您對NetBeans和Swing知之甚少,而您又需要接觸各種各樣的客戶端應(yīng)用程序,我認(rèn)為您應(yīng)該好好閱讀這篇文章。
開始
2001 年前后,由于厭倦了使用 OpenOffice 電子表格,我***次編寫了一些 Java 代碼,用于管理我的照片。我將所有內(nèi)容導(dǎo)出到 XML 并且利用 XSLT 轉(zhuǎn)換,確定了我自己的數(shù)據(jù)庫格式,通過基于 Swing 的一個非常簡單的圖形用戶界面進行管理。
在 2003 年夏天,我在數(shù)碼相機世界有了較大的飛躍,購買了 Nikon D100(專業(yè)的 SLR)。那個夏天是意大利本世紀(jì)最炎熱的夏天,因此我不得不***程度地減少拍照旅行的數(shù)量:外出散步也是受罪。我不得不待在家里,盡管托斯卡納鄉(xiāng)村的環(huán)境能令人放松,因此,大部分假期我都在學(xué)習(xí) NEF 格式。
當(dāng)時,NEF 是一種“原始數(shù)據(jù)文件格式”,并且?guī)缀鯖]有公開。原始數(shù)據(jù)文件格式包含的數(shù)據(jù)直接來自于相機 CCD 傳感器,未經(jīng)過處理。如果要將它轉(zhuǎn)換為質(zhì)量比較好的圖片,還需要對數(shù)據(jù)進行處理。這通常認(rèn)為這一過程是舊式潮濕暗室相片成像的數(shù)字過程。我從來沒有擁有過自己的潮濕暗室,我為“數(shù)字沖洗”照片而入迷,開始為此編寫了一些 Java 代碼。
夏天快結(jié)束的時候,我創(chuàng)建了一個簡單的能夠顯示照片的微型導(dǎo)航程序—— blueMarine 就此誕生了。一年之后,這個項目便能夠用編錄設(shè)備標(biāo)記照片,并且能夠在網(wǎng)上發(fā)布圖片庫。
但是,讓我非??鄲赖氖?,我需要多個軟件來執(zhí)行編輯、打印、編錄、歸檔以及 Web 發(fā)布任務(wù)。因此我著手開始研究在一個應(yīng)用程序中實現(xiàn)所有這些工作流程。同時,我認(rèn)為是時候公開發(fā)布 blueMarine 了,因此***個 alpha 版本發(fā)布到了 GPL License(后來更改為 Apache 2.0)支持下的 SourceForge 。
另一個推動力是在臺式計算機上挑戰(zhàn)使用 Java 對數(shù)字圖像進行處理。對于我來說,Java 在科學(xué)圖像處理方面的優(yōu)勢已經(jīng)非常明顯;例如, NASA 的工程師們已經(jīng)成功使用了 JAI,它是一種高級成像的 API。但是,對于普通攝影師來說,桌面處理包含哪些內(nèi)容呢?自從成為 Java 顧問 10 多年來,證明 Java 在各種各樣的應(yīng)用程序方面的優(yōu)勢一直是我追求的目標(biāo)。
挫折
雖然開始時熱情高漲,但是在 2005 年底,我在這個項目上受到了很大的打擊。性能不是大問題,但是,在使用 plain Swing 開發(fā)豐富的 GUI 應(yīng)用程序時,我遇到了困難。Swing 是一個非常出色的 API,但是當(dāng)您使用它構(gòu)建復(fù)雜的應(yīng)用程序時,您會發(fā)現(xiàn)仍然需要增加很多功能。
實現(xiàn)這些缺少的部分并不是前言科學(xué),但是這項工作浪費了很多寶貴的時間。再次舉例來說明這個問題,例如構(gòu)建菜單、以上下文相關(guān)的方式啟用操作、為內(nèi)部窗口定義靈活的、可在工作時停靠的機制等等,并且您將發(fā)現(xiàn)自己的大部分時間都花費在編寫通用的 GUI 組件上,而沒有花費在應(yīng)用程序的核心內(nèi)容上。
直到最近,才有了幾個處理此類問題的開放源碼庫,但是大部分庫都不太令人滿意,而且也很難集成。還有幾個較早版本的 NetBeans,但是我不滿意它們的性能。也可以選擇 Eclipse 和 SWT,但是我覺得我并沒有真正地仔細(xì)研究完全的替代方法和非標(biāo)準(zhǔn)的 API,我采用的學(xué)習(xí)投資回報低,繼承 Swing的方法比較麻煩。
總的來講,我認(rèn)真地考慮過放棄 blueMarine – 或許 Java 尚未準(zhǔn)備用于桌面開發(fā)。
新生
但是,同時出現(xiàn)了兩個事件使這個項目得以保留下來,這兩個事件是,我在 2005 年底參與了 JavaPolis 以及 2006 年初發(fā)布了 NetBeans 5.0。
在 JavaPolis,我呼吸到了我?guī)缀醵伎焱浀纳鐓^(qū)空氣(自從我上次參加JavaOne 已經(jīng)過去了三年)。這重新點燃了我的熱情,Romain Guy 的演示說明了使用 Swing 構(gòu)建 GUI 的效果如何,,這使我興趣倍增。我開始查看 Romain 的博客,并按照下面的鏈接訪問了其他人的博客,如 Joshua Marinacci 的博客,然后再從那里訪問所有 java.net 和 JavaDesktop 的站點。我發(fā)現(xiàn) Swing 里面有很多新鮮有趣的事;像 SwingLabs 里質(zhì)量優(yōu)良的 Swing組件和出眾的演示程序 – 很多材料我都能夠使用。但是,我仍然需要一個平臺。
幾周之后,推出了NetBeans 5.0 。這個新的版本看起來似乎最終解決了傳統(tǒng)的平臺問題,因此我決定試一試。我開始分解 blueMarine,只提取成像代碼并對該代碼重新設(shè)計以便使用 NetBeans 平臺。幾個月之后,便可以發(fā)布了***個 Early Access 版本,我開始使用這個工具管理我自己的照片。同時,從前一個 PPC Apple iBook 切換到新的 Intel MacBook Pro 沒有出現(xiàn)任何問題則強有力地表明了我的選擇是正確的。
目前,我正致力于使新的 blueMarine 更穩(wěn)定、更便于使用。獲得了新的 early access 版本,并且我正在進行所需的質(zhì)量測試(整個新設(shè)計明顯破壞了以前版本的一些穩(wěn)定性;這就是付出的代價)。
NetBeans和Swing平臺的功能
由于您已經(jīng)了解了 blueMarine 的由來,因此我將概述一些NetBeans和Swing帶來的開發(fā)優(yōu)勢、我曾經(jīng)面臨的問題以及解決這些問題的方法。
***點:是 Swing!
對于我來說,與很多競爭對手(如 Eclipse RCP)相比,NetBeans 平臺基于常規(guī)的Swing 是一個巨大的優(yōu)勢。搜索一下,您會發(fā)現(xiàn) Swing 組件(包括實現(xiàn)動畫和效果比較酷的組件)有更廣闊的選擇余地。
去年 6 月份我非常具體地認(rèn)識到了這個優(yōu)勢,當(dāng)時 Joshua Marinacci 發(fā)布了能夠顯示地圖的 Aerith Swing 組件的源代碼,命名為 JXMapViewer(Aerith 是 2006 年 JavaOne 上最熱門的演示程序)。幾周以來,我一直都在等待這個時刻,blueMarine 的其中一個功能是地理標(biāo)記(將地理位置與每個照片相關(guān)聯(lián),以便這些照片可以顯示在地圖上)。將 JXMapViewer 集成到 blueMarine 中只需要幾個小時;
模塊系統(tǒng)
當(dāng)然,NetBeans 平臺應(yīng)用程序自然分為幾個模塊,實際上,它是一組綁定在一起的模塊。每個模塊都有一個名稱、一組版本標(biāo)記及其自己的類路徑以及一個聲明的依賴關(guān)系的列表。開 發(fā)人員可以控制哪些公共類的子集向其他模塊公開,其他模塊可以看到哪些公共類的子集,平臺可以在模塊之間施加依賴關(guān)系(例如,如果所需的模塊都不存在或者 太舊,則阻止模塊安裝)。
此外,通過發(fā)布新的模塊(放在 nbm 文件中)可以在以后擴展應(yīng)用程序,用戶可以建立他們自己的“更新中心”,以便從 Internet 下載更新。可以對各個模塊進行數(shù)字簽名,系統(tǒng)會自動彈出他們的許可證以便進行批準(zhǔn)(如果需要的話)。
BueMarine 項目充分利用這個組織。該應(yīng)用程序的核心 API 由實現(xiàn)工作空間管理器、照片、縮略圖管理、簡單縮略圖和照片查看器的相對比較小的模塊集進行定義。更多的高級功能(如編錄、圖庫管理器和地理標(biāo)記功能,包括地圖查看器)可以在單獨并且?guī)缀醪幌嚓P(guān)的模塊中實現(xiàn),這些模塊就作為核心 API 的“客戶端”。
DataObject、Node 和 ExplorerManager
ExplorerManager、Node 和 DataObject 可能是 NetBeans 中最有用的 API。使用 DataObject,您可以實現(xiàn)特定于應(yīng)用程序的實體,這些實體是映射到磁盤上的文件中。例如,blueMarine 的基本實體為 PhotoDataObject,它代表數(shù)據(jù)庫中的照片。
而 DataObject 包含實體的所有狀態(tài)和行為,為了進行可視化可以將 Node 與DataObject綁定。還可以采用很多種不同的方式(如集合或圖形)將實體聚合在一起。NetBeans 平臺提供 GUI 組件,如表和列表,這些組件可以將一組 Node 對象用作其模型;最常見的組件是 BeanTreeView、ContextTreeView 和 ListView。***,ExplorerManager 控制選擇和樹導(dǎo)航。
是的,這只不過是一個復(fù)雜的 MVC 實現(xiàn),而且這個實現(xiàn)中已經(jīng)為您編寫了很多樣板文件代碼。例如,平臺 API 考慮類似于拖放支持(以及拖放操作過程中類似于可視提示等詳細(xì)的細(xì)節(jié)信息)、剪切粘貼操作和上下文菜單的事情。
【編輯推薦】