当前位置:网站首页>LayoutManager布局管理器:FlowLayout、BorderLayout、GridLayout、GridBagLayout、CardLayout、BoxLayout
LayoutManager布局管理器:FlowLayout、BorderLayout、GridLayout、GridBagLayout、CardLayout、BoxLayout
2022-07-04 05:35:00 【斯文~】
文章目录
概述
之前,我们介绍了Component中有一个方法 setBounds() 可以设置当前容器的位置和大小,但是我们需要明确一件事,如果我们手动的为组件设置位置和大小的话,就会造成程序的不通用性,例如:Label label = new Label("你好,世界");
创建了一个lable组件,很多情况下,我们需要让lable组件的宽高和 你好,世界
这个字符串自身的宽高一致,这种大小称为最佳大小。由于操作系统存在差异,例如在windows上,我们要达到这样的效果,需要把该Lable组件的宽和高分别设置为100px,20px,但是在Linux操作系统上,可能需要把Lable组件的宽和高分别设置为120px,24px,才能达到同样的效果。
如果要让我么的程序在不同的操作系统下,都有相同的使用体验,那么手动设置组件的位置和大小,无疑是一种灾难,因为有太多的组件,需要分别设置不同操作系统下的大小和位置。为了解决这个问题,Java提供了LayoutManager布局管理器,可以根据运行平台来自动调整组件大小,程序员不用再手动设置组件的大小和位置了,只需要为容器选择合适的布局管理器即可。
Panel
默认使用FlowLayout
管理其内部组件布局。Window
下的 Frame
、Dialog
以及ScrollPane
默认使用BorderLayout
管理器。
FlowLayout
概述、构造器
在 FlowLayout 布局管理器 中,组件像水流一样向某方向流动 (排列) ,遇到障碍(边界)就折回,重头开始排列 。在默认情况下, FlowLayout 布局管理器从左向右排列所有组件,遇到边界就会折回下一行重新开始。
构造方法 | 方法功能 |
---|---|
FlowLayout() | 使用默认 的对齐方式及默认的垂直间距、水平间距创建 FlowLayout 布局管理器 |
FlowLayout(int align) | 使用指定的对齐方式及默认的垂直间距、水平间距创建 FlowLayout 布局管理器 |
FlowLayout(int align,int hgap,int vgap) | 使用指定的对齐方式及指定的垂直问距、水平间距创建FlowLayout 布局管理器 |
FlowLayout 中组件的排列方向(从左向右、从右向左、从中间向两边等) , 该参数应该使用FlowLayout类的静态常量 : FlowLayout. LEFT 、 FlowLayout. CENTER 、 FlowLayout. RIGHT
,默认是左对齐。
FlowLayout 中组件间距通过整数设置,单位是像素,默认是5个像素。
代码示例
import java.awt.*;
public class FlowLayoutDemo {
public static void main(String[] args) {
//1.创建Frame对象
Frame frame = new Frame("这里测试FlowLayout");
//2.修改Frame容器的布局管理器为FlowLayout
frame.setLayout(new FlowLayout(FlowLayout.LEFT,20,20));
//3.往Frame中添加100个button
for (int i = 0; i < 100; i++) {
frame.add(new Button("按钮"+i));
}
//4.设置Frame为最佳大小
frame.pack();
//5.设置Frame可见
frame.setVisible(true);
}
}
BorderLayout
概述、构造器
BorderLayout 将容器分为 EAST 、 SOUTH 、 WEST 、 NORTH 、 CENTER
五个区域,普通组件可以被放置在这 5 个区域的任意一个中,BorderLayout布局 管理器的布局示意图如图所示。
当改变使用 BorderLayout 的容器大小时, NORTH 、 SOUTH 和 CENTER
区域水平调整,而 EAST 、 WEST 和 CENTER
区域垂直调整。使用BorderLayout 有如下两个注意点:
1.当向使用 BorderLayout 布局管理器的容器中添加组件时 , 需要指定要添加到哪个区域中 。 如果没有指定添加到哪个区域中,则默认添加到中间区域中;
2.如果向同一个区域中添加多个组件时 , 后放入的组件会覆盖先放入的组件;
构造方法 | 方法功能 |
---|---|
BorderLayout() | 使用默认的水平间距、垂直 间距创建 BorderLayout 布局管理器 |
BorderLayout(int hgap,int vgap): | 使用指定的水平间距、垂直间距创建 BorderLayout 布局管理器 |
代码示例1
import java.awt.*;
public class BorderLayoutDemo1 {
public static void main(String[] args) {
//1.创建Frame对象
Frame frame = new Frame("这里测试BorderLayout");
//2.指定Frame对象的布局管理器为BorderLayout
frame.setLayout(new BorderLayout(30,5));
//3.往Frame指定东南西北中各添加一个按钮组件
frame.add(new Button("东侧按钮"), BorderLayout.EAST);
frame.add(new Button("西侧按钮"), BorderLayout.WEST);
frame.add(new Button("南侧按钮"), BorderLayout.SOUTH);
frame.add(new Button("北侧按钮"), BorderLayout.NORTH);
frame.add(new Button("中间按钮"), BorderLayout.CENTER);
//4.设置Frame为最佳大小
frame.pack();
//5.设置Frame可见
frame.setVisible(true);
}
}
代码示例2
如果不往某个区域中放入组件,那么该区域不会空白出来,而是会被其他区域占用。
import java.awt.*;
public class BorderLayoutDemo2 {
public static void main(String[] args) {
//1.创建Frame对象
Frame frame = new Frame("这里测试BorderLayout");
//2.指定Frame对象的布局管理器为BorderLayout
frame.setLayout(new BorderLayout(30,5));
//3.往Frame指定南,北,放入一个按钮,往中间区域放入一个Panel
frame.add(new Button("南侧按钮"), BorderLayout.SOUTH);
frame.add(new Button("北侧按钮"), BorderLayout.NORTH);
Panel panel = new Panel();
panel.add(new TextField("测试文本"));
panel.add(new Button("中间按钮"));
frame.add(panel, BorderLayout.CENTER);
//4.设置Frame为最佳大小
frame.pack();
//5.设置Frame可见
frame.setVisible(true);
}
}
GridLayout
概述、构造器
GridLayout 布局管理器将容器分割成纵横线分隔的网格 , 每个网格所占的区域大小相同。当向使用 GridLayout 布局管理器的容器中添加组件时, 默认从左向右、 从上向下依次添加到每个网格中 。 与 FlowLayout不同的是,放置在 GridLayout 布局管理器中的各组件的大小由组件所处的区域决定(每 个组件将自动占满整个区域) 。
构造方法 | 方法功能 |
---|---|
GridLayout(int rows,in t cols) | 采用指定的行数、列数,以及默认的横向间距、纵向间距将容器 分割成多个网格 |
GridLayout(int rows,int cols,int hgap,int vgap) | 采用指定 的行数、列 数 ,以及指定的横向间距 、 纵向间距将容器分割成多个网格 |
代码示例
使用Frame+Panel,配合FlowLayout和GridLayout完成一个计算器效果。
import java.awt.*;
public class GridLayoutDemo{
public static void main(String[] args) {
//1.创建Frame对象,并且标题设置为计算器
Frame frame = new Frame("计算器");
//2.创建一个Panel对象,并且往Panel中放置一个TextField组件
Panel p1 = new Panel();
p1.add(new TextField(30));
//3.把上述的Panel放入到Frame的北侧区域
frame.add(p1,BorderLayout.NORTH);
//4.创建一个Panel对象,并且设置其布局管理器为GridLayout
Panel p2 = new Panel();
p2.setLayout(new GridLayout(3,5,4,4));
//5.往上述Panel中,放置15个按钮,内容依次是:0,1,2,3,4,5,6,7,8,9,+,-,*,/,.
for (int i = 0; i < 10; i++) {
p2.add(new Button(i+""));
}
p2.add(new Button("+"));
p2.add(new Button("-"));
p2.add(new Button("*"));
p2.add(new Button("/"));
p2.add(new Button("."));
//6.把上述Panel添加到Frame的中间区域中国
frame.add(p2);
//7.设置Frame为最佳大小
frame.pack();
//8.设置Frame可见
frame.setVisible(true);
}
}
GridBagLayout
概述
GridBagLayout 布局管理器的功能最强大 , 但也最复杂,与 GridLayout 布局管理器不同的是, 在GridBagLayout 布局管理器中,一个组件可以跨越一个或多个网格 , 并可以设置各网格的大小互不相同,从而增加了布局的灵活性 。 当窗口的大小发生变化时 , GridBagLayout 布局管理器也可以准确地控制窗口各部分的拉伸 。
由于在GridBagLayout 布局中,每个组件可以占用多个网格,此时,我们往容器中添加组件的时候,就需要具体的控制每个组件占用多少个网格,java提供的GridBagConstaints类,与特定的组件绑定,可以完成具体大小和跨越性的设置。
GridBagConstraints API
成员变量 | 含义 |
---|---|
gridx | 设置受该对象控制的GUI组件左上角所在网格的横向索引 |
gridy | 设置受该对象控制的GUI组件左上角所在网格的纵向索引 |
gridwidth | 设置受该对象控制的 GUI 组件横向跨越多少个网格,如果属性值为 GridBagContraints.REMAIND,则表明当前组件是横向最后一个组件,如果属性值为GridBagConstraints.RELATIVE,表明当前组件是横向倒数第二个组件。 |
gridheight | 设置受该对象控制的 GUI 组件纵向跨越多少个网格,如果属性值为 GridBagContraints.REMAIND,则表明当前组件是纵向最后一个组件,如果属性值为GridBagConstraints.RELATIVE,表明当前组件是纵向倒数第二个组件。 |
fill | 当"显示区域"大于"组件"的时候,如何调整组件 : GridBagConstraints.NONE : GUI 组件不扩大 GridBagConstraints.HORIZONTAL: GUI 组件水平扩大 以 占据空白区域 GridBagConstraints.VERTICAL: GUI 组件垂直扩大以占据空白区域 GridBagConstraints.BOTH: GUI 组件水平 、 垂直同时扩大以占据空白区域. |
ipadx | 设置受该对象控制的 GUI 组件横向内部填充的大小,即 在该组件最小尺寸的基础上还需要增大多少. |
ipady | 设置受该对象控制的 GUI 组件纵向内部填充的大小,即 在该组件最小尺寸的基础上还需要增大多少. |
insets | 设置受该对象控制 的 GUI 组件的 外部填充的大小 , 即该组件边界和显示区 域边界之间的 距离 . |
weightx | 设置受该对象控制 的 GUI 组件占据多余空间的水平比例, 假设某个容器 的水平线上包括三个 GUI 组件, 它们的水平增加比例分别是 1 、 2 、 3 , 但容器宽度增加 60 像素 时,则第一个组件宽度增加 10 像素 , 第二个组件宽度增加 20 像素,第三个组件宽度增加 30 像 素。 如 果其增 加比例为 0 , 则 表示不会增加 。 |
weighty | 设置受该对象控制 的 GUI 组件占据多余空间的垂直比例 |
anchor | 设置受该对象控制 的 GUI 组件在其显示区域中的定位方式: GridBagConstraints .CENTER (中 间 ) GridBagConstraints.NORTH (上中 ) GridBagConstraints.NORTHWEST (左上角) GridBagConstraints.NORTHEAST (右上角) GridBagConstraints.SOUTH (下中) GridBagConstraints.SOUTHEAST (右下角) GridBagConstraints.SOUTHWEST (左下角) GridBagConstraints.EAST (右中) GridBagConstraints.WEST (左中) |
GridBagLayout使用步骤
1.创建GridBagLaout布局管理器对象,并给容器设置该布局管理器对象;
2.创建GridBagConstraints对象,并设置该对象的控制属性:
gridx: 用于指定组件在网格中所处的横向索引;
gridy: 用于执行组件在网格中所处的纵向索引;
gridwidth: 用于指定组件横向跨越多少个网格;
gridheight: 用于指定组件纵向跨越多少个网格;
3.调用GridBagLayout对象的setConstraints(Component c,GridBagConstraints gbc )方法,把即将要添加到容器中的组件c和GridBagConstraints对象关联起来;
4. 把组件添加到容器中;
代码示例
import java.awt.*;
public class GridBagLayoutDemo {
public static void main(String[] args) {
//1.创建Frame对象
Frame frame = new Frame("这里是GridBagLayout测试");
//2.创建GridBagLayout对象
GridBagLayout gbl = new GridBagLayout();
//3.把Frame对象的布局管理器设置为GridBagLayout
frame.setLayout(gbl);
//4.创建GridBagConstraints对象
GridBagConstraints gbc = new GridBagConstraints();
//5.创建容量为10的Button数组
Button[] bs = new Button[10];
//6.遍历数组,初始化每一个Button
for (int i = 0; i < bs.length; i++) {
bs[i] = new Button("按钮"+(i+1));
}
//7.设置所有的GridBagConstraints对象的fill属性为GridBagConstraints.BOTH,当有空白区域时,组件自动扩大占满空白区域
gbc.fill=GridBagConstraints.BOTH;
//8.设置GridBagConstraints对象的weightx设置为1,表示横向扩展比例为1
gbc.weightx=1;
//9.往frame中添加数组中的前3个Button
addComponent(frame,bs[0],gbl,gbc);
addComponent(frame,bs[1],gbl,gbc);
addComponent(frame,bs[2],gbl,gbc);
//10.把GridBagConstraints的gridwidth设置为GridBagConstraints.REMAINDER,则表明当前组件是横向最后一个组件
gbc.gridwidth=GridBagConstraints.REMAINDER;
//11.把button数组中第四个按钮添加到frame中
addComponent(frame,bs[3],gbl,gbc);
//12.把GridBagConstraints的weighty设置为1,表示纵向扩展比例为1
gbc.weighty=1;
//13.把button数组中第5个按钮添加到frame中
addComponent(frame,bs[4],gbl,gbc);
//14.把GridBagConstaints的gridheight和gridwidth设置为2,表示纵向和横向会占用两个网格
gbc.gridheight=2;
gbc.gridwidth=2;
//15.把button数组中第6个按钮添加到frame中
addComponent(frame,bs[5],gbl,gbc);
//16.把GridBagConstaints的gridheight和gridwidth设置为1,表示纵向会占用1个网格
gbc.gridwidth=1;
gbc.gridheight=1;
//17.把button数组中第7个按钮添加到frame中
addComponent(frame,bs[6],gbl,gbc);
//18.把GridBagConstraints的gridwidth设置为GridBagConstraints.REMAINDER,则表明当前组件是横向最后一个组件
gbc.gridwidth=GridBagConstraints.REMAINDER;
//19.把button数组中第8个按钮添加到frame中
addComponent(frame,bs[7],gbl,gbc);
//20.把GridBagConstaints的gridwidth设置为1,表示纵向会占用1个网格
gbc.gridwidth=1;
//21.把button数组中第9、10个按钮添加到frame中
addComponent(frame,bs[8],gbl,gbc);
addComponent(frame,bs[9],gbl,gbc);
//22.设置frame为最佳大小
frame.pack();
//23.设置frame可见
frame.setVisible(true);
}
public static void addComponent(Container container,Component c,GridBagLayout gridBagLayout,GridBagConstraints gridBagConstraints){
gridBagLayout.setConstraints(c,gridBagConstraints);
container.add(c);
}
}
CardLayout
概述、构造器
CardLayout 布局管理器以时间而非空间来管理它里面的组件,它将加入容器的所有组件看成一叠卡片(每个卡片其实就是一个组件),每次只有最上面的那个 Component 才可见。就好像一副扑克牌,它们叠在一起,每次只有最上面的一张扑克牌才可见。
方法名称 | 方法功能 |
---|---|
CardLayout() | 创建默认的 CardLayout 布局管理器。 |
CardLayout(int hgap,int vgap) | 通过指定卡片与容器左右边界的间距 C hgap) 、上下边界 Cvgap) 的间距来创建 CardLayout 布局管理器. |
first(Container target) | 显示target 容器中的第一张卡片. |
last(Container target) | 显示target 容器中的最后一张卡片. |
previous(Container target) | 显示target 容器中的前一张卡片. |
next(Container target) | 显示target 容器中的后一张卡片. |
show(Container taget,String name) | 显 示 target 容器中指定名字的卡片. |
代码示例
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class CardLayoutDemo {
public static void main(String[] args) {
//1.创建Frame对象
Frame frame = new Frame("这里测试CardLayout");
//2.创建一个String数组,存储不同卡片的名字
String[] names = {
"第一张","第二张","第三张","第四张","第五张"};
//3.创建一个Panel容器p1,并设置其布局管理器为CardLayout,用来存放多张卡片
CardLayout cardLayout = new CardLayout();
Panel p1 = new Panel();
p1.setLayout(cardLayout);
//4.往p1中存储5个Button按钮,名字从String数组中取
for (int i = 0; i < 5; i++) {
p1.add(names[i],new Button(names[i]));
}
//5.创建一个Panel容器p2,用来存储5个按钮,完成卡片的切换
Panel p2 = new Panel();
//6.创建5个按钮,并给按钮设置监听器
ActionListener listener = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
String command = e.getActionCommand();
switch (command){
case "上一张":
cardLayout.previous(p1);
break;
case "下一张":
cardLayout.next(p1);
break;
case "第一张":
cardLayout.first(p1);
break;
case "最后一张":
cardLayout.last(p1);
break;
case "第三张":
cardLayout.show(p1,"第三张");
break;
}
}
};
Button b1 = new Button("上一张");
Button b2 = new Button("下一张");
Button b3 = new Button("第一张");
Button b4 = new Button("最后一张");
Button b5 = new Button("第三张");
b1.addActionListener(listener);
b2.addActionListener(listener);
b3.addActionListener(listener);
b4.addActionListener(listener);
b5.addActionListener(listener);
//7.把5个按钮添加到p2中
p2.add(b1);
p2.add(b2);
p2.add(b3);
p2.add(b4);
p2.add(b5);
//8.把p1添加到frame的中间区域
frame.add(p1);
//9.把p2添加到frame的底部区域
frame.add(p2,BorderLayout.SOUTH);
//10设置frame最佳大小并可见
frame.pack();
frame.setVisible(true);
}
}
BoxLayout
概述、构造器
为了简化开发,Swing 引入了 一个新的布局管理器 : BoxLayout 。 BoxLayout 可以在垂直和 水平两个方向上摆放 GUI 组件, BoxLayout 提供了如下一个简单的构造器:
方法名称 | 方法功能 |
---|---|
BoxLayout(Container target, int axis) | 指定创建基于 target 容器的 BoxLayout 布局管理器,该布局管理器里的组件按 axis 方向排列。其中 axis 有 BoxLayout.X_AXIS( 横向)和 BoxLayout.Y _AXIS (纵向〉两个方向。 |
在java.swing包中,提供了一个新的容器Box,该容器的默认布局管理器就是BoxLayout,大多数情况下,使用Box容器去容纳多个GUI组件,然后再把Box容器作为一个组件,添加到其他的容器中,从而形成整体窗口布局。
方法名称 | 方法功能 |
---|---|
static Box createHorizontalBox() | 创建一个水平排列组件的 Box 容器 |
static Box createVerticalBox() | 创建一个垂直排列组件的 Box 容器 |
Box类中,提供了5个方便的静态方法来生成这些间隔组件:
方法名称 | 方法功能 |
---|---|
static Component createHorizontalGlue() | 创建一条水平 Glue (可在两个方向上同时拉伸的间距) |
static Component createVerticalGlue() | 创建一条垂直 Glue (可在两个方向上同时拉伸的间距) |
static Component createHorizontalStrut(int width) | 创建一条指定宽度(宽度固定了,不能拉伸)的水平Strut (可在垂直方向上拉伸的间距) |
static Component createVerticalStrut(int height) | 创建一条指定高度(高度固定了,不能拉伸)的垂直Strut (可在水平方向上拉伸的间距) |
代码示例1
使用Frame和BoxLayout完成下图效果:
import javax.swing.*;
import java.awt.*;
public class BoxLayoutDemo1 {
public static void main(String[] args) {
//1.创建Frame对象
Frame frame = new Frame("这里测试BoxLayout");
//2.创建BoxLayout布局管理器,并指定容器为上面的frame对象,指定组件排列方向为纵向
BoxLayout boxLayout = new BoxLayout(frame, BoxLayout.Y_AXIS);
frame.setLayout(boxLayout);
//3.往frame对象中添加两个按钮
frame.add(new Button("按钮1"));
frame.add(new Button("按钮2"));
//4.设置frame最佳大小,并可见
frame.pack();
frame.setVisible(true);
}
}
代码示例2
使用Frame和Box,完成下图效果:
import javax.swing.*;
import java.awt.*;
public class BoxLayoutDemo2 {
public static void main(String[] args) {
//1.创建Frame对象
Frame frame = new Frame("这里测试BoxLayout");
//2.创建一个横向的Box,并添加两个按钮
Box hBox = Box.createHorizontalBox();
hBox.add(new Button("水平按钮一"));
hBox.add(new Button("水平按钮二"));
//3.创建一个纵向的Box,并添加两个按钮
Box vBox = Box.createVerticalBox();
vBox.add(new Button("垂直按钮一"));
vBox.add(new Button("垂直按钮二"));
//4.把box容器添加到frame容器中
frame.add(hBox,BorderLayout.NORTH);
frame.add(vBox);
//5.设置frame最佳大小并可见
frame.pack();
frame.setVisible(true);
}
}
代码示例3
为组件添加间隔
import javax.swing.*;
import java.awt.*;
public class BoxLayoutDemo3 {
public static void main(String[] args) {
//1.创建Frame对象
Frame frame = new Frame("这里测试BoxLayout");
//2.创建一个横向的Box,并添加两个按钮
Box hBox = Box.createHorizontalBox();
hBox.add(new Button("水平按钮一"));
hBox.add(Box.createHorizontalGlue());//两个方向都可以拉伸的间隔
hBox.add(new Button("水平按钮二"));
hBox.add(Box.createHorizontalStrut(10));//水平间隔固定,垂直间方向可以拉伸
hBox.add(new Button("水平按钮3"));
//3.创建一个纵向的Box,并添加两个按钮
Box vBox = Box.createVerticalBox();
vBox.add(new Button("垂直按钮一"));
vBox.add(Box.createVerticalGlue());//两个方向都可以拉伸的间隔
vBox.add(new Button("垂直按钮二"));
vBox.add(Box.createVerticalStrut(10));//垂直间隔固定,水平方向可以拉伸
vBox.add(new Button("垂直按钮三"));
//4.把box容器添加到frame容器中
frame.add(hBox, BorderLayout.NORTH);
frame.add(vBox);
//5.设置frame最佳大小并可见
frame.pack();
frame.setVisible(true);
}
}
边栏推荐
- LC weekly 300
- BUU-Crypto-[GXYCTF2019]CheckIn
- Enterprise level log analysis system elk (if things backfire, there must be other arrangements)
- Unity2d -- character moves and turns
- Programmers don't talk about morality, and use multithreading for Heisi's girlfriend
- JS get the attribute values nested in the object
- Supplement the JS of a video website to decrypt the video
- 十二. golang其他
- [excel] PivotChart
- BeanFactoryPostProcessor 与 BeanPostProcessor 相关子类概述
猜你喜欢
Introduction to AMBA
JS扁平化数形结构的数组
BUU-Pwn-test_ your_ nc
Enterprise level log analysis system elk (if things backfire, there must be other arrangements)
How to expand all collapse panels
Google Chrome browser will support the function of selecting text translation
Penetration tool - sqlmap
谷歌 Chrome 浏览器将支持选取文字翻译功能
配置交叉编译工具链和环境变量
Arc135 C (the proof is not very clear)
随机推荐
我的NVIDIA开发者之旅——优化显卡性能
Easy change
总线的基本概念
Flask
Qt发布多语言国际化翻译
C语言简易学生管理系统(含源码)
如何判断数组中是否含有某个元素
VB. Net GIF (making and disassembling - optimizing code, class library - 5)
[excel] PivotChart
Zhanrui tankbang | jointly build, cooperate and win-win zhanrui core ecology
SQL performance optimization skills
Wechat applet +php realizes authorized login
2022 a special equipment related management (elevator) examination questions simulation examination platform operation
Take you to quickly learn how to use qsort and simulate qsort
How to get the parent node of all nodes in El tree
How to determine whether an array contains an element
Build an Internet of things infrared temperature measuring punch in machine with esp32 / rush to work after the Spring Festival? Baa, no matter how hard you work, you must take your temperature first
[MySQL practice of massive data with high concurrency, high performance and high availability -8] - transaction isolation mechanism of InnoDB
fastjson
(4) Canal multi instance use