在第7章中,我們了解使用Swing組件周圍的邊框。在本章中,我們將會探討高層Swing容器,并且將會發現與相對應的AWT容器的不同。
使用Swing中的高層容器與使用高層AWT容器不同。對于AWT容器,Frame,Window,Dialog以及Applet,我們可以將組件直接添加到容器,并且我們只有一個位置來放置這些組件。在Swing世界中,高層容器,JFrame,JWindow,JDialog以及JApplet,加上JInternalFrame容器,依賴JRootPane。我們并不能將組件直接添加到容器,而只能將這些組件添加到root pane(根面板)的一部分。然后由根面板來管理這些組件。
為什么添加這個間接層呢?無論我們是否相信,這樣做是為了事情的簡化。根面板在層中管理其組件,從而如工具提示文本這樣的元素總是顯示在組件上面,而且我們不必擔心拖拽某個組件在其他組件周圍運動。
JInternalFrame并沒有相對應的AWT組件,他也提供了一些額外的功能用于處理被放置在桌面(在JDesktopPane中)中的情況。JInternalFrame可以用作在Swing程序創建多文檔界面(MDI)程序的基礎。在我們的程序中我們可以管理一系列的內部框架,并且他們絕不會超出我們的主程序容器。
下面我們開始探討新的JRootPane類,他管理所有的高層容器。
8.1 JRootPane類
JRootPane擔當高層Swing容器的容器代理。因為容器只存放一個JRootPane,當我們由高層容器中添加或是移除組件時,我們并沒有直接修改容器中的組件,而是間接的由JRootPane實例添加或是移除組件。事實上,高層容器擔當代理的角色,由JRootPane完成所有的工作。
JRootPane容器依賴其內聯類RootLayout進行布局管理,并且管理存儲JRootPane的高層容器的所有空間。在JRootPane中只有兩個組件:一個JLayeredPane以及一個玻璃嵌板(Component)。前面的玻璃嵌板可以是任意組件,而且是不可見的。玻璃嵌板保證類似工具提示文本這樣的元素顯示在其他的Swing之前。后面是JLayeredPane,在其上部包含一個可的選的JMenuBar,在其下面的另一層中包含一個內容面析(Container)。通常我們將組件放在JRootPane中就是放置在內容面板中。圖8-1有助于我們理解RootLayout是如何布局組件的。
注意:JLayerPane也僅是一個Swing容器。他可以包含任意的組件并且具有一些特定的布局特性。JRootPane面板中所用的JlayeredPane只包含一個JMenuBar以及一個Container作為其內容面板。內容面板有其自己的布局管理器,默認情況下為BorderLayout。
8.1.1 創建JRootPane
盡管JRootPane具有一個公開的無參數的構造函數,但是通常我們并不會親自創建JRootPane。相反,實現了RootPaneContainer接口的類創建JRootPane。然后,我們由該組件通過RootPaneContainer接口來獲取根面板,我們會在稍后進行描述。
8.1.2 JRootPane屬性
如表8-1所示,JRootPane有11個屬性。大多數情況下,當我們為高層容器獲取或是設置一個這樣的屬性時,例如JFrame,容器只是簡單的將請求傳遞給其JRootPane。
JRootPane的玻璃嵌板必須是透明的。因為玻璃嵌板會占據JLayeredPane前面的整個區域,一個不透明的玻璃嵌板會將其菜單欄與內容面板渲染為不可見。而且,因為玻璃嵌板與內容面板共享相同的邊界,當設置optimizedDrawingEnabled屬性時會返回玻璃嵌板的可見性。
Table 8-1. JRootPane屬性
屬性名
|
數據類型
|
訪問性 |
accessibleContext
|
AccessibleContext
|
只讀 |
contentPane
|
Container
|
讀寫 |
defaultButton
|
JButton
|
讀寫綁定 |
glassPane
|
Component
|
讀寫 |
jMenuBar
|
JMenuBar
|
讀寫 |
layeredPane
|
JLayeredPane
|
讀寫 |
optimizedDrawingEnabled
|
boolean
|
只讀 |
UI
|
RootPaneUI
|
讀寫 |
UIClassID
|
String
|
只讀 |
validateRoot
|
boolean
|
只讀 |
windowDecorationStyle
|
int
|
讀寫綁定 |
windowDecorationStyle屬性用來描述包含JRootPane窗口的窗口裝飾(邊框,標題,關閉窗口的按鈕)。他可以設置為下列的JRootPane類常量:
- COLOR_CHOOSER_DIALOG
- ERROR_DIALOG
- FILE_CHOOSER_DIALOG
- FRAME
- INFORMATION_DIALOG
- NONE
- PLAIN_DIALOG
- QUESTION_DIALOG
- WARNING_DIALOG
使用windowDecorationStyle設置后的實際效果要依據于當前的觀感。這只是一個小提示。默認情況,這個設置為NONE。如果這個設置不為NONE,使用true值來調用JDialog或JFrame的setUndecorated()方法,并且當前觀感的getSupportsWindowDecorations()方法報告true,那么則由觀感,而不是窗口管理器,來提供窗口裝飾。這可以使得使用高層窗口的程序看起來并不是來自于用戶所用的工作平臺,而是來自于我們自己的一半,但是仍然可以提供通知,最大化,最小化以及關閉按鈕。
對于Metal觀感(以及Ocean主題),getSupportsWindowDecorations()報告true。其他系統提供的觀感類型報告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相關的屬性。這些中的大多數屬性與配置窗體裝飾風格時所用的默認邊框有關。
JRootPane UIResource元素
屬性字符串
|
對象類型 |
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接口定義了用于訪問JRootPane中的各種面板以及訪問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(); }
?
在預定義的Swing組件之中,JFrame, JWindow, JDialog,JApplet以及JInternalFrame類實現了RootPaneContainer接口。對于大部分來說,這些實現簡單的將請求傳遞給高層容器的JRootPane實現。下面的代碼是RootPaneContainer的玻璃嵌板實現:
public Component getGlassPane() { return getRootPane().getGlassPane(); } public void setGlassPane(Component glassPane) { getRootPane().setGlassPane(glassPane); }
?
8.1.5 JLayeredPane類
JLayeredPane是JRootPane的主要組件容器。JLayeredPane管理其內部的組件的Z順序或層。這可以保證在某些任務的情況下,例如創建工具提示文本,彈出菜單與拖拽,正確的組件可以創建在其他的組件之上。我們可以使用系統定義的層次,或者是我們可以創建自己的層次。
盡管JLayeredPane容器并沒有布局管理器,但是并沒有什么可以阻止我們設置容器的layout屬性。
創建JLayeredPane
與JRootPane類似,我們從不親自創建JLayeredPane類的實例。當為實現了RootPaneContainer的預定義類創建一個默認的JRootPane時,JRootPane為其主要的組件區域創建一個JLayeredPane,并添加一個初始化的內容面板。
在層中添加組件
每一個所添加的組件的層設置管理JLayeredPane中組件的Z順序。層設置越高,則組件繪制離頂層組件就越近。當我們向JLayeredPane中添加組件時我們可以使用布局管理的限制來設置層。
Integer layer =
new
Integer(20); aLayeredPane.add(aComponent, layer);
?
我們也可以在向JLayeredPane添加組件之前調用public void setLayer(Component comp, int layer)或public void setLayer(Component comp, int layer, int position)方法。
aLayeredPane.setLayer(aComponent, 10); aLayeredPane.add(aComponent);
JLayeredPane類預定義了六個特殊值常量。另外,我們還可以使用public int currentLayer()方法來獲得最頂部的當前層,使用public int lowestLayer()方法獲得最底層。表8-3列出六個預定義的層常量。
JLayeredPane層常量
常量
|
描述 |
FRAME_CONTEND_LAYER
|
層-30000用于存儲菜單欄以及內容面板;通常并不為開發者所用。 |
DEFAULT_LAYER
|
零層用于通常的組件層。 |
PALETTE_LAYER
|
層100用于存儲浮動工具欄以及類似的組件 |
MODAL_LAYER
|
層200用于存儲顯示在默認層,調色板之上以及彈出菜單之下的彈出對話框 |
POPUP_LAYER
|
層300用于存儲彈出菜單以及工具提示文本 |
DRAG_LAYER
|
層400用于存儲保持在頂部的拖動對象 |
?
盡管我們可以為層次使用自己的常量,但是使用時要小心,因為系統會在需要時使用預定義的常量。如果我們的常量不正確,組件就不會如我們希望的那樣工作。
圖8-3可視化的顯示了不同層是如何放置的。
使用內容層與位置
JLayeredPane中的組件同時具有層與位置。當某一層只有一個組件時,其位于位置零。當在相同的層有多個組件時,后添加的組件具有更高的位置數字。位置設置越低,顯示距離頂部組件越近。(這與層的行為相反。)圖8-4顯示在相同層上四個組件的位置。
要重新安排一層上的組件,我們可以使用public void moveToBack(Component component)或是public void moveToFront(Component component)方法。當我們將一個組件移到前面時,他到達該層的位置0。當我們一個組件移動到后時,他到達該層的最大位置處。我們也可以使用public void setPosition(Component component, int position)方法來手動設置位置。位置-1自動為具有最高位置的底層(如圖8-4)。
JLayeredPane屬性
表8-4顯示了JLayeredPane的兩個屬性。optimizedDrawingEnabled屬性決定了JlayeredPane中的組件是否可以重疊。默認情況下,這個設置為true,在JRootPane的標準用法中,JMenuBar與內容面板不可以重疊。然而,JLayeredPane自動驗證屬性設置來反映面板內容的當前狀態。
JLayeredPane屬性
?
屬性名
|
數據類型
|
訪問性 |
accessibleContext
|
AccessibleContext
|
只讀 |
optimizedDrawingEnabled
|
boolean
|
只讀 |
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

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