Java的布局管理器
FlowLayout
在默认的情况下,AWT的布局管理器是FlowLayout,这个管理器将组件从左到右、从上到下顺序摆放,它将所有的组件摆放在居中位置。
构造函数
public static final int LEFT = 0; //左对齐
public static final int CENTER = 1; //居中对齐
public static final int RIGHT = 2; //右对齐
//默认居中对齐,垂直、水平5个单位
public FlowLayout() {
this(CENTER, 5, 5);
}
//指定对齐方式,垂直、水平5个单位
public FlowLayout(int align) {
this(align, 5, 5);
}
//指定对齐方式,指定垂直水平的间距
public FlowLayout(int align, int hgap, int vgap) {
this.hgap = hgap;
this.vgap = vgap;
setAlignment(align);
}
实例
import java.awt.*;
public class Demo extends Frame{
Button b1=new Button("提交");
Button b2=new Button("取消");
Button b3=new Button("重置");
public Demo(){
this.setTitle("FlowLayout布局");
this.setLayout(new FlowLayout(FlowLayout.LEFT,20,20));//左对齐,垂直、水平20的间距
this.add(b1);
this.add(b2);
this.add(b3);
this.setBounds(200,100,450,350);
this.setVisible(true);
}
public static void main(String[] args){
Demo d1=new Demo();
}
}
运行结果
BorderLayout
通过BorderLayout布局方式可以将窗口划成上、下、左、右、中5个区域,普通组件可以被放置在这5个区域中的任意一个。当改变使用BorderLayout的容器大小时,上、下和中区域可以水平调整,而左、右和中间区域可以垂直调整。在使用BorderLayout时需要注意如下两点。
- 当向使用BorderLayout布局管理器的容器中添加组件时,需要指定要添加到哪个区域里。如果没有指定添加到哪个区域里,则默认添加到中间区域里
- 如果向同一个区域中添加多个组件,后放入的组件会覆盖前面的组件
构造函数
//添加组件的时候需要指定的区域的静态常量
public static final String NORTH = "North";
public static final String SOUTH = "South";
public static final String EAST = "East";
public static final String WEST = "West";
public static final String CENTER = "Center";
//默认组件之间0间距
public BorderLayout() {
this(0, 0);
}
//指定组件之间的间距
public BorderLayout(int hgap, int vgap) {
this.hgap = hgap;
this.vgap = vgap;
}
当向使用BorderLayout布局管理器的容器中添加组件时,应该使用类BorderLayout中的几个静态属性来指定添加到哪个区域。在BorderLayout中的静态常量有:EAST(东)、NORTH(北)、WEST(西)、SOUTH(南)和CENTER(中)。
实例
import java.awt.*;
public class Demo extends Frame{
Button b1=new Button("中间");
Button b2=new Button("上面");
Button b3=new Button("下面");
Button b4=new Button("左面");
Button b5=new Button("右面");
public Demo(){
this.setTitle("BorderLayout布局");
this.setLayout(new BorderLayout(5,5));
this.add(b1,BorderLayout.CENTER);
this.add(b2,BorderLayout.NORTH);
this.add(b3,BorderLayout.SOUTH);
this.add(b4,BorderLayout.WEST);
this.add(b5,BorderLayout.EAST);
this.setBounds(200,100,450,350);
this.setVisible(true);
}
public static void main(String[] args){
Demo d1=new Demo();
}
}
运行结果
注意:BorderLayout最多只能放5个组件,要想放多个组件,需要先将部分组件放在Panel中,然后再把Panel添加到BorderLayout中。如果组件小于5个,没有放置组件的地方,将被相邻的组件占用
GridLayout
GridLayout布局也是AWT中常用的一种布局方式,它实际上就是矩形网格,在网格中放置各个组件,每个网格的高度相等,组件随着网格的大小而在水平方向和垂直方向拉伸,网格的大小是由容器和创建网格的多少来确定的。当向GridLayout的容器中添加组件时,默认从左向右、从上向下依次添加到每个网格中。与FlowLayout不同的是,放在GridLayout布局管理器中的各组件的大小由组件所处的区域来决定(每个组件将自动涨大到占满整个区域)。
构造函数
//默认的行数列数,以及组件之间的间距
public GridLayout() {
this(1, 0, 0, 0);
}
//采用指定的行数和列数,默认的组件之间的间距
public GridLayout(int rows, int cols) {
this(rows, cols, 0, 0);
}
//采用指定的行数和列数,以及指定的组件之间的间距
public GridLayout(int rows, int cols, int hgap, int vgap) {
if ((rows == 0) && (cols == 0)) {
throw new IllegalArgumentException("rows and cols cannot both be zero");
}
this.rows = rows;
this.cols = cols;
this.hgap = hgap;
this.vgap = vgap;
}
实例
import java.awt.*;
public class Demo extends Frame{
Button b1=new Button("A");
Button b2=new Button("B");
Button b3=new Button("C");
Button b4=new Button("D");
Button b5=new Button("E");
Button b6=new Button("F");
public Demo(){
this.setTitle("GridLayout布局");
this.setLayout(new GridLayout(2,3));//2行3列
this.add(b1);
this.add(b2);
this.add(b3);
this.add(b4);
this.add(b5);
this.add(b6);
this.setBounds(200,100,450,350);
this.setVisible(true);
}
public static void main(String[] args){
Demo d1=new Demo();
}
}
运行结果
GridBagLayout
GridBagLayout是Java中最有弹性但也是最复杂的一种版面管理器,它只有一种构造函数,但必须配合GridBagConstraints才能达到设置的效果。
构造函数
//GridBagLayout的构造函数,只有一个
public GridBagLayout () {
comptable = new Hashtable<Component,GridBagConstraints>();
defaultConstraints = new GridBagConstraints();
}
//GridBagConstraints的默认构造函数
public GridBagConstraints () {
gridx = RELATIVE;
gridy = RELATIVE;
gridwidth = 1;
gridheight = 1;
weightx = 0;
weighty = 0;
anchor = CENTER;
fill = NONE;
insets = new Insets(0, 0, 0, 0);
ipadx = 0;
ipady = 0;
}
//GridBagConstraints指定参数的构造函数
public GridBagConstraints(int gridx, int gridy,
int gridwidth, int gridheight,
double weightx, double weighty,
int anchor, int fill,
Insets insets, int ipadx, int ipady) {
this.gridx = gridx;
this.gridy = gridy;
this.gridwidth = gridwidth;
this.gridheight = gridheight;
this.fill = fill;
this.ipadx = ipadx;
this.ipady = ipady;
this.insets = insets;
this.anchor = anchor;
this.weightx = weightx;
this.weighty = weighty;
}
参数说明:
gridx/gridy:设置组件的位置,当gridx=0,gridy=0时表示放在0行0列
gridwidth/gridheight:设置组件的长度和高度,默认值为1
ipadx/ipady:设置组件内的间距,默认为0
insets:设置组件彼此之间的间距,有4个参数上下左右,默认(0,0,0,0)
anchor:当组件空间大于组件本身时,要将组件置于何处,有CENTER(默认值)、NORTH、NORTHEAST、EAST、SOUTHEAST、WEST、NORTHWEST可供选择
weightx/weighty:用来设置窗口变大时,各组件跟着变大的比例,当数字越大,表示组件能得到更多的空间,默认值皆为0
实例
import java.awt.*;
public class Demo{
private Frame f=new Frame();
private Button[] bs=new Button[10];
private GridBagLayout gb=new GridBagLayout();
private GridBagConstraints gbc=new GridBagConstraints();
public Demo(){
f.setTitle("GridBagLayout布局");
f.setLayout(gb);
for(int i=0;i<bs.length;i++){
bs[i]=new Button("按钮"+i);
}
//所有组件都可以横向、纵向扩大
gbc.fill=GridBagConstraints.BOTH;
gbc.gridheight=1;
gbc.gridwidth=1;
addButton(bs[0]);
addButton(bs[1]);
addButton(bs[2]);
gbc.gridwidth=GridBagConstraints.REMAINDER;
addButton(bs[3]);//设置为横向的最后一个元素
gbc.gridheight=2;
gbc.gridwidth=3;
addButton(bs[4]);//该组件横跨3个,纵跨2个
gbc.gridheight=1;
addButton(bs[5]);
gbc.gridwidth=GridBagConstraints.REMAINDER;
addButton(bs[6]);//设置为横向的最后一个元素
gbc.gridwidth=3;
addButton(bs[7]);
addButton(bs[8]);
gbc.gridwidth=GridBagConstraints.REMAINDER;
addButton(bs[9]);//设置为横向的最后一个元素
f.pack();
f.setVisible(true);
}
private void addButton(Button button){
gb.setConstraints(button,gbc);
f.add(button);
}
public static void main(String[] args){
Demo d1=new Demo();
}
}
运行结果
这样的布局方式会受周围组件影响。
CardLayout
Cardlayout布局管理器可以设置在一组组件中只显示某一个组件,用户可以根据需要选择需要显示的某一个组件。就像一副扑克牌一样,扑克叠在一起,每次只有最上面的一张扑克牌才可见。
构造函数
//默认0间距的构造函数
public CardLayout() {
this(0, 0);
}
//指定间距的构造函数
public CardLayout(int hgap, int vgap) {
this.hgap = hgap;
this.vgap = vgap;
}
CardLayout布局中有5个方法来显示组件
- first(Container parent)显示目标容器的第一个卡片
- last(Container parent)显示目标容器最后一个卡片
- previous(Container parent)显示目标容器前一个卡片
- next(Container parent)显示目标容器下一个卡片
- show(Container parent, String name)显示目标容器指定名字的卡片
实例
import java.awt.*;
import java.awt.event.*;
public class Demo extends Frame implements ActionListener{
public Panel p=new Panel();
public Button bf=new Button("第一个");
public Button bl=new Button("最后一个");
public Button bn=new Button("下一个");
public Button bp=new Button("上一个");
public Button bg=new Button("搜索");
public TextField tf=new TextField();
public CardLayout cl=new CardLayout();
public Button[] btt=new Button[5];
public Demo(){
this.setTitle("CardLayout布局的组件进行测试");
this.setLayout(null);
this.add(p);
p.setLayout(cl);
for(int i=0;i<btt.length;i++){
btt[i]=new Button("面板按钮"+i);
p.add(btt[i],""+i);
}
p.setBounds(10,40,100,100);
this.add(bf);
bf.addActionListener(this);
bf.setBounds(120,40,60,20);
this.add(bl);
bl.addActionListener(this);
bl.setBounds(120,70,60,20);
this.add(bn);
bn.addActionListener(this);
bn.setBounds(120,100,60,20);
this.add(bp);
bp.addActionListener(this);
bp.setBounds(120,130,60,20);
this.add(bg);
bg.addActionListener(this);
bg.setBounds(60,160,40,20);
this.add(tf);
tf.addActionListener(this);
tf.setBounds(20,160,40,20);
this.setBounds(200,200,400,400);
this.setVisible(true);
}
public void actionPerformed(ActionEvent e){
if(e.getSource()==bf){
cl.first(p);
}
if(e.getSource()==bl){
cl.last(p);
}
if(e.getSource()==bn){
cl.next(p);
}
if(e.getSource()==bp){
cl.previous(p);
}
if(e.getSource()==bg){
cl.show(p,tf.getText().trim());
tf.setText("");
}
}
public static void main(String[] args){
Demo d1=new Demo();
}
}
运行结果
BoxLayout
虽然GridBagLayout布局管理器的功能很强大,但是使用方法比较复杂,为此Swing引入了一个新的布局管理器——BoxLayout。BoxLayout保留了GridBagLayout的很多优点,并且使用简单。BoxLayout可以在垂直和水平两个方向上摆放GUI组件,BoxLayout为我们提供了一个如下简单的构造器。
构造函数
public static final int X_AXIS = 0;//横向
public static final int Y_AXIS = 1;//纵向
//指定容器按照指定的方向排列
public BoxLayout(Container target, int axis) {
if (axis != X_AXIS && axis != Y_AXIS &&
axis != LINE_AXIS && axis != PAGE_AXIS) {
throw new AWTError("Invalid axis");
}
this.axis = axis;
this.target = target;
}
实例
import java.awt.*;
import javax.swing.*;
public class Demo extends Frame{
public Demo(){
this.setTitle("BoxLayout布局测试");
this.setLayout(new BoxLayout(this,BoxLayout.Y_AXIS));
this.add(new Button("A"));
this.add(new Button("B"));
this.setBounds(200,200,400,400);
this.setVisible(true);
}
public static void main(String[] args){
Demo d1=new Demo();
}
}
运行结果
null布局,自由随意
前面讲了很多的布局管理器,但是如果想自由的布局,那就选null布局
实例
import java.awt.*;
public class Demo extends Frame{
public Button b1=new Button("A");
public Button b2=new Button("B");
public Button b3=new Button("C");
public Demo(){
this.setTitle("bull布局测试");
this.setLayout(null);
this.add(b1);
this.add(b2);
this.add(b3);
b1.setBounds(100,100,50,60);
b2.setBounds(100,170,50,60);
b3.setBounds(100,240,50,60);
this.setBounds(200,200,400,400);
this.setVisible(true);
}
public static void main(String[] args){
Demo d1=new Demo();
}
}
运行结果