Swing DayDayUP之三:Swing組件層次結(jié)構(gòu)介紹
Posted on 2009-07-08 22:49 zht 閱讀(2772) 評(píng)論(1) 編輯 收藏 所屬分類: Swing 一直想寫(xiě)篇關(guān)于Swing體系結(jié)構(gòu)的文章,不過(guò)一直不敢下手,怕理解的有偏差,最近看了下這方面的資料,記錄下,Swing的整體組織結(jié)構(gòu)如下圖所示。
Swing程序要呈現(xiàn)出來(lái),肯定要將組件放到JFrame,JDialog,JApplet,JWindow這幾個(gè)容器組件中,這些頂層容器組件,有一個(gè)共同的結(jié)構(gòu),如上圖所示,都有一個(gè)JRootPane面板來(lái)承載著所有要顯示的組件。JRootPane又有以下部分組成:
1、GlassPane
2、JLayeredPane
(1)ContentPane
(2)JMenuBar
其中JRootPanel中的RootLayout對(duì)以上幾部分進(jìn)行布局,關(guān)于這點(diǎn)可以參考Java的API文檔和java源碼,里面有詳細(xì)的說(shuō)明。
這里想要說(shuō)的一點(diǎn)是,JRootPane并不是只能放在這些頂層容器中的,你也可以放在一般的組件,比如JPanel中,這樣Panel就有了層次結(jié)構(gòu),可以再其不同的層次上放置組件,這個(gè)后邊還會(huì)再講一下。
寫(xiě)這篇文章,并不是為了講Swing的這個(gè)架構(gòu),主要是想通過(guò)講述這個(gè)架構(gòu),給大家介紹些開(kāi)發(fā)過(guò)程中用的技巧。
GlassPanel這個(gè)可能大家都了解了,比如,可以模擬Eclipse中Tab頁(yè)簽的拖拽效果,當(dāng)處理一些比較費(fèi)時(shí)的操作,比如加載數(shù)據(jù)時(shí),可以用來(lái)遮罩面板,一方面可以防止用戶重復(fù)操作,另一方面可以用來(lái)顯示進(jìn)度。不過(guò)有一點(diǎn)限制就是每個(gè)頂層容器中GlassPanel只能有一個(gè)(其實(shí)像上面提到的,如果一個(gè)面板中的組件都有一個(gè)JRootPane來(lái)承載組件,其實(shí)在一個(gè)程序中GlassPane也是可以有多個(gè)的,通過(guò)這個(gè),GlassPanel和JLayeredPane幾乎可以達(dá)到相同的效果)。
JLayeredPane有了深度的概念,一般的Layout在JLayeredPane是不適用的。一個(gè)Integer來(lái)標(biāo)示組件在JLayeredPane中的深度,這個(gè)值越大,就會(huì)顯示在越上面。JLayeredPane還有一個(gè)同層的上下關(guān)系,這個(gè)可以參考API或者源代碼。重要的一點(diǎn)是JLayeredPane默認(rèn)的Layout是null,所以,放到JLayeredPane上的組件,必須要通過(guò)setBounds的形式來(lái)設(shè)置大小才會(huì)顯示出來(lái),否則是看不到的,這點(diǎn)尤其要注意。JLayeredPane的層次結(jié)構(gòu)能實(shí)現(xiàn)非常多的特效,我甚至認(rèn)為,JLayeredPane 是Swing結(jié)構(gòu)中,最精妙的設(shè)計(jì)之一,通過(guò)JLayeredPane我們可以實(shí)現(xiàn)文本的驗(yàn)證提示功能,舉個(gè)例子,有一個(gè)文本框,用來(lái)輸入電話號(hào)碼,有時(shí)候可能用戶會(huì)輸入些字母,甚至是漢字,當(dāng)用戶切換到下一個(gè)面板或者最后提交驗(yàn)證以后,你可能希望給出一些提示來(lái)標(biāo)明這些輸入非法,這時(shí)候,就可以用到JLayeredPane了,你可以將非法輸入的組件,傳遞給一個(gè)Panel,這個(gè)Panel在非法的組件旁邊繪制一個(gè)小圖標(biāo),然后讓這個(gè)Panel顯示在主界面的上面(后續(xù)會(huì)把相關(guān)代碼發(fā)出)。還有另外一個(gè)用途就是使用JInternalFrame做控制面板,可以通過(guò)JLayeredPane將一個(gè)JInternalFrame懸浮到一個(gè)面板中,既不會(huì)占用程序的空間,又不會(huì)像dialog那樣,必須要彈出來(lái)才可以。
附一個(gè)通過(guò)LayeredPane來(lái)顯示加載進(jìn)度的例子,使用方法很簡(jiǎn)單只需要將你的組件通過(guò)我的adapter封裝下,然后再放到你的程序中即可MaskAdapter maskPanel = MaskAdapter.getMaskpanel(panel, false);。
下載


Swing程序要呈現(xiàn)出來(lái),肯定要將組件放到JFrame,JDialog,JApplet,JWindow這幾個(gè)容器組件中,這些頂層容器組件,有一個(gè)共同的結(jié)構(gòu),如上圖所示,都有一個(gè)JRootPane面板來(lái)承載著所有要顯示的組件。JRootPane又有以下部分組成:
1、GlassPane
2、JLayeredPane
(1)ContentPane
(2)JMenuBar
其中JRootPanel中的RootLayout對(duì)以上幾部分進(jìn)行布局,關(guān)于這點(diǎn)可以參考Java的API文檔和java源碼,里面有詳細(xì)的說(shuō)明。
這里想要說(shuō)的一點(diǎn)是,JRootPane并不是只能放在這些頂層容器中的,你也可以放在一般的組件,比如JPanel中,這樣Panel就有了層次結(jié)構(gòu),可以再其不同的層次上放置組件,這個(gè)后邊還會(huì)再講一下。
寫(xiě)這篇文章,并不是為了講Swing的這個(gè)架構(gòu),主要是想通過(guò)講述這個(gè)架構(gòu),給大家介紹些開(kāi)發(fā)過(guò)程中用的技巧。
GlassPanel這個(gè)可能大家都了解了,比如,可以模擬Eclipse中Tab頁(yè)簽的拖拽效果,當(dāng)處理一些比較費(fèi)時(shí)的操作,比如加載數(shù)據(jù)時(shí),可以用來(lái)遮罩面板,一方面可以防止用戶重復(fù)操作,另一方面可以用來(lái)顯示進(jìn)度。不過(guò)有一點(diǎn)限制就是每個(gè)頂層容器中GlassPanel只能有一個(gè)(其實(shí)像上面提到的,如果一個(gè)面板中的組件都有一個(gè)JRootPane來(lái)承載組件,其實(shí)在一個(gè)程序中GlassPane也是可以有多個(gè)的,通過(guò)這個(gè),GlassPanel和JLayeredPane幾乎可以達(dá)到相同的效果)。
JLayeredPane有了深度的概念,一般的Layout在JLayeredPane是不適用的。一個(gè)Integer來(lái)標(biāo)示組件在JLayeredPane中的深度,這個(gè)值越大,就會(huì)顯示在越上面。JLayeredPane還有一個(gè)同層的上下關(guān)系,這個(gè)可以參考API或者源代碼。重要的一點(diǎn)是JLayeredPane默認(rèn)的Layout是null,所以,放到JLayeredPane上的組件,必須要通過(guò)setBounds的形式來(lái)設(shè)置大小才會(huì)顯示出來(lái),否則是看不到的,這點(diǎn)尤其要注意。JLayeredPane的層次結(jié)構(gòu)能實(shí)現(xiàn)非常多的特效,我甚至認(rèn)為,JLayeredPane 是Swing結(jié)構(gòu)中,最精妙的設(shè)計(jì)之一,通過(guò)JLayeredPane我們可以實(shí)現(xiàn)文本的驗(yàn)證提示功能,舉個(gè)例子,有一個(gè)文本框,用來(lái)輸入電話號(hào)碼,有時(shí)候可能用戶會(huì)輸入些字母,甚至是漢字,當(dāng)用戶切換到下一個(gè)面板或者最后提交驗(yàn)證以后,你可能希望給出一些提示來(lái)標(biāo)明這些輸入非法,這時(shí)候,就可以用到JLayeredPane了,你可以將非法輸入的組件,傳遞給一個(gè)Panel,這個(gè)Panel在非法的組件旁邊繪制一個(gè)小圖標(biāo),然后讓這個(gè)Panel顯示在主界面的上面(后續(xù)會(huì)把相關(guān)代碼發(fā)出)。還有另外一個(gè)用途就是使用JInternalFrame做控制面板,可以通過(guò)JLayeredPane將一個(gè)JInternalFrame懸浮到一個(gè)面板中,既不會(huì)占用程序的空間,又不會(huì)像dialog那樣,必須要彈出來(lái)才可以。
附一個(gè)通過(guò)LayeredPane來(lái)顯示加載進(jìn)度的例子,使用方法很簡(jiǎn)單只需要將你的組件通過(guò)我的adapter封裝下,然后再放到你的程序中即可MaskAdapter maskPanel = MaskAdapter.getMaskpanel(panel, false);。
下載