JTable和TableModel簡化Swing
Java Desktop 的再介紹”強(qiáng)調(diào)了今年的 JavaOne 大會(huì)。對(duì)于那些抱怨 Swing 太慢、太難使用、界面太難看的開發(fā)人員來說,Swing 和 GUI 開發(fā)所做的更新努力,并沒有帶來什么受人歡迎的好消息。如果您最近沒有用過 Swing,那么您會(huì)很高興聽到其中的許多問題已經(jīng)得到解決。Swing 被重新設(shè)計(jì),它能執(zhí)行得更好,并能更好地利用 Java 2D API。Swing 的開發(fā)者在 1.4 版甚至最新發(fā)布的 5.0 版中提高了外觀支持。Swing 從沒像現(xiàn)在這么好過。
如果以前曾經(jīng)用過 JTable,那么您可能也同時(shí)被迫使用了 TableModel。您可能還注意到,每個(gè) TableModel 中的所有代碼,與其他 TableModel 中的代碼幾乎是一樣的,在編譯的 Java 類中,有差異的代碼實(shí)際上是不存在的。
本文將分析JTable和TableModel目前的設(shè)計(jì)方法,說明這種設(shè)計(jì)的不足,展示為什么它沒有實(shí)現(xiàn)模型-視圖-控制器(MVC)模式的真正目標(biāo)。您將看到框架和構(gòu)成 TMF 框架的代碼 —— 我以前編寫的代碼與最常用的開放源代碼項(xiàng)目的組合。使用該框架,開發(fā)人員可以把 TableModel 的大小從數(shù)百行代碼減少到只有區(qū)區(qū)一行,并把重要的表信息放在外部 XML 文件中。在讀完本文之后,只使用如下所示的一行代碼,您就可以管理您的 JTable 數(shù)據(jù):
- TableUtilities.setViewToModel("tableconfig.xml", "My Table",
- myJTable, CollectionUtilities.observableList(myData));
JTable和TableModel存在的 MVC 問題
MVC 已經(jīng)成為非常流行的 UI 設(shè)計(jì)模式,因?yàn)樗褬I(yè)務(wù)邏輯清晰地從數(shù)據(jù)的視圖中分離了出來。Struts 是 MVC 在 Web 上應(yīng)用的一個(gè)非常好的例子。最初,Swing 最大的一個(gè)賣點(diǎn)是它采用了 MVC,將視圖從模型中分離了出來,代碼背后的想法是:代碼的模塊化程度足夠高,所以,不用修改模型中的任何代碼,就可以分離出視圖。我想,任何用過JTable和TableModel的人都會(huì)發(fā)笑,告訴您這是絕對(duì)不可能的。使用 MVC 設(shè)計(jì)模式的理想情況是,在開發(fā)人員用 JList 或 JComboBox 替換 JTable 時(shí),可以不用修改表示數(shù)據(jù)的模式中的代碼。但是,在 Swing 中做不到這點(diǎn)。
Swing 使得把 JTable、 JList 和 JComboBox 熱交換到應(yīng)用程序中成為不可能,即使所有這三個(gè)組件都是用來為相同的數(shù)據(jù)模型提供視圖。對(duì)于 Swing 中的 MVC 設(shè)計(jì),這是一個(gè)嚴(yán)重的不足。如果您想為 JTable 交換 JList,就必須重寫視圖背后的全部代碼,才能實(shí)現(xiàn)該交換。
JTable和TableModel的另一個(gè) MVC 缺陷是:模型變化的時(shí)候,視圖不會(huì)更新自身。開發(fā)人員必須保持對(duì)模型的引用,并調(diào)用一個(gè)函數(shù),這樣模型才會(huì)告訴視圖對(duì)自身進(jìn)行更新;但是,理想的情況應(yīng)當(dāng)是:不需要任何額外的代碼,就能實(shí)現(xiàn)自動(dòng)更新。
最后,JTable和TableModel 組件設(shè)計(jì)的問題是,它們彼此之間纏雜得過于密切。如果您修改了 JTable 中的代碼,那么您需要確保您沒有破壞負(fù)責(zé)處理的 TableModel,反之亦然。對(duì)于一個(gè)被認(rèn)為是在模塊化基礎(chǔ)上建立的設(shè)計(jì)模式來說,目前的實(shí)現(xiàn)顯然是一種存在過多依賴關(guān)系的設(shè)計(jì)。
TMF 框架更好地遵循了 MVC 的目標(biāo),它把 JTable 中視圖和模型的工作更加清晰地分離開來。雖然它還沒有達(dá)到讓組件能夠熱切換的更高目標(biāo),但是它已經(jīng)在正確方向上邁出了一步。
【編輯推薦】