Java Swing 應用編程接口提供了可插拔式外觀風格(PLAF)的特性它允許Swing 圖形用戶接口(GUI)小應用根據編程人員定制的外觀風格設置來改變界面外觀風格
幾乎所有現代用戶接口框架都結合了視圖和控制無論它們是基於SmallTalkC++或Java
Swing將每個組件的視圖和控制封裝到一個稱為UI委托的對象中
因此Swing的體系結構被稱為模型委托結構而不是模式視圖控制器結構理想情況下模型和UI委托直接的通訊是間接的允許多個模型與一個UI委托相連反之亦然
UI委托
每個UI委托源自一個名為ComponentUI的抽象類ComponentUI的方法描述了一個UI委托和使用它的組件之間進行通訊的基本原理
注意的是每個方法都將JComponent作為一個參數ComponentUI有很多方法這裡只給出幾個最重要的
·static ComponentUI createUI(JComponent c)該方法通常用來返回UI委托的一個共享實例該UI委托通過定義ComponentUI子類本身而定義這個共享實例用於相同類型的組件之間的共享(例如所有使用金屬外觀的JButtons共享同樣的靜態UI委托實例默認情況下該委托實例在talMetalButtonUI中定義
·InstallUI(JComponent c)該方法在特定的組件上安裝ComponentUI通常會給組件和它的模型添加一個監聽器當狀態發生改變時來通知UI委托進行視圖的更新
·Update (Graphics g JComponent c)如果組件是不透明的那麼應該描繪它的背景並調用paint(Graphics gJComponent C)方法
·Paint (Graphics g JComponent c):為了能夠正確地描繪該方法要從組件收集所有需要的信息以及可能的模型
為了增強特定UI委托的使用我們可以調用一個組件的setUI()方法如下所示
JButton m_button = new JButton();
m_buttonsetUI((MyButtonUI)MyButtonUIcreateUI(m_button));
JComponent類中定義了用於分配UI委托的方法因為方法聲明中不包含特定組件代碼然而對數據模型而言這是不可能的因為不存在所有模型可以追溯到的基接口(例如不存在像Swing模型中的ComponentUI此類的基類)為此分配模型的方法在JComponent的子類中定義
使用PLAF
Swing包含幾個UI委托集每個集合中包含了用於大部分Swing組件的ComponentUI實現且每個這樣的集合稱為一個PLAF實現
javaxswingplaf包有繼承自ComponentUI的抽象類組成javaxswingplafbasic包中的類擴展了這些抽象類用來實現基本的外觀UI委托集合是所有其它外觀類用作構建自己的外觀的基類基本外觀不能自己使用因為BasicLookAndFeel是一個抽象類有三個繼承自BasicLookAndFeel的可插拔式外觀實現
·Windows: comsunjavaswingplafwindowsWindowsLookAndFeel
·CDEMotif: comsunjavaswingplafmotifMotifLookAndFeel
·Metal (default): talMetalLookAndFeel
同時還有一個模仿蘋果用戶接口的MacLookAndFeel但是沒有包含在Java中必須單獨下載多路外觀javaxswingplafmultiMultiLookAndFeel擴展了javaxswingplaf中的所有抽象類它運行同時使用多種外觀的組合且有意但並不僅限於和訪問外觀一起使用每個多路UI委托的任務是管理每個它們的子UI委托
每個外觀包中都包含了一個繼承自抽象類javaxswingLookAndFeelBasicLookAndFeel MetalLookAndFeel WindowsLookAndFeel等的類這是訪問每個外觀包的中心點當改變當前外觀時你會用到它們同時UIManager類(用於管理安裝的外觀)使用它們來訪問當前外觀UIDefaults表(其中包含了用於每個Swing組件相應外觀的UI委托類名稱)
要想改變應用的當前外觀你只需要簡單調用UIManager的setLookAndFeel()方法並將要使用的外觀全名傳遞給該方法即可可以使用列表A中的代碼在運行時完成該任務
列表A
try {
UIManager
setLookAndFeel(
com
sun
java
swing
plaf
motif
MotifLookAndFeel
);
SwingUtilities
updateComponentTreeUI(myJFrame);
}
catch (Exception e) {
System
err
println(
Could not load LookAndFeel
);
}
當外觀改變時Swing實用工具updateComponentTreeUI()通知所有特定組件的孩子並通知它們丟棄原來的UI委托用來換取一個不同的特定類型委托
圖AB和C演示了金屬圖形和窗口外觀之間的不同之處
![](http://tw.wingwit.com/Article/UploadFiles/201311/2013112319091806.bmp)
圖A
![](http://tw.wingwit.com/Article/UploadFiles/201311/2013112319091839.bmp)
圖B
![](http://tw.wingwit.com/Article/UploadFiles/201311/2013112319091891.bmp)
圖C
創建一個PLAF
在創建一個PLAF之前你必須在Java中創建外觀的兩種設計方法中做出決定其中一種方法是通過擴展javaxswingplaf包來創建外觀另一種方法是通過擴展已經存在的外觀包通常是javaxswingplafbasic來實現
如果要創建一個用於PC的外觀我們不推薦使用擴展來自javaxswingplaf包中的外觀的方法這是因為javaxswingbasic包中已經擴展了幾乎整個的javaxswingplaf包供我們使用這樣我們可以通過挑選外觀需要的東西來進行定制而不需要擴展和實現任何東西
javaxswingplaf包的實現遵循的一個基本原則是使得定制一個外觀盡可能的簡單這個原則是LookAndFeel類中組件顏色和UI類的中心
javaxswingplafbasic包以我們希望的方式描繪輕量級Swing組件如果你是為一台設備而不是計算機屏幕創建一個外觀那麼最好的方法是從零開始擴展javaxswingplaf包
Peter VMikhalenko是 Sun公司認證專業技術人員現為Deutsche銀行業務顧問
From:http://tw.wingwit.com/Article/program/Java/hx/201311/26367.html