GUI(图形用户界面)——AWT概述、布局管理器

文章目录

    • 1. GUI简介
    • 2. AWT概述
      • 2.1 Component(组件)
      • 2.2 Container(容器)
        • 2.2.1 Window
        • 2.2.2 Panel(面板)
    • 3.布局管理器
      • 3.1 FlowLayout(流式布局管理器)
        • 3.1.1 举例:实现一个流式布局管理器对按钮进行管理。
      • 3.2 BorderLayout(边界布局管理器)
        • 3.2.1 举例:设置一个BorderLayout布局管理器,在容器的东、南、西、北、中5个区域放置5个按钮。
      • 3.3 GridLayout(网格布局管理器)
        • 3.3.1 举例:用GridLayoutt布局管理器,设置9个按钮组件,按钮组件按照编号从左到右、从上到下填充满整个容器。
      • 3.4 GridLayout(网格包布局管理器)
        • 3.4.1 举例:向GridBagLayout布局管理器中添加10个按钮
      • 3.5 CardLayout(卡片布局管理器)
        • 3.5.1 举例
      • 3.6 不使用布局管理器
        • 3.6.1 举例:演示不使用布局管理器对组件进行布局

1. GUI简介

GUI全称是Graphical User Interface,即图形用户界面或图型用户接口,就是应用程序提供给用户操作的图形界面,包括窗口、菜单、按钮、工具栏和其他各种图形界面元素。
Java中针对GUI设计提供了丰富的类库,这些类分别位于java.awt 和 javax.swing包中,简称为AWT和Swing。其中,AWT是SUN公司最早推出的一套API,他需要利用本地操作系统所提供的图形库,属于重量级组件,不跨平台,它的组件种类有限,可以提供基本的GUI设计工具,却无法实现目前GUI设计所需的所有功能。随后,SUN公司对AWT进行改进,提供了Swing组件,Swing组件有纯Java语言编写,属于轻量级组件,可跨平台,Swing不仅实现了AWT中的所有功能,而且提供了更加丰富的组件和功能,足以满足GUI设计的一切需求。

2. AWT概述

AWT适用于创建图形用户界面的一个工具包,它提供了一系类用于实现图形界面的组件,如窗口、按钮、文本框、对话框等。在JDK中针对每个组件都提供了对应的Java类,这些类都是位于java.awt包中,接下来通过一个图例来描述这些类的继承关系。
GUI(图形用户界面)——AWT概述、布局管理器_第1张图片
从上图继承关系可以看出,在AWT中组建分为两大类,这两类的基类分别是Component 和 MenuComponent。其中,MenuComponent是与菜单相关组件的父类,Component则是除菜单外其他AWT组件的父类,它表示一个能图形化方式显示出来并可与用户交互的对象。
Component类通常被成为组件,根据Component的不同作用,可将其分为基本组件类和容器类。基本组件类是诸如按钮(Button)、文本框(TextField)之类的图形界面元素,而容器类则是通过Component的子类Container实例化的对象。

2.1 Component(组件)

组件是图形用户界面最基本的部分,也称为构件,是可以以图形化的方式显示在屏幕上,并能与用户进行交互的对象。组件不能独立的显示出来,必须将其放在一定的容器中才可以显示。

组件名称 构造方法
按钮(Button) Button b = new Button(“退出”);
文本框(TextField) TextField text = new TextField();
颜色(Color) 非构造方法①setBackground(Color.BULE); ②setBackground(new Color(100, 100, 100));
字体(Font) Font font = new Font(“宋体”, Font.BOLD, 10);

2.2 Container(容器)

Container类表示容器,它是一种特殊的组件,可以用来容纳其他组件。Container容器又分为两种类型,分别是Window(Frame)和Panel。

2.2.1 Window

Window类是不依赖其他容器而独立存在的容器,它有两个子类,分别是Frame类和Dialog类。Frame类用于创建一个具有标题栏的框架窗口,作为程序的主页面。Dialog类用于创建一个对话框,实现用户信息交互。
要生成一个窗口,通常使用Window的子类进行实例化,而不是直接使用Window类,框架的外观就像平常Windows系统下的窗口,有标题、边框、菜单和大小等。
框架的构造方法:

Frame frm = new Frame("New Window");

2.2.2 Panel(面板)

Panel是一种透明的容器,没有标题和边框。与Frame不同,它不能作为最外层的容器单独存在,它首先必须作为一个组件放置在其他容器(Window或其子类)中,一个Panel对象代表一个长方形的区域,在这个区域中可以容纳其它组件。在java.swing中式JPanel。
面板的构造方法:

Panel panel = new Panel();

举例:创建一个简单的图形界面

import java.awt.*;

public class Test{
    public static void main(String[] args){
        // 建立一个新的窗体
        Frame f = new Frame("新窗体");
        // 设置窗体的宽和高
        f.setSize(500, 300);
        // 设置窗体在屏幕中所处的位置(参数是左上角坐标)
        f.setLocation(300, 200);
        // 设置窗体可见
        f.setVisible(true);
    }
}

运行后,结果如下,会出现一个“新窗体”的图形化界面。
GUI(图形用户界面)——AWT概述、布局管理器_第2张图片
下面分析一下上面代码所带的含义:
① 创建一个带有标题Frame窗体对象

Frame f = new Frame("新窗体");

② setSize()方法用于设置窗体对象的宽度和高度

f.setSize(500, 300);

③ setLocation()方法用于设置窗体对象在屏幕所处的坐标位置

f.setLocation(300, 200);

②③中的坐标全部为所处的左上角为(0,0)
④ setVisible(true)是用来设置创建的窗体是否隐藏状态

f.setVisible(true);

true为可见,false为不可见。

3.布局管理器

组件不能单独存在,必须放置与容器中,而组建在容器中的位置和尺寸是由布局管理器来决定的。在java.awt包中提供了5种布局管理器,分别是FlowLayout(流式布局管理器)、BorderLayout(边界布局管理器)、GridLayout(网格布局管理器)、GirdBagLayout(网格包布局管理器)和CardLayout(卡片布局管理器)。每个容器在创建是都会使用一种默认的布局管理器,在程序中可以通过调用容器对象的setLayout()方法设置布局管理器,通过布局管理器来自动进行组建的布局管理器。
GUI(图形用户界面)——AWT概述、布局管理器_第3张图片

3.1 FlowLayout(流式布局管理器)

最简单的布局,Panel的默认布局管理器。容器会将组件按照添加顺序从上到下、从左向右放置。当到达容器的边界是,会自动将组建放到下一行的开始位置。这些组件可以左对齐、居中对齐(默认方式)或右对齐的方式排列。
FlowLayout构造方法:
FlowLayout有3个构造方法。

方法声明 功能描述
FlowLayout() 组件默认居中对齐,水平、垂直间距默认为5个单位
FlowLayout(int align) 制定组建相对于容器的对其方法,水平、垂直间距默认为5个单位
FlowLayout(int align, int hgap, int vgap) 指定组件的对齐方式和水平、垂直间距

注意:
① 参数align决定组件在每行中相对于容器边界的对齐方式,可以使用该类中提供的常量作为参数传递给构造方法。

  • FlowLayout.LEFT用于表示左对齐
  • FlowLayout.RIGHT用于表示右对齐
  • FlowLayout.CENTER用于表示居中对齐
    ② 参数hgap和参数vgap分别设定组件之间的水平和垂直间隙,可以填入一个任意数值。

3.1.1 举例:实现一个流式布局管理器对按钮进行管理。

import java.awt.*;

public class Test{
    public static void main(String[] args){
    	final Frame f = new Frame("Flowlayout");	//创建名为Flowlayout的窗体
    	//设置布局管理器为FlowLayout,所有组件左对齐,水平间距为20,垂直间距为30
    	f.setLayout(new FlowLayout(FlowLayout.LEFT, 20, 30));
    	f.setSize(220, 300);	//设置窗体大小
    	f.setLocation(300, 200);	//设置窗体显示的位置
    	f.add(new Button("第一个按钮"));	//把"第一个按钮"添加到f窗口
    	f.add(new Button("第二个按钮"));
    	f.add(new Button("第三个按钮"));
    	f.add(new Button("第四个按钮"));
    	f.add(new Button("第五个按钮"));
    	f.add(new Button("第六个按钮"));
    	
    	f.setVisible(true);	//设置窗体可见
    }
}

运行结果如下所示:
GUI(图形用户界面)——AWT概述、布局管理器_第4张图片
特点:
① 所有组件像流水一样依次排列,不需要用户明确地设定,但灵活性上相对差。
② 窗体拉伸变宽,按钮的大小和按钮之间的间距保持不变,但按钮相对于容器边界的距离会发生变化。

3.2 BorderLayout(边界布局管理器)

复杂的布局,Frame的默认布局管理器。将容器划为5个区域,分别是东(EAST)、南(SOUTH)、西(WEST)、北(NORTH)、中(CENTER)。组件可以被放置在这5个区域中的任意一个。
GUI(图形用户界面)——AWT概述、布局管理器_第5张图片
注意:
① 箭头是指改变容器大小时各个区域需要改变的方向。
 就是说,在改变容器时,NORTH和SOUTH区域高度不变,长度调整;WEST和EAST区域宽度不变,高度调整;CENTER会进行相应调整。
② 向BorderLayout布局管理器中添加组件是,需要使用add(Component comp, Object constraints)方法。

  • 参数comp表示要添加的组件
  • 参数comstraints表示将指定组件添加到布局中的方式和位置对象。它是一个Object类型,在传参时可以使用BorderLayout类型提供5个常量,分别是EAST、SOUTH、WEST、NORTH、CENTER。

3.2.1 举例:设置一个BorderLayout布局管理器,在容器的东、南、西、北、中5个区域放置5个按钮。

import java.awt.*;

public class Test{
    public static void main(String[] args){
    	final Frame f = new Frame("BorderLayout");
    	f.setLayout(new BorderLayout());
    	f.setSize(300, 300);
    	f.setLocation(300, 200);	//设置窗体大小
    	// 创建5个按钮
    	Button bt1 = new Button("东");
    	Button bt2 = new Button("西");
    	Button bt3 = new Button("南");
    	Button bt4 = new Button("北");
    	Button bt5 = new Button("中");
    	// 将创建好的代码添加到窗体中,并设置按钮所在的区域
    	f.add(bt1, BorderLayout.EAST);
    	f.add(bt2, BorderLayout.WEST);
    	f.add(bt3, BorderLayout.SOUTH);
    	f.add(bt4, BorderLayout.NORTH);
    	f.add(bt5, BorderLayout.CENTER);
    	
    	f.setVisible(true);
    }
}

运行结果如下所示:
GUI(图形用户界面)——AWT概述、布局管理器_第6张图片
特点:
① 可以限定各区域的边界,当用户改变容器窗口大小时,各个组件的相对位置不变。
② 向BorderLayout的布局管理器中添加组件是,如果不能指定添加到哪个区域,则默认添加到CENTER区域,并且每个区域只能放置一个组件,如果向一个区域中添加多个组件,后放入的组件会覆盖先放入的组件。

3.3 GridLayout(网格布局管理器)

使用纵横线将容器分为n行m列大小相等的网络,每个网络中放置一个组件。添加到容器中的组件首先防止在第一个行第一列(左上角)的网络中,然后再第1行的网格中从左向右一次放置其它组件。行满后,继续在下一行中从左至右防止组件。与FlowLayout不同的是,放置在GridLayout布局管理器中的组件将会自动占据网格的整个区域。
GridLayout构造方法:

方法声明 功能描述
GridLayout() 默认只有一行,每个组件占一列
GridLayout(int rows, int cols) 指定容器的行数和列数
GridLayout(int rows, int cols, int hgap, int vgap) 指定容器的行数和列数以及组件之间水平、垂直间距

注意:
① 参数代表意义:

  • 参数rows和cols分别代表行数和列数
  • 参数hgap和vgap规定水平 和垂直方向的间隙

3.3.1 举例:用GridLayoutt布局管理器,设置9个按钮组件,按钮组件按照编号从左到右、从上到下填充满整个容器。

import java.awt.*;

public class Test{
    public static void main(String[] args){
    	Frame f = new Frame("GridLayout");	//创建一个名为GridLayout的窗体
    	f.setLayout(new GridLayout(3, 3));	//设置该窗体为3*3的网络
    	f.setSize(300, 300);	//设置窗体大小
    	f.setLocation(400, 300);
    	// 下面的代码是循环添加9个按钮到GridLayout中
    	for(int i = 0; i <= 9; i++)
    	{
    		Button bti = new Button("bt" + i);
    		f.add(bti);	//向窗体中添加按钮
    	}
    	f.setVisible(true);	//设置窗体可见
    }
}

运行结果如下所示:
GUI(图形用户界面)——AWT概述、布局管理器_第7张图片
特点:
① 组件的相对位置不随区域的缩放而改变,但组件的大小会随之改变,组件始终占据网格的整个区域。
② 缺点是总忽略组件的最佳大小,所有组件的宽高都相同。

3.4 GridLayout(网格包布局管理器)

最灵活、最复杂的布局管理器。与GraiLayout布局管理器类似,不同的是,它允许网格中的组件大小各不相同,而且允许一个组件跨越一个或者多个网格。

使用GridLayout布局管理器的步骤如下:
① 创建GridLayout布局管理器,并使容器采用该布局管理器。

    	GridLayout layout = new GridLayout();
    	container.setLayout(gl);

② 创建GridBagContraints对象(布局约束条件),并设置该对象的相关属性。

    	GridBagConstraints constraints = new GridBagConstraints();
    	constraints.gridx = 1;	//设置网格的左上角横向索引
    	constraints.gridy = 1;	//设置网络的左上角纵向索引
    	constraints.gridwidth = 1;	//设置组件横向跨越的网格
    	constraints.gridheight = 1;	//设置组件纵向跨越的网格

③ 调用GridBagLayout对象的setConstraints()方法建立GridBagConstraints对象和受控组件之间的关联。

    	layout.setConstraints(component, constraints);

④ 向容器中添加组件

    	container.add(conponent);

GridBagConstraints对象可以重复使用,只需要改变它的属性即可。如果要向容器中添加多个组件,则重复步骤(2)、步骤(3)、步骤(4)。
 从上述步骤可以看出,使用GridBagLayout布局管理器的关键在于GridBagConstraints对象,它才是控制组件容器中每个组件布局的核心类,在GridBagConstraints类中有许多表示约束的属性,下面对GridBagConstraints类中的一些常用属性进行介绍,

属性 作用
gridx和gridy 设置组件的左上角所在网格的横向和纵向索引(即所在的行和列)。如果将gridx和gridy的值设为GridBagConstraints.RELATIVE(默认值),表示当前组件紧跟在上一个组件后面
gridwidth和gridheight 设置组件横向、纵向跨越几个网格,两个属性都是1.如果如果把这两个属性的值设为GridBagConstraints.REMAINER,表示当前组件其行或其列上为最后一个组件。如果把这两个属性的值设为GridBagConstraints.RELATIVE表示当前组件在其行或列上为倒数第2个组件
fill 如果当组件的显示区域大于组件需要的大小,设置是否以及如何改变组件大小,该属性接受以下几个属性值。① NONE:默认,不改变组件大小 ② HORIZONTAL:使组件水平方向足够长以填充显示区域,但是高度不变 ③ VERTICAL:使组件垂直方向足够高以填充显示区域,但长度不变 ④ BOTH:使组件足够大,以填充整个显示区域
weightx和weighty 设置组件占领容器中多于的水平方向和垂直方向空白的比例(也称为权重)。假设容器的水平方向放置3个组件,其weightx分别为1、2、3,当容器宽度为增加60个像素时,这3个容器分别增加10、20和30的像素。这两个属性的默认值是0,即不占领多余的空间

总结:

  • gridx和gridy用于设置组件左上角所在网络的横向和纵向索引
  • gridwidth和gridheigh用于设置组件横向、纵向跨越几个网络
  • fill用于设置是否及如何改变组件大小
  • weightx和weighty用于设置组件在容器中的水平方向和垂直方向的权重
    注意:
    如果希望组件的大小随着容器的增大而增大,必须同时设置GridBagConstraints对象的fill属性和weightx、weighty属性。

3.4.1 举例:向GridBagLayout布局管理器中添加10个按钮

import java.awt.*;

class Layout extends Frame {
	public Layout(String title)
	{
		GridBagLayout layout = new GridBagLayout();
		GridBagConstraints c = new GridBagConstraints();
		this.setLayout(layout);
		c.fill = GridBagConstraints.BOTH;	//设置组件横向纵向可以拉伸
		c.weightx = 1;	//设置横向权重为1
		c.weighty = 1;	//设置纵向权重为1
		this.addComponent("btn1", layout, c);
		this.addComponent("btn2", layout, c);
		this.addComponent("btn3", layout, c);
		
		//添加的组件是否是本行最后一个组件
		c.gridwidth = GridBagConstraints.REMAINDER;
		this.addComponent("btn4", layout, c);
		
		c.weightx = 0;	//设置横向权重
		c.weighty = 0;	//设置纵向权重
		addComponent("btn5", layout, c);
		
		c.gridwidth = 1;	//设置组件跨一个网络(默认值)
		this.addComponent("btn6", layout, c);
		
		//添加的组件是本行最后一个组件
		c.gridwidth = GridBagConstraints.REMAINDER;
		this.addComponent("btn7", layout, c);
		
		c.gridheight = 2;	//设置组件纵向跨两个网络
		c.gridwidth = 1;	//设置组件横向跨一个网络
		c.weightx = 2;		//设置横向权重为2
		c.weighty = 2;		//设置纵向权重为2
		this.addComponent("btn8", layout, c);
		
		c.gridwidth = GridBagConstraints.REMAINDER;
		c.gridheight = 1;
		this.addComponent("btn9", layout, c);
		this.addComponent("btn10", layout, c);
		this.setTitle(title);
		this.pack();
		this.setVisible(true);	//设置窗体可见
	}
	//每次添加组件的时候都要调用setConstraints的方法,将GridBagConstraints对象与按钮组件相关联
	private void addComponent(String name, GridBagLayout layout, GridBagConstraints c) {
		Button bt = new Button(name);	//创建一个名为name的按钮
		layout.setConstraints(bt, c);	//设置gridBagConstraints和按钮的关系
		this.add(bt);	//增加按钮	
	}
}

public class Test{
    public static void main(String[] args){
    	new Layout("GridBagLayout");
    }
}

运行结果如下:
GUI(图形用户界面)——AWT概述、布局管理器_第8张图片
由上图我们可以看到,由于在添加btn5~btn7时,将权重weightx和weighty的值设为0,因此在高度拉伸时没有变化,但长度受上下组件的影响,还是会随着窗口变大。

3.5 CardLayout(卡片布局管理器)

  在操作系统中经常会遇到通过选项卡按钮来切换程序的界面,这些界面就相当于一张张卡片,而管理这些卡片的布局管理器就是卡片布局管理器(CardLayout)。卡片布局管理器将界面看做是一系列卡片,在任何时候只要其中一张卡片是可见的,这张卡片占据容器的整个区域。
  卡片布局管理中经常会用到的方法:

方法声明 功能描述
void first(Containers parent) 显示parent容器的第一张卡片
void last(Containers parent) 显示parent容器的最后一张卡片
void previous(Containers parent) 显示parent容器的前一张卡片
void next(Containers parent) 显示parent容器的下一张卡片
void show(Containers parent,String name) 显示parent容器中名为name的组件,如果不存在则不会发生任何操作

3.5.1 举例

import java.awt.*;
import java.awt.event.*;
class  Cardlayout extends Frame implements ActionListener{
	//定义面板放置卡片
	Panel cardPanel=new Panel();
	//定义面板放置按钮
	Panel controlpaPanel = new Panel();
	
	Button nextButton,preButton;
	CardLayout cardLayout =new CardLayout();
	//设置卡片布局管理器的属性
	public Cardlayout()
	{
		setSize(300,200);
		setVisible(true);
		//为窗口添加关闭事件监听器
		this.addWindowListener(new WindowAdapter()
		{
			public void windowClosing(WindowEvent e)
			{
				Cardlayout.this.dispose();
			}
	});
	cardPanel.setLayout(cardLayout);
	//在cardPanel面板对象中添加3个文本文件
	cardPanel.add(new Label("第一个界面",Label.CENTER));
	cardPanel.add(new Label("第二个界面",Label.CENTER));
	cardPanel.add(new Label("第三个界面",Label.CENTER));
	//创建两个按钮对象
	nextButton = new Button("下一张卡片");
	preButton = new Button("上一张卡片");
	//为按钮对象注册监听器
	nextButton.addActionListener(this);
	preButton.addActionListener(this);
	//将按钮添加到controlpaPanel面板中
	controlpaPanel.add(preButton);
	controlpaPanel.add(nextButton);
	//将cardPanel面板放置在窗口边界布局的中间,窗口默认为边界布局
	this.add(cardPanel,BorderLayout.CENTER);
	//将controlpaPanel面板放置在窗口边界布局的南区
	this.add(controlpaPanel,BorderLayout.SOUTH);
}
	public void actionPerformed(ActionEvent e)
	{
		if(e.getSource()==nextButton)
		{
			//切换到面板中的组件,若当前组价为最后一个组件,则显示第一个组件
			cardLayout.next(cardPanel);
		}
		if(e.getSource()==preButton)
		{
			//切换到面板中的组件,若当前组件为第一个组件,则显示最后一个组件
			cardLayout.previous(cardPanel);
		}
	}
}
	
public class Test {
	public static void main(String[] args) {
		Cardlayout cardlayout=new Cardlayout();
	}
}

GUI(图形用户界面)——AWT概述、布局管理器_第9张图片
 文件中,在顶层Frame容器采用BordLayout布局,CENTER和SOUTH区域分别放置cardPanel和controlpaPanel面板,其中cardPanel采用CardLayout布局管理器,其中放置了三个Label标签代表三个卡片。controlpaPanel中放置了两个名为“上一张卡片”和“下一张卡片”按钮,通过单击这两个按钮,会触发按钮的时间监听器,条用cardLayout的previous()和next()方法对cardPanel面板中的卡片进行切换。
特点: 是可以使两个或者更多的界面共享一个显示空间,某一时刻只有一个界面可见。

3.6 不使用布局管理器

当一个容器被创建后,他们都会有一个默认的布局管理器。Window、Frame和Dialog的默认布局管理器是BorderLayou,Panel的默认布局管理器是FlowLayout。如果不希望通过布局管理器来对容器进行布局,也可以调用容器的setLayout(null)方法,将布局管理器都取消。在这种情况下,程序必须调用容器中每个组件的setSize()和setLocation()方法或者是setBounds()方法(这个方法接收4个参数,分别是左上角的x、y坐标和组件

3.6.1 举例:演示不使用布局管理器对组件进行布局

import java.awt.*;

public class Test{
    public static void main(String[] args){
		Frame f = new Frame("hello");
		f.setLayout(null);	//取消frame的布局管理器
		f.setSize(300, 150);
		Button btn1 = new Button("press");
		Button btn2 = new Button("pop");
		btn1.setBounds(40, 60, 100, 30);
		btn2.setBounds(140, 90, 100, 30);
		//向窗口中添加按钮
		f.add(btn1);
		f.add(btn2);
		f.setVisible(true);
    }
}

运行结果如下所示:
GUI(图形用户界面)——AWT概述、布局管理器_第10张图片

你可能感兴趣的:(Java,AWT概述,布局管理器)