在第7章中,我們了解使用Swing組件周圍的邊框。在本章中,我們將會(huì)探討高層Swing容器,并且將會(huì)發(fā)現(xiàn)與相對(duì)應(yīng)的AWT容器的不同。
使用Swing中的高層容器與使用高層AWT容器不同。對(duì)于AWT容器,F(xiàn)rame,Window,Dialog以及Applet,我們可以將組件直接添加到容器,并且我們只有一個(gè)位置來(lái)放置這些組件。在Swing世界中,高層容器,JFrame,JWindow,JDialog以及JApplet,加上JInternalFrame容器,依賴JRootPane。我們并不能將組件直接添加到容器,而只能將這些組件添加到root pane(根面板)的一部分。然后由根面板來(lái)管理這些組件。
為什么添加這個(gè)間接層呢?無(wú)論我們是否相信,這樣做是為了事情的簡(jiǎn)化。根面板在層中管理其組件,從而如工具提示文本這樣的元素總是顯示在組件上面,而且我們不必?fù)?dān)心拖拽某個(gè)組件在其他組件周圍運(yùn)動(dòng)。
JInternalFrame并沒(méi)有相對(duì)應(yīng)的AWT組件,他也提供了一些額外的功能用于處理被放置在桌面(在JDesktopPane中)中的情況。JInternalFrame可以用作在Swing程序創(chuàng)建多文檔界面(MDI)程序的基礎(chǔ)。在我們的程序中我們可以管理一系列的內(nèi)部框架,并且他們絕不會(huì)超出我們的主程序容器。
下面我們開(kāi)始探討新的JRootPane類,他管理所有的高層容器。
8.1 JRootPane類
JRootPane擔(dān)當(dāng)高層Swing容器的容器代理。因?yàn)槿萜髦淮娣乓粋€(gè)JRootPane,當(dāng)我們由高層容器中添加或是移除組件時(shí),我們并沒(méi)有直接修改容器中的組件,而是間接的由JRootPane實(shí)例添加或是移除組件。事實(shí)上,高層容器擔(dān)當(dāng)代理的角色,由JRootPane完成所有的工作。
JRootPane容器依賴其內(nèi)聯(lián)類RootLayout進(jìn)行布局管理,并且管理存儲(chǔ)JRootPane的高層容器的所有空間。在JRootPane中只有兩個(gè)組件:一個(gè)JLayeredPane以及一個(gè)玻璃嵌板(Component)。前面的玻璃嵌板可以是任意組件,而且是不可見(jiàn)的。玻璃嵌板保證類似工具提示文本這樣的元素顯示在其他的Swing之前。后面是JLayeredPane,在其上部包含一個(gè)可的選的JMenuBar,在其下面的另一層中包含一個(gè)內(nèi)容面析(Container)。通常我們將組件放在JRootPane中就是放置在內(nèi)容面板中。圖8-1有助于我們理解RootLayout是如何布局組件的。
注意:JLayerPane也僅是一個(gè)Swing容器。他可以包含任意的組件并且具有一些特定的布局特性。JRootPane面板中所用的JlayeredPane只包含一個(gè)JMenuBar以及一個(gè)Container作為其內(nèi)容面板。內(nèi)容面板有其自己的布局管理器,默認(rèn)情況下為BorderLayout。
8.1.1 創(chuàng)建JRootPane
盡管JRootPane具有一個(gè)公開(kāi)的無(wú)參數(shù)的構(gòu)造函數(shù),但是通常我們并不會(huì)親自創(chuàng)建JRootPane。相反,實(shí)現(xiàn)了RootPaneContainer接口的類創(chuàng)建JRootPane。然后,我們由該組件通過(guò)RootPaneContainer接口來(lái)獲取根面板,我們會(huì)在稍后進(jìn)行描述。
8.1.2 JRootPane屬性
如表8-1所示,JRootPane有11個(gè)屬性。大多數(shù)情況下,當(dāng)我們?yōu)楦邔尤萜鳙@取或是設(shè)置一個(gè)這樣的屬性時(shí),例如JFrame,容器只是簡(jiǎn)單的將請(qǐng)求傳遞給其JRootPane。
JRootPane的玻璃嵌板必須是透明的。因?yàn)椴A栋鍟?huì)占據(jù)JLayeredPane前面的整個(gè)區(qū)域,一個(gè)不透明的玻璃嵌板會(huì)將其菜單欄與內(nèi)容面板渲染為不可見(jiàn)。而且,因?yàn)椴A栋迮c內(nèi)容面板共享相同的邊界,當(dāng)設(shè)置optimizedDrawingEnabled屬性時(shí)會(huì)返回玻璃嵌板的可見(jiàn)性。
Table 8-1. JRootPane屬性
屬性名
|
數(shù)據(jù)類型
|
訪問(wèn)性 |
accessibleContext
|
AccessibleContext
|
只讀 |
contentPane
|
Container
|
讀寫 |
defaultButton
|
JButton
|
讀寫綁定 |
glassPane
|
Component
|
讀寫 |
jMenuBar
|
JMenuBar
|
讀寫 |
layeredPane
|
JLayeredPane
|
讀寫 |
optimizedDrawingEnabled
|
boolean
|
只讀 |
UI
|
RootPaneUI
|
讀寫 |
UIClassID
|
String
|
只讀 |
validateRoot
|
boolean
|
只讀 |
windowDecorationStyle
|
int
|
讀寫綁定 |
windowDecorationStyle屬性用來(lái)描述包含JRootPane窗口的窗口裝飾(邊框,標(biāo)題,關(guān)閉窗口的按鈕)。他可以設(shè)置為下列的JRootPane類常量:
- COLOR_CHOOSER_DIALOG
- ERROR_DIALOG
- FILE_CHOOSER_DIALOG
- FRAME
- INFORMATION_DIALOG
- NONE
- PLAIN_DIALOG
- QUESTION_DIALOG
- WARNING_DIALOG
使用windowDecorationStyle設(shè)置后的實(shí)際效果要依據(jù)于當(dāng)前的觀感。這只是一個(gè)小提示。默認(rèn)情況,這個(gè)設(shè)置為NONE。如果這個(gè)設(shè)置不為NONE,使用true值來(lái)調(diào)用JDialog或JFrame的setUndecorated()方法,并且當(dāng)前觀感的getSupportsWindowDecorations()方法報(bào)告true,那么則由觀感,而不是窗口管理器,來(lái)提供窗口裝飾。這可以使得使用高層窗口的程序看起來(lái)并不是來(lái)自于用戶所用的工作平臺(tái),而是來(lái)自于我們自己的一半,但是仍然可以提供通知,最大化,最小化以及關(guān)閉按鈕。
對(duì)于Metal觀感(以及Ocean主題),getSupportsWindowDecorations()報(bào)告true。其他系統(tǒng)提供的觀感類型報(bào)告false。圖8-2演示了由Metal觀感所提供的帶有窗口裝飾的框架樣子。
生成圖8-2的程序源碼顯示在列表8-1中。
package swingstudy.ch08; import java.awt.EventQueue; import javax.swing.JFrame; import javax.swing.JRootPane; public class AdornSample { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub Runnable runner = new Runnable() { public void run() { JFrame frame = new JFrame(" Adornment Example "); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setUndecorated( true ); frame.getRootPane().setWindowDecorationStyle(JRootPane.FRAME); frame.setSize(300, 100); frame.setVisible( true ); } }; EventQueue.invokeLater(runner); } }
?
8.1.3 自定義JRootPane觀感
表8-2顯示了JRootPane的12UIResource相關(guān)的屬性。這些中的大多數(shù)屬性與配置窗體裝飾風(fēng)格時(shí)所用的默認(rèn)邊框有關(guān)。
JRootPane UIResource元素
屬性字符串
|
對(duì)象類型 |
RootPane.actionMap
|
ActionMap |
RootPane.ancestroInputMap
|
InputMap |
RootPane.colorChooserDialogBorder
|
Border |
RootPane.defaultButtonWindowKeyBindings
|
Object[] |
RootPane.errorDialogBorder
|
Border |
RootPane.fileChooserDialogBorder
|
Border |
RootPane.frameBorder
|
Border |
RootPane.informationDialogBorder
|
Border |
RootPane.plainDialogBorder
|
Border |
RootPane.questionDialogBorder
|
Border |
RootPane.warningDialogBorder
|
Border |
RootPnaeUI
|
String |
8.1.4 RootPaneContainer接口
RootPaneContainer接口定義了用于訪問(wèn)JRootPane中的各種面板以及訪問(wèn)JRootPane本身的setter/getter方法。
public interface RootPaneContainer { // Properties public Container getContentPane(); public void setContentPane(Container contentPane); public Component getGlassPane(); public void setGlassPane(Component glassPane); public JLayeredPane getLayeredPane(); public void setLayeredPane(JLayeredPane layeredPane); public JRootPane getRootPane(); }
?
在預(yù)定義的Swing組件之中,JFrame, JWindow, JDialog,JApplet以及JInternalFrame類實(shí)現(xiàn)了RootPaneContainer接口。對(duì)于大部分來(lái)說(shuō),這些實(shí)現(xiàn)簡(jiǎn)單的將請(qǐng)求傳遞給高層容器的JRootPane實(shí)現(xiàn)。下面的代碼是RootPaneContainer的玻璃嵌板實(shí)現(xiàn):
public Component getGlassPane() { return getRootPane().getGlassPane(); } public void setGlassPane(Component glassPane) { getRootPane().setGlassPane(glassPane); }
?
8.1.5 JLayeredPane類
JLayeredPane是JRootPane的主要組件容器。JLayeredPane管理其內(nèi)部的組件的Z順序或?qū)印_@可以保證在某些任務(wù)的情況下,例如創(chuàng)建工具提示文本,彈出菜單與拖拽,正確的組件可以創(chuàng)建在其他的組件之上。我們可以使用系統(tǒng)定義的層次,或者是我們可以創(chuàng)建自己的層次。
盡管JLayeredPane容器并沒(méi)有布局管理器,但是并沒(méi)有什么可以阻止我們?cè)O(shè)置容器的layout屬性。
創(chuàng)建JLayeredPane
與JRootPane類似,我們從不親自創(chuàng)建JLayeredPane類的實(shí)例。當(dāng)為實(shí)現(xiàn)了RootPaneContainer的預(yù)定義類創(chuàng)建一個(gè)默認(rèn)的JRootPane時(shí),JRootPane為其主要的組件區(qū)域創(chuàng)建一個(gè)JLayeredPane,并添加一個(gè)初始化的內(nèi)容面板。
在層中添加組件
每一個(gè)所添加的組件的層設(shè)置管理JLayeredPane中組件的Z順序。層設(shè)置越高,則組件繪制離頂層組件就越近。當(dāng)我們向JLayeredPane中添加組件時(shí)我們可以使用布局管理的限制來(lái)設(shè)置層。
Integer layer =
new
Integer(20); aLayeredPane.add(aComponent, layer);
?
我們也可以在向JLayeredPane添加組件之前調(diào)用public void setLayer(Component comp, int layer)或public void setLayer(Component comp, int layer, int position)方法。
aLayeredPane.setLayer(aComponent, 10); aLayeredPane.add(aComponent);
JLayeredPane類預(yù)定義了六個(gè)特殊值常量。另外,我們還可以使用public int currentLayer()方法來(lái)獲得最頂部的當(dāng)前層,使用public int lowestLayer()方法獲得最底層。表8-3列出六個(gè)預(yù)定義的層常量。
JLayeredPane層常量
常量
|
描述 |
FRAME_CONTEND_LAYER
|
層-30000用于存儲(chǔ)菜單欄以及內(nèi)容面板;通常并不為開(kāi)發(fā)者所用。 |
DEFAULT_LAYER
|
零層用于通常的組件層。 |
PALETTE_LAYER
|
層100用于存儲(chǔ)浮動(dòng)工具欄以及類似的組件 |
MODAL_LAYER
|
層200用于存儲(chǔ)顯示在默認(rèn)層,調(diào)色板之上以及彈出菜單之下的彈出對(duì)話框 |
POPUP_LAYER
|
層300用于存儲(chǔ)彈出菜單以及工具提示文本 |
DRAG_LAYER
|
層400用于存儲(chǔ)保持在頂部的拖動(dòng)對(duì)象 |
?
盡管我們可以為層次使用自己的常量,但是使用時(shí)要小心,因?yàn)橄到y(tǒng)會(huì)在需要時(shí)使用預(yù)定義的常量。如果我們的常量不正確,組件就不會(huì)如我們希望的那樣工作。
圖8-3可視化的顯示了不同層是如何放置的。
使用內(nèi)容層與位置
JLayeredPane中的組件同時(shí)具有層與位置。當(dāng)某一層只有一個(gè)組件時(shí),其位于位置零。當(dāng)在相同的層有多個(gè)組件時(shí),后添加的組件具有更高的位置數(shù)字。位置設(shè)置越低,顯示距離頂部組件越近。(這與層的行為相反。)圖8-4顯示在相同層上四個(gè)組件的位置。
要重新安排一層上的組件,我們可以使用public void moveToBack(Component component)或是public void moveToFront(Component component)方法。當(dāng)我們將一個(gè)組件移到前面時(shí),他到達(dá)該層的位置0。當(dāng)我們一個(gè)組件移動(dòng)到后時(shí),他到達(dá)該層的最大位置處。我們也可以使用public void setPosition(Component component, int position)方法來(lái)手動(dòng)設(shè)置位置。位置-1自動(dòng)為具有最高位置的底層(如圖8-4)。
JLayeredPane屬性
表8-4顯示了JLayeredPane的兩個(gè)屬性。optimizedDrawingEnabled屬性決定了JlayeredPane中的組件是否可以重疊。默認(rèn)情況下,這個(gè)設(shè)置為true,在JRootPane的標(biāo)準(zhǔn)用法中,JMenuBar與內(nèi)容面板不可以重疊。然而,JLayeredPane自動(dòng)驗(yàn)證屬性設(shè)置來(lái)反映面板內(nèi)容的當(dāng)前狀態(tài)。
JLayeredPane屬性
?
屬性名
|
數(shù)據(jù)類型
|
訪問(wèn)性 |
accessibleContext
|
AccessibleContext
|
只讀 |
optimizedDrawingEnabled
|
boolean
|
只讀 |
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號(hào)聯(lián)系: 360901061
您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對(duì)您有幫助就好】元
