今天做了画图板界面的布局,感觉传统的布局都难以满足需求(难以实现画图面板的左上角停靠),所以无奈只能使用这个比较恶心的布局管理器了,由于涉及到的参数很多,因此相当复杂,而且其内的单元网格是动态的,所以也更加难以把控。。
分享下源码:http://download.csdn.net/detail/skl_tz/5406099
为了能更好的说明,此处用 xp的画图板作为列子,为了方便下面的说明,先写上一段代码:
JFrame frame = new JFrame(); JPanel panel = new JPanel(); frame.setLayout(new GridBagLayout()); frame.add(panel, new GridBagConstraints());
首先先上个图吧,有图好说话(此图的原作者为mytream),略做了点修改
这个图是 xp画图板的原型,1和2所在区域表示菜单条,3表示工具面板,4表示画图面板,5和6表示颜色选择面板,7和8表示状态面板
从红色字体标注的数字中不难发现,这个布局中一共有8个单元网格,但是在为frame设置布局时,并没有说明要创建这8个单元网格啊,这些网格是哪里来的?又应该如何理解这些网格?这应该是困扰很多人的一个问题,也是解开GridBagLayout布局之谜 的关键!
下面就来详细的解说:
官方API对于
类是一个灵活的布局管理器,它不要求组件的大小相同便可以将组件垂直、水平或沿它们的基线对齐。每个GridBagLayout是这样解说的:
GridBagLayoutGridBagLayout
对象维持一个动态的矩形单元网格,每个组件占用一个或多个这样的单元,该单元被称为显示区域。
相信很多人在看完这个描述后,应该就晕了(我也是~ ~),其中的 “一个” 二字就很难理解,难道每一个单元网格都绑定一个GridBagLayout
对象?那上面8个单元网格,不就应该有8个GridBagLayout
对象?然而实际使用时,创建GridBagLayout
对象的却只有 frame.setLayout(new GridBagLayout()); 这句,显然,就只有创建了一次。至于显示区域可以理解为就是单元格。。
new GridBagLayout()只是告诉了frame应该以网格包的方式来对其中的组件进行管理,然后就将其余职责都转交给了GridBagConstraints(),GridBagConstraints()顾名思义就是网格包约束 ,其中包含有11个约束参数,通过这些参数,可以对网格进行划分,如图就从1个大的单元格划分为8个小的单元格。所以,只要理解了这11个参数,就能很好的运用网格包了。。
参数解释(最重要的部分):
gridx, gridy : 用于指定组件的 左上角所在位置,如gridx=0 , gridy=0 就表示红色字体1所在单元格的左上角,gridx=1, gridy=1 就表示红色字体4所在单元格的左上角
gridwidth, gridheight : 用于指定组件所占用的单元格数目,如:gridwidth=2,gridheight=1 就表示占有了2个单元格宽1个单元格高的区域,如果配合gridx, gridy 使用,如:gridx=0 , gridy=0 ,gridwidth=2,gridheight=1就表示此组件占有了单元格1和单元格2,这个组件就是菜单条,以此类推,就能写出其他组件了。。
读懂前面这个参数就能完成基本的布局了。。
fill : 主要用于 当组件的大小比显示区域大小要小的时候,指定是否填充,如果不填充,组件就不会被拉伸。。
anchor : 指定组件应置于其显示区域中何处(当组件比显示区域小),可以指定为置于左上角。
insets : 指定组件与显示区域的边距(当组件比显示区域小)。
ipadx, ipady :对组件最小大小的添加量,可以指定组件的初始化大小。
weightx, weighty :指定如何分布额外的水平空间,用处有待发掘。
网格包布局其实是通过约束条件来动态的划分单元格数量的,其中gridx, gridy可以划分出单元格的数量,gridwidth, gridheight 可以接着说明某个组件所占有的单元格数量,有了这四个参数,就能划分出基本的布局了,也就是上图的样子。而下面的字段就是在划分出区域之后,指定如何放置和调整组件,仔细研究下这些字段,就能很好地运用网格包了。。