詳解Swing組件相應(yīng)外觀
Swing將每個(gè)組件的視圖和控制封裝到一個(gè)稱為UI委托的對象中。
因此,Swing的體系結(jié)構(gòu)被稱為模型委托結(jié)構(gòu)而不是模式-視圖-控制器結(jié)構(gòu)。理想情況下,模型和UI委托直接的通訊是間接的,允許多個(gè)模型與一個(gè)UI委托相連,反之亦然。
UI委托
每個(gè)UI委托源自一個(gè)名為ComponentUI的抽象類。ComponentUI的方法描述了一個(gè)UI委托和使用它的組件之間進(jìn)行通訊的基本原理。
注意的是每個(gè)方法都將JComponent作為一個(gè)參數(shù)。ComponentUI有很多方法,這里只給出幾個(gè)最重要的:
◆static ComponentUI createUI(JComponent c):該方法通常用來返回UI委托的一個(gè)共享實(shí)例,該UI委托通過定義ComponentUI子類本身而定義。這個(gè)共享實(shí)例用于相同類型的組件之間的共享(例如,所有使用金屬外觀的JButtons共享同樣的靜態(tài)UI委托實(shí)例,默認(rèn)情況下,該委托實(shí)例在javax.swing.plaf.metal.MetalButtonUI中定義。
◆InstallUI(JComponent c):該方法在特定的組件上安裝ComponentUI。通常會(huì)給組件和它的模型添加一個(gè)監(jiān)聽器,當(dāng)狀態(tài)發(fā)生改變時(shí)來通知UI委托進(jìn)行視圖的更新。
◆Update (Graphics g, JComponent c):如果組件是不透明的,那么應(yīng)該描繪它的背景并調(diào)用paint(Graphics g,JComponent C)方法。
◆Paint (Graphics g, JComponent c):為了能夠正確地描繪,該方法要從組件收集所有需要的信息以及可能的模型。
為了增強(qiáng)特定UI委托的使用,我們可以調(diào)用一個(gè)組件的setUI()方法,如下所示:
JComponent類中定義了用于分配UI委托的方法,因?yàn)榉椒暶髦胁话囟ńM件代碼。然而,對數(shù)據(jù)模型而言這是不可能的,因?yàn)椴淮嬖谒心P涂梢宰匪莸降幕涌冢ɡ纾淮嬖谙馭wing模型中的ComponentUI此類的基類)。為此,分配模型的方法在JComponent的子類中定義。
使用PLAF
Swing包含幾個(gè)UI委托集。每個(gè)集合中包含了用于大部分Swing組件的ComponentUI實(shí)現(xiàn),且每個(gè)這樣的集合稱為一個(gè)PLAF實(shí)現(xiàn)。
javax.swing.plaf包有繼承自ComponentUI的抽象類組成,javax.swing.plaf.basic包中的類擴(kuò)展了這些抽象類用來實(shí)現(xiàn)基本的外觀。UI委托集合是所有其它外觀類用作構(gòu)建自己的外觀的基類。基本外觀不能自己使用因?yàn)锽asicLookAndFeel是一個(gè)抽象類。有三個(gè)繼承自BasicLookAndFeel的可插拔式外觀實(shí)現(xiàn):
◆Windows: com.sun.java.swing.plaf.windows.WindowsLookAndFeel
◆CDEMotif: com.sun.java.swing.plaf.motif.MotifLookAndFeel
◆Metal (default): javax.swing.plaf.metal.MetalLookAndFeel
同時(shí)還有一個(gè)模仿蘋果用戶接口的MacLookAndFeel,但是沒有包含在Java2中,必須單獨(dú)下載。多路外觀javax.swing.plaf.multi.MultiLookAndFeel擴(kuò)展了javax.swing.plaf中的所有抽象類。它運(yùn)行同時(shí)使用多種外觀的組合,且有意但并不僅限于和訪問外觀一起使用。每個(gè)多路UI委托的任務(wù)是管理每個(gè)它們的子UI委托。
每個(gè)外觀包中都包含了一個(gè)繼承自抽象類javax.swing.LookAndFeel:BasicLookAndFeel, MetalLookAndFeel, WindowsLookAndFeel等的類。這是訪問每個(gè)外觀包的中心點(diǎn)。當(dāng)改變當(dāng)前外觀時(shí),你會(huì)用到它們。同時(shí)UIManager類(用于管理安裝的外觀)使用它們來訪問當(dāng)前外觀UIDefaults表(其中包含了用于每個(gè)Swing組件相應(yīng)外觀的UI委托類名稱)。
要想改變應(yīng)用的當(dāng)前外觀,你只需要簡單調(diào)用UIManager的setLookAndFeel()方法,并將要使用的外觀全名傳遞給該方法即可。
創(chuàng)建一個(gè)PLAF
在創(chuàng)建一個(gè)PLAF之前,你必須在Java中創(chuàng)建外觀的兩種設(shè)計(jì)方法中做出決定。其中一種方法是通過擴(kuò)展javax.swing.plaf包來創(chuàng)建外觀,另一種方法是通過擴(kuò)展已經(jīng)存在的外觀包,通常是javax.swing.plaf.basic來實(shí)現(xiàn)。
如果要?jiǎng)?chuàng)建一個(gè)用于PC的外觀,我們不推薦使用擴(kuò)展來自javax.swing.plaf包中的外觀的方法。這是因?yàn)閖avax.swing.basic包中已經(jīng)擴(kuò)展了幾乎整個(gè)的javax.swing.plaf包供我們使用。這樣我們可以通過挑選外觀需要的東西來進(jìn)行定制而不需要擴(kuò)展和實(shí)現(xiàn)任何東西。
javax.swing.plaf包的實(shí)現(xiàn)遵循的一個(gè)基本原則是使得定制一個(gè)外觀盡可能的簡單。這個(gè)原則是LookAndFeel類中組件,顏色和UI類的中心。
javax.swing.plaf.basic包以我們希望的方式描繪輕量級Swing組件。如果你是為一臺(tái)設(shè)備而不是計(jì)算機(jī)屏幕創(chuàng)建一個(gè)外觀,那么最好的方法是從零開始擴(kuò)展javax.swing.plaf包。
Peter V.Mikhalenko是 Sun公司認(rèn)證專業(yè)技術(shù)人員,現(xiàn)為Deutsche銀行業(yè)務(wù)顧問。
【編輯推薦】