Root Pane Containers (一)
注意: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只读
contentPane读写
defaultButton读写绑定
glassPane读写
jMenuBar读写
layeredPane读写
optimizedDrawingEnabled只读
UI读写
UIClassID只读
validateRoot只读
windowDecorationStyle读写绑定
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.actionMapActionMap
RootPane.ancestroInputMapInputMap
RootPane.colorChooserDialogBorderBorder
RootPane.defaultButtonWindowKeyBindingsObject[]
RootPane.errorDialogBorderBorder
RootPane.fileChooserDialogBorderBorder
RootPane.frameBorderBorder
RootPane.informationDialogBorderBorder
RootPane.plainDialogBorderBorder
RootPane.questionDialogBorderBorder
RootPane.warningDialogBorderBorder
RootPnaeUIString
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零层用于通常的组件层。
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只读
optimizedDrawingEnabled只读