|
探究 Z-Order http://www. 2001年11月27日 CSDN Z-order,也有人稱為 Zorder,指的是對象之間的層次關(guān)系。舉個(gè)簡單的例子:在使用 PowERPoint 制作文件時(shí),當(dāng)你把文件上被其它對象蓋住的某個(gè)對象「上推至最頂層」,你就是在改變它的 Z-order。通常 Z-order 高者置于 Z-order 低者的「上面」。
通常 GUI 程序設(shè)計(jì)都會用到 Z-order 的觀念,所以 Borland OWL 有 Z-order,Java AWT 有 Z-order,Java Swing 也有 Z-order。這些 GUI 鏈接庫都提供了良好的 Z-order 自動管理機(jī)制,貼心地幫我們管理 Z-order,大部分的情況之下,我們不會直接使用到 Z-order。但是,當(dāng)你需要處理到對象之間的層次關(guān)系時(shí),如果你不知道 Z-order,你可就麻煩了。我曾經(jīng)用 Java 設(shè)計(jì)過一個(gè)簡單的 UML 繪圖軟件,當(dāng)時(shí)并未善加使用 Swing 的 Z-order 管理機(jī)制(即 JLayeredPane),結(jié)果多寫了好些程序代碼就只是為了控制層次關(guān)系。這篇文章簡單地為您介紹 Java 的 Z-order 觀念以及 JLayeredPane,希望你不要重蹈我的覆轍。 許多 Swing 的書都會再三告誡讀者,「盡量不要」混合使用 Swing 和 AWT 的組件,原因就在于 Swing 和 AWT 的 Z-order 系統(tǒng)是不一樣的。Swing 組件大都是 lightweight 的,而 AWT 的組件則一律是 heavyweight 的。我有個(gè)不錯(cuò)的比喻:Swing 組件是在 AWT 組件之內(nèi)徑自切割出來的層次,就好比 green thread 是在 process 之內(nèi)徑自切割出來的排程單位。你可能會問:「現(xiàn)在 green thread 已經(jīng)「進(jìn)化」成 native thread 了,以后 Swing 的 Z-order 會不會也「進(jìn)化」成和 AWT 的 Z-order 同地位?」我認(rèn)為不會,因?yàn)槿绻@樣做的話,Swing 組件都必須繼承自 AWT 組件,而目前 Swing 正致力于減少 CPU 和內(nèi)存資源的消耗量來提升速度,所以不可能還走回頭路 heavyweight 化。 AWT 和 Swing 的 Z-order 規(guī)則一樣,如下: 1. 組件的 Z-order 一定比其容器來得高,組件一定位于容器上層。 2. 同一個(gè)容器的兩個(gè)組件中,越早加入容器者其 Z-order 越高,位置越上層。 但是如果混合使用 AWT 和 Swing,上述第二條規(guī)則就不一定了。比方說,在某容器內(nèi)先加入一個(gè) Swing 的組件,再加入一個(gè) AWT 的組件,且此二組件有重疊的區(qū)域,結(jié)果卻是 AWT 組件出現(xiàn)在 Swing 組件上面。這并未遵守第二條的規(guī)定,因?yàn)榇死瑫r(shí)使用了 AWT 和 Swing,Swing 組件被當(dāng)成和容器同一個(gè)層,AWT 組件則是容器上一層。 在六個(gè)標(biāo)準(zhǔn)的 layout(包括 BorderLayout、FlowLayout、GridLayout、GridBagLayout、CardLayout、以及 BoxLayout)管理之下,容器的組件之間不會重疊(甚至連 CardLayout 管理之下也是如此,因?yàn)?CardLayout 只是邏輯上組件重疊,但實(shí)際上的做法是一次只有一個(gè)組件被設(shè)為 visible),所以大多數(shù)情況下 Z-order 并不會影響外觀。但是當(dāng)組件之間有重疊的情況發(fā)生時(shí),你就要特別注意了,這些包括了: ˙ 將 layout 設(shè)為 null,由程序自行控制組件的 layout,而且允許組件重疊的話,你不可以同時(shí)使用 AWT 和 Swing 的組件。 ˙ JInternalFrame、JScrollPane、JLayeredPane、JDesktopPane...... 等容器會以重疊的方式放置組件,你不可以同時(shí)使用 AWT 和 Swing 的組件。 ˙ 當(dāng)使用 pop-up menu 時(shí),此 menu 的容器如果有 heavyweight 的組件,那么你必須讓此 pop-up menu 為 heavyweight,否則此 pop-up menu 可能會被蓋住。呼叫 JPopupMenu.setLightWeightPopupEnabled(false) 即可讓以后產(chǎn)生的 pop-up menu 都是 heavyweight 形式的。 前面提到,越早加入某容器的組件,其 Z-order 越高。除了 remove 再 add 之外,想改變 Z-order,你別無它法。但是如果你真的需要改變某容器的組件之 Z-order,那么你可以改用 javax.swing.JLayeredPane 當(dāng)作容器,因?yàn)?JLayeredPane 提供了許多讓你可以改變組件 Z-order 的 method。 對于 JLayeredPane 來說,Z-order 由兩部分組成,分別是 layer 和 position,兩者都是整數(shù)值。某組件的 layer 數(shù)目越高,表示位于越上層。如果兩個(gè)組件位于同一個(gè) layer,則 position 數(shù)目越低者位于越上層。關(guān)于 JLayeredPane,請看 O'Reilly 出版的「Java Swing」一書 223~231 頁。 這篇文章可能有點(diǎn)復(fù)雜,必要時(shí)請仔細(xì)地多閱讀幾次。 |
|
|