网格组布局管理器GridBagLayout(又称为网格包布局管理器),是GridLayout的加强版,它是一个灵活的布局管理器,它不要求组件的大小相同便可以将组件沿垂直、水平或它们的基线对齐。每个GridBagLayout对象维持一个动态的单元网格矩形,每个组件占用一个或多个这样的单元网格,这些单元网格被称为显示区域。
每个由GridBagLayout管理的组件都需要由GridBagConstraints对象设置约束条件;Constraints 对象指定组件的显示区域在网格矩形中的具体放置位置,以及组件在其显示区域中的放置方式。除此之外还需考虑每个组件的最小大小和首选大小,以确定组件最终显示区域的大小。

使用网格组布局管理器的步骤:
创建一个GridBagLayout对象,并设置窗体容器的布局管理器为该对象。
创建组件。
给每个组件创建一个GridBagConstraints对象。设置好GridBagConstraints对象的约束属性,以确定该组件在网格组中的布局方案。
然后通过“add( component, constraints );”方法调用把组件放入容器中。

下面的例程,为了程序简明,我们把GridBagConstraints又封装为Gbc类。下面这段代码实现上面的几个步骤:
GridBagLayout layout = new GridBagLayout();
setLayout(layout); //给窗体设置布局管理器
//创建按钮A
JButton btnA = new JButton(“A”); //创建组件
Gbc gbcA = new Gbc(0, 0); //创建GridBagConstraints对象
gbcA.weightx=10; //设置另外的约束属性
gbcA.fill = Gbc.HORIZONTAL; //设置另外的约束属性
add(btnA, gbcA); //把组件放入容器

网格组布局管理器的难点是,如何正确设置GridBagConstraints对象的约束条件,另外理论上的预期结果有时与实际显示并不一致的,因此还是要经实际调试,以实际显示为准。下面我们对一些重要的约束属性进行简单介绍:
(1)属性 int gridx, gridy 默认值都为0
这两个属性gridx、gridy分别表示组件在网格矩形的行、列位置(X轴方向为gridx 、Y轴方向为gridy)。网格的坐标从0开始,其中X 向右递增,Y 向下递增。gridx=0和gridy=0表示网格坐标(0,0) 位于窗体容器的左上角(即第1行第1列);gridx=3和gridy=0表示第1行第4列。

(2)属性int gridwidth、gridheight 默认值都为 1
gridwidth、gridheight 分别指定组件的显示区域所占的网格单元数(gridwidth行、gridheight列)。gridwidth和gridheight默认值都为 1。这二个约束条件也可使用常量GridBagConstraints.REMAINDER(等同于整型数0)来指定组件的显示区域(表示组件行或列的显示区域一直延伸到行尾或列尾)。但是很遗憾的是与GridLayout布局中不同,单元网格大小不是固定大小的,实际显示区域可能与预期并不一致。

上面两个测试效果图出自同一个例程GridBagLayoutFrm.java,只是组件名长度不同。第一行的三个组件,水平方向的gridwidth属性值都是1、2、1。第一个图控件B的宽度约是A和C的2倍与预期结果相一致;但第二个图控件“网格A”、“网格B”、“网格C”的宽度好像都一样,“网格B”gridwidth属性值是2,好像与预期结果不一致;实际上组件“网格B”的二个单元网格的宽度好像缩小了一半。这就是令人疑惑不解的地方:组件的最小大小和首选大小不知是如何影响组件最终显示区域大小的。

(3)属性int fill 默认值为NONE(不填充)
fill,其字面意思是填充,也就是填充方式。只当控件显示区域大于单个单元网格时,fill属性才有效。默认值为NONE(不填充)。可用的取值还有BOTH(纵横双向填充)、HORIZONTAL(水平方向填充)、VERTICAL(垂直方向填充)。

(4)属性int anchor 默认值为CENTER(居中)
anchor,其字面意思是锚,也就是指控件显示时的停靠固定方式。anchor有很多种取值。绝对位置有8种取值分别是:NORTHWEST、NORTH、NORTHEAST、WEST、CENTER、EAST、SOUTHWEST、SOUTH、SOUTHEAST共9个方位。相对位置另有9种取值:FIRST_LINE_START、LINE_START、FIRST_LINE_END、PAGE_START、CENTER、PAGE_END、LAST_LINE_START、LINE_END、LAST_LINE_END。anchor还有其他取值。
如果组件没有填充满它的显示区域,此时可通过设置anchor来指定停靠方式。

(5)属性int ipadx、ipady 默认值为0
ipadx和ipady也被称为内部填充,该参数用以设置组件的最小尺寸,如果参数值为正值则组件的最小尺寸将比原始最小尺寸大,如果为负值,则组件的最小尺寸将会变得比原始的最小尺寸小。该参数也可以理解为直接为组件设定大小,这个设置是以组件的最小尺寸为基础。其设置后组件的大小为组件的原始最小尺寸加上ipadx*2个像素。ipadx用于修正组件的宽度;ipady则用于修正组件的高度。
(6)属性insets 默认值为 new Insets(0, 0, 0, 0)
insets被称为外部填充,指定组件边框周围的外部填充,即组件与其组件之间间距的最小量。要注意的是即使使用了fill参数填充横向和纵向,但只要设置了insets参数,同样会留出insets所设置的空白区域。
insets参数通过设置Insets对象的top、left、bottom和right四个方向的值来调整组件与组件之间间距大小,比如“gbc.insets = new Insets(10,10,10,10);”其中gbc是GridBagConstraints类型的约束对象,这里要注意后面的new Insets其中的Insets第一个字母是大写的。当然也可以为Insets指定负值参数,以扩大组件的显示区域。

(7)属性值 double weightx、weighty 默认值为0.0
weightx和weighty这两个属性参数可分别对x方向和y方向指定一个权重值。这两个参数与fill属性有关联性,当窗体缩放时有作用。当组件以最小尺寸显示时这个参数好像没有作用;若两参数使用默认值,则当窗体缩放时组件不改变大小;如果同一行中的组件都使用默认值,则窗体缩放时组件不改变大小,而且组件只显示在窗体中央。
这两参数可分别对x方向和y方向指定一个权重值。这个权重值直接影响到窗体放大时组件显示区域的大小,例如,同一行有三个组件,它们的fill属性为HORIZONTAL,当它们的weightx值分别为10,20,30,则在容器窗体的x方向三个组件按设定的权重分配每个组件的宽度,其中权重值越大的组件显示宽度越大,但好像也不是精确按指定比例显示大小。
如果同一行中的多个组件,只有一个组件设置了weightx值(非默认值),它们的fill属性为HORIZONTAL,当窗体缩放时,只有设置了weightx值的组件会动态放大,其他组件只则维持首选的组件尺寸大小不变。
属性参数weightx、weighty的优先级大于属性gridwidth、gridheight。例如:同一行放置二个组件,设置二个组件权重相同weightx=10,第一个组件gridwidth=2(占2个单元网格列),第二个组件gridwidth=1(占1个单元网格列),当窗体放大时,二个组件显示区域的宽度却是相同的。可自行编程测试。
因此在使用GridBagLayout网格包布局管理器时,一定要进行反复测试,程序的实际结果与你想象的预期结果不完全一样。

GridBagLayou是一种有弹性的布局管理器,而且网格单元可以不填满整个容器。下面的例程中我们演示了7个不同形状和大小按钮的摆放。这是一个很有意思的例程,你可注释掉一部分按钮或亦可修改一些属性参数,反复进行测试验证,有时候好像得不到预期的效果,有时候又显示预期效果,请测试体验并思考其中的原因,以加强对这种管理器约束条件的理解。

import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import javax.swing.*;
public class GridBagLayoutTest extends JFrame {public GridBagLayoutTest() {GridBagLayout layout = new GridBagLayout();setLayout(layout);//创建按钮AJButton btnA = new JButton("A");Gbc gbcA = new Gbc(0, 0);gbcA.weightx=10;gbcA.fill = Gbc.HORIZONTAL;add(btnA, gbcA);//创建按钮BJButton btnB = new JButton("B");Gbc gbcB = new Gbc(1, 0);gbcB.weightx=20;gbcB.fill = Gbc.HORIZONTAL;gbcB.setInsets(0, 5, 0, 0);add(btnB, gbcB);//创建按钮CJButton btnC = new JButton("C");Gbc gbcC = new Gbc(2, 0, 1, 2);gbcC.weightx=30;gbcC.fill = Gbc.BOTH;gbcC.setInsets(0, 5, 0, 0);add(btnC, gbcC);//创建按钮DJButton btnD = new JButton("D");Gbc gbcD = new Gbc(0, 1, 2, 1);gbcD.fill = Gbc.HORIZONTAL;gbcD.setInsets(5, 0, 0, 0);add(btnD, gbcD);//创建按钮EJButton btnE = new JButton("E");Gbc gbcE = new Gbc(3, 0, 1, 3);//new Gbc(3, 0, 1, Gbc.REMAINDER);gbcE.weightx=40;gbcE.fill = Gbc.VERTICAL;gbcE.setInsets(0, 5, 0, 0);add(btnE, gbcE);//创建按钮FJButton btnF = new JButton("F");Gbc gbcF = new Gbc(0, 2, 1, 1);gbcF.fill = Gbc.HORIZONTAL;gbcF.setInsets(5, 0, 0, 0);add(btnF, gbcF);//创建按钮GJButton btnG = new JButton("G");Gbc gbcG = new Gbc(1,2, 2,1);gbcG.fill = Gbc.HORIZONTAL;gbcG.setInsets(5, 5, 0, 0);add(btnG, gbcG);setTitle("网格组布局测试");pack();setVisible(true);}public static void main(String[] args) {    new GridBagLayoutTest();  }
}class Gbc extends GridBagConstraints {/**此构造器gridwidth和gridheight使用默认值1**/public Gbc(int gridx,int gridy) {this.gridx = gridx;this.gridy = gridy;}public Gbc(int gridx,int gridy,int gridwidth,int gridheight) {this.gridx = gridx;this.gridy = gridy;this.gridwidth = gridwidth;this.gridheight = gridheight;}//设置外边距public Gbc setInsets(int top,int left,int bottom,int right) {this.insets = new Insets(top, left, bottom, right);return this;}
}   //网格组布局管理器例程GridBagLayoutTest.java结束。

下面这二个测试效果图都是这个例程的:大图是窗口放大时的效果;小图是窗口未缩放时的效果。

大图中,组件A、组件B和组件C的权重比例是1:2:3。当窗体扩大时,组件B和C显示区域有所扩大,但好像也与设定的权重比例不完全一致。

下面是第二个测试例程GridBagLayoutFrm.java,请多做一些测试调试,以体验网络组布局管理器的特性。请仔细观测三种情形有何异同:
情形一:直接编译调试,对程序窗体进行缩放。
情形二:修改第一行的三个按钮名用单字母命名,再编译调试,对程序窗体进行缩放。
情形三:放开三个按钮gbc.weightx 的注释,再编译调试,对程序窗体进行缩放。

import java.awt.*;
import javax.swing.*;
public class GridBagLayoutFrm extends JFrame {public GridBagLayoutFrm() {GridBagLayout layout = new GridBagLayout();setLayout(layout);//创建按钮AJButton btn = new JButton("网格A");Gbc gbc = new Gbc(0,0);//组件尺寸,默认1*1网格//gbc.weightx = 10.0;gbc.fill = Gbc.HORIZONTAL; //填充方式:水平填充add(btn, gbc);//创建按钮Bbtn = new JButton("网格B");gbc = new Gbc(1,0,2,1);//组件尺寸,2*1网格//gbc.weightx = 20.0;//gbc.fill = Gbc.BOTH;gbc.fill = Gbc.HORIZONTAL;add(btn, gbc);//创建按钮Cbtn = new JButton("网格C");gbc = new Gbc(3, 0);//gbc.weightx = 30.0;gbc.fill = Gbc.HORIZONTAL;add(btn, gbc);//创建按钮Dbtn = new JButton("网格D");gbc = new Gbc(0,1,3,1);//组件尺寸,3*1网格gbc.fill = Gbc.HORIZONTAL;gbc.ipady = 20; //组件高度增加内部填充add(btn, gbc);//创建按钮Ebtn = new JButton("网格E");gbc = new Gbc(1, 2, 2, 1);gbc.ipady=0;gbc.weighty=1.0;gbc.fill = Gbc.HORIZONTAL;gbc.setInsets(10, 0, 0, 0); //增加外部填充gbc.anchor = Gbc.PAGE_END; //停靠于页结束处add(btn, gbc);setTitle("网格组布局Demo");pack();setVisible(true);}public static void main(String[] args) {EventQueue.invokeLater(()->{new GridBagLayoutFrm();}); }
}   //网格组布局管理器例程GridBagLayoutFrm.java结束。

网格组布局管理器(GridBagLayout)网格包布局管理器相关推荐

  1. Java GridBagLayout(网格包布局管理器)

    概述 GridBagLayout(网格包布局管理器)是在网格基础上提供复杂的布局,是最灵活. 最复杂的布局管理器.GridBagLayout 不需要组件的尺寸一致,允许组件扩展到多行多列.每个 Gri ...

  2. 【Java AWT 图形界面编程】LayoutManager 布局管理器 ④ ( GridLayout 网格布局 | GridBagLayout 网格包布局 )

    文章目录 一.GridLayout 网格布局 二.GridLayout 构造函数 三.GridLayout 网格布局代码示例 四.GridBagLayout 网格包布局 一.GridLayout 网格 ...

  3. java 网格布局管理器,Java使用网格组布局管理器

    package com.han; import java.awt.Container; import java.awt.GridBagConstraints; import java.awt.Grid ...

  4. GridBagConstraints(网格组布局管理器的使用)

    GridBagConstraints特征: 由GridBagConstraints类实现的布局管理器称为网格组布局管理器,它实现了一个动态的矩形网格,这个矩形风格由无数个矩形单元格组成,每个组件可以占 ...

  5. java常用布局管理器(流布局管理器、边界布局管理器、网格布局管理器)

    在Swing中,每个组件在容器中都有一个具体的位置大小.而在容器中摆放各种组件时很难判断其具体位置和大小,使用布局管理器比程序员直接在容器中控制Swing组件的位置和大小方便得多,可以更加有效地处理整 ...

  6. python布局管理_Python基础=== Tkinter Grid布局管理器详解

    本文转自:https://www.cnblogs.com/ruo-li-suo-yi/p/7425307.html          @ 箬笠蓑衣 Grid(网格)布局管理器会将控件放置到一个二维的表 ...

  7. java gui 布局 旋转_JAVA GUI编程之布局管理器

    JAVA的GUI(图形用户界面)由各种组件构成,主要分为AWT组件(java.awt)以及功能更强的Swing组件(javax.swing)两种. 组件可以分为容器组件和非容器组件.容器组件是指可以包 ...

  8. 布局管理器android,Android课程---布局管理器之相对布局(一)

    下面示例的是在父容器里如何设置按钮的位置,难度:***,重点是找到一个主按钮,设置它的id,然后根据它来设置其他按钮在父容器的位置. 代码示例: android:layout_width=" ...

  9. 响应式网格项目动画布局_响应式网格及其实际使用方式:常见的UI布局

    响应式网格项目动画布局 重点 (Top highlight) 第二部分 (Part II) Now that you have a basic understanding of how to use ...

最新文章

  1. 3D物体分类---ModelNet .OFF格式生成多视角图像(Blender方法之第二步)
  2. python中的库及module的 路径
  3. golang的reflection(转)(一)
  4. 密码学-网站的安全登录认证设计
  5. 面向对象的基本概念(二)--UML.类之间的关系
  6. ACM training贪心算法——坐椅子的背包问题
  7. 推荐一个滴滴开源的跨端整体解决方案!
  8. vMix(视频混合器软件)v22.0.0.48免费版
  9. Syclover-Web题解
  10. 分布图用什么软件制作,公司区域分布图怎么做
  11. Solr_专题:shema 之 types
  12. 物联网的背景及其发展
  13. 《Java程序小作业之自动贩卖机》#谭子
  14. KL Divergence KL散度
  15. PDO中错误处理:errorCode方法和errorInfo方法
  16. OSChina 周四乱弹 ——老板:把骨头统统交出来
  17. 计算机邵博士网课,程序设计入门——C语言(邵绪强)
  18. 字符串全排列与组合算法以及八皇后问题
  19. 陷波滤波器设计及应用
  20. 分享扫描文字识别软件的操作方法

热门文章

  1. Switchhosts软件的使用
  2. vue后台管理系统中,table表格页面使用mixins【混入自用】
  3. 华米变心:只因大健康前景太勾引人?
  4. 基于虹软人脸识别-iOS画框更改及前后摄像头的切换
  5. pdf文件的分割使用工具
  6. SDUT ACM 4078 女装大佬买地
  7. 绿水青山苗疆行 新年游走黔东南
  8. 最小生成树克鲁斯卡尔算法
  9. copy语法 postgre_PostgreSQL copy 命令教程详解
  10. 微信官方揭秘高收益骗局:既骗用户还骗运营者