一、慎用自定義UI組件
雖然計算機軟件技術發展迅速,但在人機交互的方式卻保持相對穩定。鼠標和鍵盤自誕生之日起就沒有發生過什麼實質性變化,而我們日常使用軟件時,也只是和諸如按鈕、菜單、輸入框以及下拉列表等有限的幾種UI組件打交道,任何一種新UI組件的產生,都意味著向幾十年來累積的習慣發起挑戰。
JSF框架缺省的UI組件通常能滿足你的需求,如果不能滿足,則有必要重新審視一下你的界面設計,問問自己這幾個問題:
1. 是否用缺省的UI組件就能實現所需的人機交互功能?
2. 如果單個UI組件不能,幾個UI組件組合在一起是否可以?
3. 有沒有替代的界面設計方案,可以避開使用自定義UI組件?
即使答案都是否定的,也不要急於下編寫自定義UI組件的決心。別忘了,除了Sun的參考實現附帶的UI組件外,還有很多UI組件包供你選擇:
1. 開發工具如NetBeans在安裝時一般都會自動安裝額外的UI組件包;
2. 專業的第三方廠商會提供種類繁多功能強大的UI組件包,例如MyFaces。JSF規范稱這種專業廠商為的Component Writer,是JSF建議的5種職能劃分中的一種。
不論是開發工具附送的,還是第三方廠商提供的,這些組件包有專門的開發和維護團隊,經過了充分的測試和實戰考驗,文檔詳盡,與開發工具集成,有的更有技術支持,總之四個字:方便可靠。
如果這些都不能令你滿意,你還是一意孤行要編寫自定義UI組件,那麼,在開始動手之前,先了解一下自定義UI組件的不足:
1. 需要額外的編碼,讓你的設計變得復雜
2. 需要花費精力測試,而如果測試不足,則有可能含有Bug
3. 可能隱藏潛在的性能問題
4. 如果你在一個團隊中工作,你必須編寫足夠詳細的Java Doc,讓別人明白怎麼用你的自定義UI組件
5. 如果你希望你的UI組件能夠集成到開發工具中,以便顯示在組件面板上,你必須面對工具相關的配置工作
二、編寫自定義UI組件的好處
當然,嘗試編寫自定義UI組件也並非全無好處。對於JSF的初學者,這是深入了解JSF內部細節的一種有效途徑。當你成功編寫一個自定義UI組件並理解了每個代碼片段的含義後,你對JSF框架的理解肯定會向前邁進一大步。畢竟,UI組件是JSF框架的核心。
另一個好處是你可以實現一些非標准的界面設計,有時候這是必要的。例如,假設你是JS高手,你完全可以在自定義UI組件上用JS實現一些令人眩目的客戶端效果。
將若干個標准UI組件組合成一個有著某種特定功能的組件集合,是自定義UI組件的另一用處。典型的例子如文件上載組件,可由一個文本字段組件、一個“浏覽 ”按鈕組件和一個“上傳”按鈕組件組成。這允許你一次鼠標拖放就能將這些捆在一起的組件添加到頁面上,而不必逐個添加。更重要的是,你可以在自定義UI組件的內部處理這些組件之間的相互協調,而無需組件的使用者操心。例如,在文件上傳組件中,如果文本字段組件為空,則不允許點擊“上傳”按鈕。
三、寫這篇文章的用意
很多讀者寫郵件給我,提到JSF自定義UI組件的問題。雖然我私底下並不贊成JSF的初學者涉足這個相對比較復雜的編程領域,但程序員們打破沙鍋問到底的探索精神確實值得稱道。
從郵件中可以看出,大部分讀者都關注著JSF的發展,有些讀者實際接觸過JSF,用JSF做過項目,其中不乏對JSF已經非常了解的程序員。鑒於自定義 UI組件在《JSF Web應用開發實戰》一書中只是一筆帶過,為了使這本書能夠適合更多不同程度的讀者,我最終還是決定在博客上發表一些文章,系統地介紹一下JSF自定義 UI組件的相關知識,作為對書中內容的一個補充。
必須申明,寫這樣一個文章系列,不是為了演示JSF有多復雜。關於JSF的復雜性,已經有太多的誤會,個中原因,主要是JSF生命周期被談論得太多,以至於讓初學者望而卻步。其實,讀過《JSF Web應用開發實戰》一書的讀者一定發現了,JSF實際上是迄今為止最簡單的、生產率最高的Web應用編程手段之一。JSF的復雜性體現在框架的實現本身,而這恰恰給作為框架使用者的程序員帶來了使用上的簡單和方便。好比一台自動檔的車,雖然波箱比手動檔要復雜得多,但顯然駕駛員更輕松了。
可以這樣說,自定義UI組件好比在波箱上動手腳,至少對於JSF 1.2版本來說是這樣。醞釀中的JSF 2.0據說在這方面有很大的提升,編寫自定義UI組件將變得十分容易。我對此變化的理解是,Sun已經不滿足於自動波了,手自一體才是JSF 2.0的追求。
這個文章系列會包含多少篇文章,說實話我現在心裡還真沒底。可以肯定的是,我仍然會按照自己的寫作習慣去組織文字,一是由淺入深,二是注重實戰,三是用例子說話。還有,既然是對《JSF Web應用開發實戰》一書的補充,我還是會結合NetBeans來寫,至於NetBeans的版本,在寫書時6.0.1是最新版,那就還是用6.0.1 吧,雖然現在最新版已經是6.1了,好在與6.0.1相比變化不大,6.0.1的代碼在6.1中運行應該不會有太多問題。