一直想写篇关于Swing体系结构的文章,不过一直不敢下手,怕理解的有偏差,最近看了下这方面的资料,记录下,Swing的整体组织结构如下图所示。
Swing程序要呈现出来,肯定要将组件放到JFrame,JDialog,JApplet,JWindow这几个容器组件中,这些顶层容器组件,有一个共同的结构,如上图所示,都有一个JRootPane面板来承载着所有要显示的组件。JRootPane又有以下部分组成:
1、GlassPane
2、JLayeredPane
(1)ContentPane
(2)JMenuBar
其中JRootPanel中的RootLayout对以上几部分进行布局,关于这点可以参考Java的API文档和java源码,里面有详细的说明。
这里想要说的一点是,JRootPane并不是只能放在这些顶层容器中的,你也可以放在一般的组件,比如JPanel中,这样Panel就有了层次结构,可以再其不同的层次上放置组件,这个后边还会再讲一下。
写这篇文章,并不是为了讲Swing的这个架构,主要是想通过讲述这个架构,给大家介绍些开发过程中用的技巧。
GlassPanel这个可能大家都了解了,比如,可以模拟Eclipse中Tab页签的拖拽效果,当处理一些比较费时的操作,比如加载数据时,可以用来遮罩面板,一方面可以防止用户重复操作,另一方面可以用来显示进度。不过有一点限制就是每个顶层容器中GlassPanel只能有一个(其实像上面提到的,如果一个面板中的组件都有一个JRootPane来承载组件,其实在一个程序中GlassPane也是可以有多个的,通过这个,GlassPanel和JLayeredPane几乎可以达到相同的效果)。
JLayeredPane有了深度的概念,一般的Layout在JLayeredPane是不适用的。一个Integer来标示组件在JLayeredPane中的深度,这个值越大,就会显示在越上面。JLayeredPane还有一个同层的上下关系,这个可以参考API或者源代码。重要的一点是JLayeredPane默认的Layout是null,所以,放到JLayeredPane上的组件,必须要通过setBounds的形式来设置大小才会显示出来,否则是看不到的,这点尤其要注意。JLayeredPane的层次结构能实现非常多的特效,我甚至认为,JLayeredPane 是Swing结构中,最精妙的设计之一,通过JLayeredPane我们可以实现文本的验证提示功能,举个例子,有一个文本框,用来输入电话号码,有时候可能用户会输入些字母,甚至是汉字,当用户切换到下一个面板或者最后提交验证以后,你可能希望给出一些提示来标明这些输入非法,这时候,就可以用到JLayeredPane了,你可以将非法输入的组件,传递给一个Panel,这个Panel在非法的组件旁边绘制一个小图标,然后让这个Panel显示在主界面的上面(后续会把相关代码发出)。还有另外一个用途就是使用JInternalFrame做控制面板,可以通过JLayeredPane将一个JInternalFrame悬浮到一个面板中,既不会占用程序的空间,又不会像dialog那样,必须要弹出来才可以。
附一个通过LayeredPane来显示加载进度的例子,使用方法很简单只需要将你的组件通过我的adapter封装下,然后再放到你的程序中即可MaskAdapter maskPanel = MaskAdapter.getMaskpanel(panel, false);。
下载