一、GUI概述
GUI全称是Graphiacl User Interface,即图形用户界面。户名思议,就是应用程序提供给用户操作的图形界面,包括窗口、菜单、按钮、工具栏和其他各种图形界面元素。目前,图形用户界面已经成为一种趋势,几乎所有的程序设计语言都提供了GUI设计功能。Java中针对GUI设计提供了丰富的类库,这些类分别位于java.awt和javax.swing包中,简称AWT和Swing。其中,AWT是SUN公司最早推出的一套API,它需要利用本地操作系统所提供的图形库,属于重量级组件,不跨平台,它的组件种类有限,可以提供基本的GUI设计工具,却无法实现目前GUI设计所需的功能。随后,SUN公司对AWT进行改进,提供了Swing组件,Swing组件有纯java语言编写,属于轻量级组件,可跨平台,Swing不仅实现了AWT中的所有功能,而且还提供了更加丰富的组件和功能,足以满足GUI设计的一切需求。
二、AWT概述
AWT是用于创建图形用户界面的一个工具包,它提供了一系列用于实现图形界面的组件,如窗口、按钮、文本框、对话框等。在JDK中针对每个组件都提供了对应的Java类,这些类都位于java.awt包中。
AWT中组件分为两大类,这两大类基类分贝时Component和Menu Component。其中,Menu Component是所有与菜单相关组件的父类。Component则是除菜单外其他AWT组件的父类,它表示一个能以图形化方式显示出来,并可与用户交互的对象。
Compoment类通常被称为组件,根据Component的不同作用,可将其分为基本组件类和容器类。基本组件是诸如按钮、文本框之类的图形界面元素,而容器类则是通过Component的子类Container实例化的对象。Container类表示容器,是一种特殊的组件,可以用来容纳其他组件。Container容器又分为两种类型,分别是Window和Panel。
1.Window
Window类是不依赖其他容器而独立存在的容器,它有两个子类,分别是Frame类和Dialog类。Frame类用于创建一个具有标题栏的框架窗口,作为程序的主界面,Dialog类用于创建一个对话框,实现与用户的信息交互。
2.Panel
Panel也是一个容器,但是它不能单独存在,只能存在其他容器(Window或其子类)中,一个Panel对象代表了一个长方形的区域,在这个区域中可以容纳其他组件。在程序中通常会使用Panel来实现一些特殊的布局。
案例1:制作第一个窗体
public class Example01 {
public static void main(String[] args) {
//建立新窗体对象
Frame f = new Frame("我的第一个窗体!");
//设置窗体的宽度和高度
f.setSize(400,300);
//设置窗体在屏幕中所处位置(参数是窗口左上角的坐标)
f.setLocation(300,200);
//设置窗体可见
f.setVisible(true);
}
}
三、布局管理器
之前提到过,组件不能单独存在,必须放置于容器当中,而组件在容器中的位置和尺寸是由布局管理器来决定的,在java.awt包中提供了五种布局管理器,分别是:FlowLayout(流式布局管理器)、BorderLayout(边界布局管理器)、GridLayout(网络布局管理器)、GridBagLayout(网络包布局管理器)和CardLayout(卡片布局管理器)。每个容器在创建时都会使用一种默认的布局管理器,在程序中可以通过调用同期对象的setLayout()方法设置布局管理器。
例如把一个Frame窗体的布局管理器设置为FlowLayout,代码如下:
Frame frame = new Frame();
frame.setLayout(new FlowLayout());
1.FlowLayout
流式布局管理是最简单的布局管理,在这种布局下,容器会将组按照添加顺序从左向右放置。当达到容器的边界时,会自动将组建放到下一行的开始位置。这些组建可以左对齐、居中对齐(默认方式)或右对齐的方式排列。FlowLayout对象有三个构造方法。
方法声明 | 功能描述 |
---|---|
FlowLayout() | 组建默认居中对齐,水平,垂直间距默认为5个单位 |
FlowLayout(int align) | 指定组建相对于容器的对齐方式、水平、垂直间距默认为5个单位 |
FlowLayout(int align,int hgap,int vgap) | 指定组建的对齐方式,如水平,垂直间距 |
表中列出了FlowLayout的三个构造方法,其中,参数align决定组建在每行中相对于容器边界的对齐方式,可以使用该类中提供的常量作为参数传递给构造方法,其中FlowLayout用于表示左对齐、FlowLayout.RIGHT用于表示右对齐、FlowLayout.CENTER用于表示居中对齐。参数hgap和参数vgap分别设定组件之间的水平和垂直间隙,可以填入一个任意数值。
例:
import java.awt.Button;
import java.awt.FlowLayout;
import java.awt.Frame;
public class example02 {
public static void main(String[] args) {
//创建一个FlowLayout的窗体
Frame f = new Frame("FlowLayout");
//设置窗体中的布局管理器FlowLayout,所有组件左对齐,水平间距为20,垂直间距为30
f.setLayout(new FlowLayout(FlowLayout.LEFT,20,30));
//设置窗体大小
f.setSize(220,300);
//设置窗体的位置(左上角)
f.setLocation(300,200);
//把按钮添加到f对应的窗口中
f.add(new Button("第一个按钮"));
f.add(new Button("第二个按钮"));
f.add(new Button("第三个按钮"));
f.add(new Button("第四个按钮"));
f.add(new Button("第五个按钮"));
f.add(new Button("第六个按钮"));
//设置窗体可见
f.setVisible(true);
}
}
2.BorderLayout
边界布局管理器是一种较为复杂的布局方式,它将容器划分为五个区域,分别是东(EAST)、南(SOUTH)、西(WEST)、北(NORTH)、中(CENTER)。组件可以被放置在这五个区域中的任意一个。
边界布局管理器将容器划分为五个区域,其中箭头是指改变容器大小时,各个区域需要改变的方向。也就是说,在改变容器是NORTH和SOUTH区域高度不变长度调整,WEST和EAST区域宽度不变高度调整增,CENTER会相应进行调整。
当向边界布局管理器中添加组件时,需要使用add(Component comp,Object constrains)方法。其中参数comp表示要添加的组件,constrains指定将组件添加到布局中的方式和对象,它是一个Object类型,在传参时可以使用BorderLayout提供的五个常量。
例:
import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.Frame;
public class example03 {
public static void main(String[] args) {
//创建一个名为BorderLayout对的窗体
Frame f = new Frame("BorderLayout");
f.setLayout(new BorderLayout());//设置窗体中的布局管理器BorderLayout
f.setSize(300,300);//设置大小
f.setLocation(300,200);
f.setVisible(true);
//下面代码是创建五个按钮,分别用于填充BorderLayout的五个区域
Button but1 = new Button("EAST");
Button but2 = new Button("SOUTH");
Button but3 = new Button("WEST");
Button but4 = new Button("NORTH");
Button but5 = new Button("CENTER");
//将创建好的按钮添加到窗体中,并且设置按钮所在的区域
f.add(but1,BorderLayout.EAST);
f.add(but2,BorderLayout.SOUTH);
f.add(but3,BorderLayout.WEST);
f.add(but4,BorderLayout.NORTH);
f.add(but5,BorderLayout.CENTER);
}
}
3.GridLayout
网格布局管理器使用纵横线将容器分成n行m列相等的网格,每个网格中放置一个组件。添加到容器中的组件首先放置在第一行第一列的网格中,然后在第1行的网格中从左向右一次放置其他组件,行满后,继续在下一行中从左到右放置组件。与FlowLayout不同的是,放置在GridLayout布局管理器中的组件将自动占据整个网格区域。
构造方法:
方法声明 | 功能描述 |
---|---|
GridLayout() | 默认只有一行,每个组件占一列 |
GridLayout(int rows,int cols) | 指定容器的行数和列数 |
GridLayout(int rows,int cols,int,hgap,int xgap) | 指定容器的行数和列数以及组件之间的水平、垂直间距 |
水平间隙指的是网格之间的水平距离,垂直间隙同理
import java.awt.Button;
import java.awt.Frame;
import java.awt.GridLayout;
public class example04 {
public static void main(String[] args) {
// 创建一个名为GridLayout的窗体
Frame f = new Frame("GridLayout");
f.setLayout(new GridLayout(3,3));//设置该窗体为3*3的网格
f.setSize(300,300);
f.setLocation(200,300);
//循环添加9个按钮到GridLayout中
for(int i=1;i<=9;i++) {
Button btn = new Button("btn"+i);
f.add(btn);//向窗体中添加按钮
}
f.setVisible(true);
}
}
4.GridBagLayout
网格包布局管理器是最灵活、最复杂的布局管理器。与GridLayout布局管理器类似,不同的是,它允许网格中的组件大小各不相同,而且允许一个组件跨越一个或多个网络。
使用GridBagLayout布局管理器的步骤如下:
- 创建GridBagLayout布局管理器,并使用容器采用该布局管理器
- 创建GridBagLayout对象(布局约束条件),并设置该对象的相关属性
- 调用GridBagLayout对象的setConstrains()方法建立GridBagConstrains对象和受控组件之间的并联
- 向容器中添加组件
GridBagConstraints对象可以重复使用,只需要改变它的属性即可。如果要向容器中添加多个组件,则重复(2)、(3)、(4)步骤。
import java.awt.Button;
import java.awt.Frame;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
//网格包布局管理器
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;//设置纵向权重为0
c.weighty = 0;//设置纵向权重为0
this.addComponent("btn5",layout,c);
c.gridwidth = 1;//设置组件跨一个网格(默认值)
this.addComponent("btn6",layout,c);
c.gridwidth = GridBagConstraints.REMAINDER;//添加的组件是本行的最后一个组件
this.addComponent("btn7",layout,c);
c.gridwidth = 1;//设置组件跨2个网格
c.gridheight = 2;设置组件跨一个网格(默认值)
c.weightx = 2;//设置纵向权重为2
c.weighty = 2;//设置纵向权重为2
this.addComponent("btn8",layout,c);
c.gridwidth = GridBagConstraints.REMAINDER;//添加的组件是本行的最后一个组件
c.gridheight = 1;//设置组件跨1个网格
this.addComponent("btn9",layout,c);
this.addComponent("btn10",layout,c);
this.setTitle(title);//设置窗体的标题
this.pack();//设置自动窗体大小
this.setVisible(true);
}
//添加组件的方法,通过指定的约束,将组件添加到布局管理器中
public void addComponent(String name,GridBagLayout layout,GridBagConstraints c) {
Button bt = new Button(name);//创建一个名为name的按钮
layout.setConstraints(bt, c);//设置约束对象和按钮的关联
this.add(bt);
}
}
public class example05 {
public static void main(String[] args) {
new Layout("GridBagLayout");
}
}
从上面的步骤可以看出,使用GridBagLayout布局管理器关键在于GridBagConstraints对象,它才是控制容器中每个组件布局的核心类,在GridBagConstraints类中有很多表示约束的属性.
-
GridBagConstraints.gridwidth
、GridBagConstraints.gridheight
指定组件显示区域中一行中的单元格数(对于
gridwidth
)或列(对于gridheight
)。 默认值为1.使用GridBagConstraints.REMAINDER
指定组件的显示区域将从gridx
到行中的最后一个单元格(对于gridwidth
),或从gridy
到列中的最后一个单元格(对于gridheight
)。 使用GridBagConstraints.RELATIVE
来指定组件的显示区域将从gridx
到其行中最后一个单元格的下一个(对于gridwidth
或从其列中的最后一个单元格的gridy
到gridheight
)。 -
GridBagConstraints.fill
当组件的显示区域大于组件的请求大小时使用,以确定是否(以及如何)调整组件的大小。 可能的值为
GridBagConstraints.NONE
(默认值),GridBagConstraints.HORIZONTAL
(使组件足够宽,可以水平填充其显示区域,但不要更改其高度),GridBagConstraints.VERTICAL
(使组件足够高以垂直填充其显示区域,但不要更改其宽度)和GridBagConstraints.BOTH
(使组件完全填充其显示区域)。 -
GridBagConstraints.weightx、GridBagConstraints.weighty
用于确定如何分配空间,这对于指定调整大小的行为很重要。 除非您指定一行中至少一个组件(
weightx
)和列(weighty
)的权重,否则所有组件都将集中在其容器的中心。 这是因为当重量为零(默认值)时,GridBagLayout
对象在其单元格格栅和容器边缘之间放置任何额外的空格。
5.CardLayout
在操作程序时,经常会遇到通过选项卡按钮来切换程序中的界面,这些界面就相当于一张张卡片,而管理这些卡片的布局管理器就是卡片布局管理器。卡片布局管理器将界面看做是一系列卡片,在任何时候只有其中一张卡片是可见的,这张卡片占据容器的整个区域。
在CardLayout不倦利器中经常会用到下面几个方法:
方法声明 | 功能需求 |
---|---|
void first(Container parent) | 显示parent容器第一张卡片 |
void last(Container parent) | 显示parent容器的最后一张卡片 |
void previous(Container parent) | 显示parent容器的前一张卡片 |
void next(Container parent) | 显示parent容器的下一张卡片 |
void show(Container parent,String name) | 显示parent容器中名称为name的组件,如果不存在,则不会发生任何操作 |
import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.CardLayout;
import java.awt.Frame;
import java.awt.Label;
import java.awt.Panel;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
class cardLayout extends Frame implements ActionListener{
CardLayout cardlayout = new CardLayout();//定义卡片布局管理器
Panel cardPanel = new Panel();//定义面板,放置卡片内容
Panel controlPanel = new Panel();//定义面板,放置按钮
Button preButton;//声明切换到上一张卡片的按钮
Button nextButton;//声明切换到下一张卡片的按钮
public cardLayout() {
this.setSize(300,200);//设置窗体大小
cardPanel.setLayout(cardlayout);//设置布局为卡片布局管理器
//在cardPanel中添加三个文本标签
cardPanel.add(new Label("第一个界面",Label.CENTER));
cardPanel.add(new