这个题目起的有点难懂,但也实在想不出更好的题目来。所谓分层Pane结构是指JFrame/JApplet/JDialog等Swing顶层容器
的JRootPane/JLayeredPane/GlassPane/ContentPane结构。所谓Swing组件高级特性其实是指某些组件的特殊
功能的实现,比如弹出菜单、Tooltip、JComboBox的下拉窗口、Drag and Drop实现、Docking
Pallete窗口等等。这些特性同普通组件不同,它们往往需要动态的变化、覆盖其他组件,它们之间存在一定层次关系。那么Swing中是怎么样实现这些
功能呢?
一直以来想写一篇文章来描述这个关键结构,但每次总被自己的语言表达能力所限制。Swing这个精巧结构是我叹服的原因之一。虽然一般的
GUI系统设计原理我都知道,但是细节如此处精细却不是一开始就能清楚的。我在2000年以前曾经写过大量基于AWT
Canvas的自定义组件,当时认为Swing的自定义组件也不过如此,原理不过也是给我一个刷子,我给你画出来。但是上述所说的这些特性,却从来没能实
现过。我想过很多方法,做过很多实验,但终究没有想透这一层。之后某次偶然机会,看到了下面这张著名的图,使我豁然开朗。让我又一次理解了创新需要跳出旧
的思维模式勇气和智慧。
简单来说Swing中这些顶层容器的多Pane结构是实现这些特性的基础。这些Pane实际是一些特殊的JComponent,它们之间存在包含被包含、覆盖被覆盖的树状多层次结构。我重新画了上面这张图,使得其更具体、更直观,更容易理解些:
其实有了这张图,加上图形系统中Z-order的概念,就不难理解并实现上面提到的特性。Z-order概念和图形学中Z深度是一致
的。离观察点近的物体总是会遮挡离观察点远的物体。物体所在法平面离观察点的距离就是所谓Z深度。Swing中通过先画出Z-order远(小)的组件,
再画Z-order近(大)的组件的方法实现组件之间的遮挡关系。每个组件所在平面的都有一个数字描述其位置,这个位置同三维坐标系中的Z轴类似,离观察
者越近,坐标越大:
Swing的顶层容器都包含有一个JRootPane,该JRootPane是一切Swing组件起点。JRootPane中包含了一个
JLayeredPane和一个GlassPane。GlassPane和JLayeredPane都是充满JRootPane的。GlassPane缺
省情况下是不可见的,因此我们看到都是JLayeredPane。GlassPane如果是可见的,它Z-order大于任何其他组件,因此它会覆盖住整
个窗口,使得所有的鼠标事件都被它截获。另外通常可见情况下它是透明的,因此你能仍然看到JLayeredPane上面的一切,但是
JLayeredPane上面的组件都得不到鼠标事件。
GlassPane这个奇怪的组件主要是用来实现Drag &
Drop以及跨组件渲染用的。NetBeans和Eclipse中哪种常见的Docking
Frame的实现就和这种组件相关。这些工程、文件、源代码的窗口其实不过是普通的Swing组件,它们本身并不能实现这种拖拽功能。鼠标在它们上面标题
栏区域按下之后,标题栏组件会检测到这种事件,经过粘连性判断后,如果发现这些鼠标事件目的是拖拽窗口,这种Docking系统就会将拖拽区域(即所谓的
ClientArea)的GlassPane设置为可见,于是下面的一些列拖拽鼠标事件就被这个GlassPane所接管了过去。GlassPane是覆
盖于应用程序ClientArea的透明组件,它处理这些事件时计算出当前鼠标位置所蕴含着的拖拽动作,并根据这些动作画出相应的焦点矩形。
NetBeans的Docking
Framework一个拖拽过程如下图所示.注意GlassPane是背景透明的,所以可以在上面画背景透明的焦点矩形:
JLayeredPane是实现弹出式窗口或类似Pallete浮动窗口的主要组件。如同它的名字一样,它将自己的内部结构也分成许多
亚层。在使用它的add(Component,
Object)方法加入组件时,第二个参数是一个Integer值,这个值决定了加入的层。这个值相当于前面所说的Z-order值。目前主要有下面几个
预定义值:
public final static Integer DEFAULT_LAYER = new Integer(0);
这层加入的缺省层。
public final static Integer PALETTE_LAYER = new Integer(100);
这层是定义Palette窗口的层。那种浮动选项窗口属于这一层。
public final static Integer MODAL_LAYER = new Integer(200);
这层是模态对话框的层。这个模态对话框应该是指JInternalFrame的模态对话框,而不是JDialog。
public final static Integer POPUP_LAYER = new Integer(300);
这层是菜单、下拉框窗口、Tooltip等窗口浮动的层。
public final static Integer DRAG_LAYER = new Integer(400);
这一层是拖拽层,组件可以在这一层被托拽。
public final static Integer FRAME_CONTENT_LAYER = new Integer(-30000);
这一层是ContentPane和MenuBar所在的层。注意它非常小,前面所有层的组件都会覆盖这一层的组件。我们知道ContentPane是所有应用程序组件所在的地方。
JLayeredPane直接包含有ContentPane组件。应用程序如果定了MenuBar,JLayeredPane还包含
MenuBar。注意JLayeredPane本身没有布局管理器,它对组件的布局是由它的父容器JRootPane的布局管理器RootLayout来
完成的。简单来说,所在层数值小的组件有可能被高层组件所覆盖。Swing将不同类型的组件放置在不同层面上,就实现了文章一开始提到的特性:菜单、浮动
窗口、下拉框窗口和Tooltip等。当然这些窗口有可能不是JLayeredPane上的轻量级Swing组件,当它们的边界超过顶层容器的窗口时,这
些窗口的就变成了重量级AWT窗口。这在上一篇文章《
如何混排Swing和AWT组件
》
中已经提到过。
下面是这些Pane组件之间的树状包含关系图:
本文的目的是讲述Swing的这种组件层次结构,并不是讲述如何使用JLayeredPane和GlassPane来实现某中特殊的功
能。如果需要学习如何使用它们实现某些特殊效果,Java Tutorial的Swing部分提供了详尽的编程资料。Java
Tutorial的Swing部分编程在:
如何使用RootPane、GlassPane和JLayeredPane分别见下面的章节:
分享到:
相关推荐
分层介绍java Swing组件,详细说明rootPane,LayeredPane,rootPane,contentPane之间的关系
在Java的Swing库中,实现组件的透明拖动是一项常用的功能,这使得用户界面更加美观和交互友好。Swing提供了丰富的组件库,允许开发者创建复杂的GUI应用,并且支持自定义外观和行为。本篇文章将深入探讨如何在Swing中...
JFC Swing的高级特性还包括对键盘快捷键的支持、对国际化和本地化(i18n/l10n)的支持,这些特性让Swing的应用程序能够适应不同文化和语言环境。 通过阅读和学习《深入学习:JFC Swing-Java基础类组件集》,开发者...
通过这个例子,初学者可以深入理解如何使用Swing组件创建交互式的窗口应用,以及如何通过自定义代码实现更高级的功能,如窗体风格的动态切换。这有助于提升Java GUI编程的技巧,对于开发桌面应用或者需要创建复杂...
**高级篇:自定义组件与高级特性** 在高级阶段,学习如何创建自定义组件是必要的,这可能涉及到继承现有的JComponent或JPanel类,并添加特殊的功能。此外,高级特性如Swing Workers(用于后台线程处理),以及如何...
在实际开发中,`JTaskPane`通常与其他Swing组件一起使用,如`JTabbedPane`、`JOptionPane`等,以创建更丰富的应用程序。例如,你可能会在一个`JTabbedPane`中使用多个`JTaskPane`,每个任务窗格代表一类任务。 总结...
"SWING 图像设计"这一主题,聚焦于利用Swing进行图像和动画的设计与实现,这在开发交互式应用时尤为重要。 Swing是Java Foundation Classes (JFC)的一部分,它建立在早期的Abstract Window Toolkit (AWT)之上,弥补...
Swing组件的添加不同于AWT,Swing组件不能直接添加到顶级容器,而是需要添加到顶级容器的内容面板(content pane)上。例如,对于JFrame,我们可以通过`getContentPane()`方法获取内容面板,然后使用`add()`方法添加...
Swing还包含JLayer和JComponent的glass pane特性,这些可以用来实现高级的界面特效。JLayer允许在组件上添加额外的行为,比如拖放操作、透明效果或者自定义绘制。玻璃pane则可以在整个窗口上添加全局的交互效果,...
5. **响应式设计**:与CSS媒体查询结合,可以实现不同屏幕尺寸下的布局变化。 6. **API控制**:通过组件的API,可以在运行时动态改变面板的大小,适应不同的业务逻辑。 7. **可定制化**:支持自定义分隔符样式和行为...
Swing组件的核心特点是它们都是轻量级的,这意味着它们的实现不依赖于底层操作系统,这使得Swing在跨平台兼容性和性能上有优势。Swing提供了一系列组件,如按钮(JButton)、文本框(JTextField)、标签(JLabel)、...
Swing组件与AWT组件的一个显著区别在于,它们不能直接添加到顶级容器,而是需要添加到内容面板(content pane)上。例如,对于JFrame,我们可以通过`frame.getContentPane().add(childComponent)`来添加组件。在Java...
import javax.swing.BorderFactory; import javax.swing.Box; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JDialog; import javax.swing.JFrame; import javax.swing.JLabel; ...
在Swing中,我们可以使用JTable和JTree来创建表格和树形视图,这两个组件可以独立使用,也可以结合在一起,形成一个具有表格和树结构的复杂视图,这在数据展示和操作时非常有用。 **JTable组件** JTable是Swing中...
在Swing中创建GUI时,有一个重要的规则:Swing组件不能直接添加到顶层容器(如JFrame、JApplet、JDialog和JWindow)中,而是需要先添加到一个内容面板(content pane)或者中间容器上。例如,通常会使用...
可能包括如何布局组件(如使用FlowLayout,BorderLayout,GridLayout, MigLayout等),如何创建菜单栏和快捷键,如何处理键盘和鼠标事件,以及如何使用内置的Swing组件实现复杂的功能,如文件选择对话框,表格...
1. **数据结构与模型**:contacts-pane可能定义了一种数据结构,用于存储和操作联系人信息,如姓名、电话号码、电子邮件地址等。这通常涉及到JavaScript对象或者类的设计,确保数据的组织和访问符合预期。 2. **...
在本文中,我们将深入探讨如何基于Vue.js框架实现一个面板分割组件。Vue.js是一个轻量级、高性能的前端JavaScript框架,被广泛用于构建用户界面。面板分割组件在各种Web应用中非常常见,它允许用户动态调整两个或多...
与 AWT 组件不同,Swing 组件不能直接添加到顶层容器中,它必须添加到一个与 Swing 顶层容器相关联的内容面板(content pane)上。基本规则如下: 1. 把 Swing 组件放入一个顶层 Swing 容器的内容面板上 2. 避免...
为了实现完全透明的窗体,开发者可能还使用了`Glass Pane`技术,使其成为所有组件的父容器并处理透明效果。 接下来,秒表的鼠标拖拽事件功能表明它实现了窗口的动态移动。在Java Swing中,可以通过添加`...