一、AWT
1、AWT
JAVA使用AWT和Swing 类完成图形用户界面编程,AWT全称是抽象窗口工具集(Abstract Window Toolkit),它是最早的sun提供的GUI库(Graphics User Interface)图形用户界面。
AWT是窗口框架,它从不同平台的窗口系统中抽取共同组件,当使用AWT编写图形界面应用时,程序仅指定了界面组件的位置和行为,并为提供真正的实现,JVM 调用操作系统本地的图形界面来创建和平台一直的对等体。
2、AWT继承体系
所有和AWT编程相关的类都放在java.awt包以及他的子包中,AWT中有两个基类:Component和MenuComponent
- Component:代表一个能以图形化方式显示出来,并可与用户交换的对象
- MenuComponent:代表图形界面的菜单组件,包括菜单条、菜单项等子类
二、AWT容器
1、AWT容器
容器(Container)是Component的子类,因此容器对象本身也是一个组件,具有组件的所有性质,可以调用Component类的所有方法,Component类提供了几个常用方法设置组件的大小,位置和可见性:
- setLocation(int x, int y):设置组件的位置。
- setSize(int width, int height):设置组件的大小。
- setBounds(int x, int y, int width, int height):同时设置组件的位置、大小。
- setVisible(Boolean b):设置该组件的可见性。
Container容器,此容器还可以盛装其他组件,其提供了如下几个常用方法来访问容器里的组件。
- Component add(Component comp):向容器中添加其他组件(该组件既可以是普通组件,也可以是容器),并返回被添加的组件。
- Component getComponentAt(int x, int y):返回指定点的组件。
- int getComponentCount():返回该容器内组件的数量。
- Component getComponents():返回该容器内的所有组件。
2、AWT容器类型
AWT主要提供的容器类型:
- Window:可独立存在的顶级窗口,默认为BorderLayout布局管理器。
- Panel:可作为容器容纳其他组件,但不能独立存在,必须被添加到其他容器中(如 Window、Panel 或者 Applet等)。默认为FlowLayout布局管理器。
- ScrollPane:含有滚动条的容器,默认为BorderLayout布局管理器。
如下使用Frame创建一个窗口:
public static void main(String[] args) {
Frame f = new Frame("测试窗口");
f.setBounds(240,240,100,100); //设置窗口大小,位置
f.setVisible(true);
}
常用的关闭窗口方法有以下4种
- DO NOTHING _ON_CLOSE //代表什么都不做就能把窗口关闭
- DISPOSE_ON_CLOSE //代表任何注册监听程序对象后会自动隐藏并释放窗体
- HIDE_ON_CLOSE //表示隐藏窗口的默认窗口关闭
- EXIT_ON_CLOS //表示退出应用程序默认窗口关闭
Panel是AWT中另一种典型的容器,他代表不能独立存在,必须放在其他容器中过的容器。Panel外在表现为一个矩形区域,该区域内可盛装其他组件,Panel容器存在的意义在于为其他组件提供空间,Panel容器特点如下:
- 可作为容器来盛装其他组件,为放置组件提供空间
- 不能单独存在,必须放置在其他容器中
- 默认使用FlowLayout作为其布局管理器
如下使用Pane作为容器盛装个按钮和一个文本框,并将该Panel对象添加到Frame对象中:
public static void main(String[] args) {
Frame f = new Frame("测试窗口");
//创建一个Panel容器
Panel p = new Panel();
//向容器中添加两个组件
p.add(new TextField(20));
p.add(new Button("按钮"));
//将Panel容器添加到Frame窗口中
f.add(p);
//设置窗口大小,位置
f.setBounds(240,240,100,100);
//将窗口显示出来
f.setVisible(true);
}
ScrollPane是一个带滚动条的容器,他不独立存在,必须被添加到其他容器中,ScrollPane具有以下几个特点:
- 可作为容器来盛装其他组件,当组件占用空间过大时,ScrollPane自动产生滚动条。当然也可以通过指定特定的构造器参数来指定默认具有滚动条
- 不能单独存在,必须放在其他容器中
- 默认使用BorderLayout作为布局管理器
如下使用ScrollPane容器代替Panel容器:
public static void main(String[] args) {
Frame f = new Frame("测试窗口");
//创建一个ScrollPanel容器,指定总是具有滚动条
ScrollPane sp = new ScrollPane(ScrollPane.SCROLLBARS_ALWAYS);
//向ScrollPanel容器中添加两个组件
sp.add(new TextField(20));
sp.add(new Button("单击此处"));
//将ScrollPanel容器添加到Frame对象中
f.add(sp);
//设置窗口大小、位置
f.setBounds(30,30,250,120);
//将窗口显示出来
f.setVisible(true);
}
三、布局管理器
1、FlowLayout
FlowLayout布局管理器中,组件像水流一样向某方向流动(排列),遇到障碍(边界)就会折回,重头开始排列,默认情况下,FlowLayout布局管理器从左向右排列所有组件,遇到边界就会折回下一行重新开始。
FlowLayout有三个构造器:
- FlowLayout():使用默认对齐方式及默认的垂直间距,水平间距创建FlowLayout布局管理器
- FlowLayout(int align):使用指定的对齐方式及默认的垂直间距、水平间距创建FlowLayout布局管理器
- FlowLayout(int align,int hgap,int vgap):使用指定的对齐方式及指定的水平间距、垂直间距创建FlowLayout布局管理器,其中align代表FlowLayout中组件的排列方向(从左向右、从右向左、从中间向两边),该参数使用FlowLayout类的静态常量:FlowLayout.LEFT、FlowLayout.CERTER、FlowLayout.RIGHT
如下将Frame改为使用FlowLayout布局管理器
public static void main(String[] args) {
Frame f = new Frame("测试窗口");
//设置Frame容器使用FlowLayout布局管理器
f.setLayout(new FlowLayout(FlowLayout.LEFT,20,5));
//向窗口中添加10个按钮
for(int i =1;i<=10;i++) {
f.add(new Button("Button "+i));
}
//设置窗口为最佳大小
f.pack();
//将窗口显示出来
f.setVisible(true);
}
2、BorderLayout布局管理器
BorderLayout 将容器分为 EAST、SOUTH、WEST、NORTH、CENTER (东、南、西、北、中心)五个区域,普通组件可以被放置在这 5 个区域的任意一个中。当改变使用 BorderLayout 的容器大小时,NORTH、SOUTH 和 CENTER区域水平调整,而 EAST、WEST 和 CENTER 区域垂直调整。BorderLayout最多可以放5个组件,如果某个区域没有放置组件时,旁白你的区域就会自动占据该区域。
使用BorderLayout 有如下两个注意点:
- 当向使用 BorderLayout 布局管理器的容器中添加组件时,需要指定要添加到哪个区域中。如果没有指定添加到哪个区域中,则默认添加到中间区域中。
- 如果向同一个区域中添加多个组件时,后放入的组件会覆盖先放入的组件。
BorderLayout有两个构造器:
- BorderLayout():使用默认的水平间距、垂直间距创建BorderLayout布局管理器
- BorderLayout(int hgap,int vgap):使用指定的水平间距,垂直间距创建BorderLayout布局管理器
如下将Frame改为使用BorderLayout布局管理器
public static void main(String[] args) {
Frame f = new Frame("测试窗口");
//设置Frame容器使用BorderLayout布局管理器
f.setLayout(new BorderLayout(20,5));
//向窗口中添加按钮
f.add(new Button("东"),EAST);
f.add(new Button("西"),WEST);
f.add(new Button("南"),SOUTH);
f.add(new Button("北"),NORTH);
f.add(new Button("中"));
//设置窗口为最佳大小
f.pack();
//将窗口显示出来
f.setVisible(true);
}
3、GridBagLayout布局管理器
GridLayout 布局管理器将容器分割成纵横线分隔的网格,每个网格所占的区域大小相同。当向使用GridLayout 布局管理器的容器中添加组件时,默认从左向右、从上向下依次添加到每个网格中。与FlowLayout 不同的是,放置在 GridLayout 布局管理器中的各组件的大小由组件所处的区域来决定(每个组件将自动占满整个区域)。
GridLayout 有如下两个构造器。
- GridLayout(int rows,int cols):采用指定的行数、列数,以及默认的横向间距、纵向间距将容器分割成多个网格。
- GridLayout(int rows,int cols,int hgap,int vgap):采用指定的行数、列数,以及指定的横向间距、纵向间距将容器分割成多个网格。
如下将Frame改为使用GridLayout布局管理器
public static void main(String[] args) {
Frame f = new Frame("计算器");
Panel p1 = new Panel();
p1.add(new TextField(30));
f.add(p1.NORTH);
Panel p2 = new Panel();
p2.setLayout(new GridLayout(3,5,4, 4));
String[] name = {"0","1","2","3","4","5","6","7","8","9","0","+","-","*","%","."};
//向Panel中依次添加15个元素
for(int i=1;i<=name.length;i++){
p2.add(new Button(name[i]));
}
//默认将Panel对象添加到Frame窗口的中间
f.add(p2);
//设置窗口为最佳大小
f.pack();
//将窗口显示出来
f.setVisible(true);
}
4、GridBagLayout布局管理器
GridBagLayout 布局管理器的功能最强大,但也最复杂,与 GridLayout 布局管理器不同的是,在GridBagLayout 布局管理器中,一个组件可以跨越一个或多个网格,并可以设置各网格的大小互不相同,从而增加了布局的灵活性。当窗口的大小发生变化时,GridBagLayout 布局管理器也可以准确地控制窗口各部分的拉伸。为了处理 GridBagLayout 中 GUI 组件的大小、跨越性,Java 提供了 GridBagConstraints 对象,该对象与特定的 GUI 组件关联,用于控制该 GUI 组件的大小、跨越性。
使用GridBagLayout布局管理器步骤如下:
1、创建GridBagLayout布局管理器,并指定GUI容器使用该布局管理器
GridBagLayout gb = new GridBagLayout();
container.setLayout(gb);
2、创建GridBagConstraints对象,并设置该对象的相关属性(用于设置受该对象控制的GUI组件的大小、跨越性等)
gbc.gridx = 2; //设置受该对象控制的GUI组件位于网络的横向索引
gbc.gridy = 1; //设置受该对象控制的GUI组件位于网络的纵向索引
gbc.gridwidth = 2; //设置受该对象控制的GUI的组件横向跨越多少网格
gbc.gridheight = 1; //设置受该对象控制值得GUI组件纵向跨越多少网格
3、调用GridBagLayout对象方法来建立GridBagConstraints对象和受控组件之间的关联
gb.setConstraints(c.gbc); //设置c组件受gbc对象控制
4、添加组件,与采用普通布局管理器添加组件的方法完全一样
container.add(c);
GridBagLayout有7中属性:
- gridx、gridy:横向索引、纵向索引
- gridwidth、gridheight:设置受该对象控制的GUI组件横向、纵向跨越多少个网格
- fill:设置受该对象控制的GUI组件如何占据空白区域
- ipadx、ipady:设置受该对象控制的GUI组件横向、纵向内部填充的大小
- insets:设置受该对象控制的GUI组件的外部填充的大小
- anchor:设置受该对象控制的GUI组件在其显示区域的定位方式
- weightx、weighty:设置受该对象控制的GUI组件占据多余空间的水平、垂直增加比例,这两个属性的默认值是0
如何使用GridBagLayout布局管理器来管理窗口
public class GridBagLayout {
private Frame f = new Frame("测试窗口");
private GridBagLayout gb = new GridBagLayout();
private GridBagConstraints gbc = new GridBagConstraints();
private Button[] bs = new Button[10];
public void init() {
f.setLayout(gb);
for (int i = 0; i < bs.length; i++) {
bs[i] = new Button("按钮" + i);
}
//所有组件都可以在横向、纵向上扩大
gbc.fill = GridBagConstraints.BOTH;
gbc.weightx = 1;
addButton(bs[0]);
addButton(bs[1]);
addButton(bs[2]);
//该GridBagConstraints控制的GUI组件将会成为横向最后一个组件
gbc.gridwidth = GridBagConstraints.REMAINDER;
addButton(bs[3]);
//该GridBagConstraints控制的GUI组件将在横向上不会扩大
gbc.weightx = 0;
addButton(bs[4]);
//该GridBagConstraints控制的GUI组件将横跨两个网格
gbc.gridwidth = 2;
addButton(bs[5]);
//该GridBagConstraints控制的GUI组件将横跨一个网格
gbc.gridwidth = 1;
//该GridBagConstraints控制的GUI组件将在纵向上跨两个网格
gbc.gridwidth = 2;
//该GridBagConstraints控制的GUI组件将会成为横向最后一个组件
gbc.gridwidth = GridBagConstraints.REMAINDER;
addButton(bs[6]);
//该GridBagConstraints控制的GUI组件纵向扩大的权重为1
gbc.weighty = 1;
addButton(bs[7]);
//设置下面的按钮不会在纵向上扩大
gbc.weighty = 0;
//该GridBagConstraints控制的GUI组件将会成为横向最后一个组件
gbc.gridwidth = GridBagConstraints.REMAINDER;
//该GridBagConstraints控制的GUI组件将在纵向上横跨一个网格
gbc.gridwidth = 1;
addButton(bs[8]);
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){
new GridBagLayout().init();
}
}
5、CardLayout布局管理器
CardLayout将加入容器的所有组件看成一叠卡片,每次只有最上面的那个Component才可见。
CardLayout提供了两个构造器:
- CardLayout():创建默认的CardLayout布局管理器
- CardLayout(int hgap,int vgap):通过指定卡片与容器左右边界的间距(hgap)、上下边界(vgap)的间距来创建CardLayout布局管理器
CardLayout用于组件控制的5个常用方法:
- frist(Container target):显示target容器中的第一张卡片
- last(Container target):显示target容器中的最后一张卡片
- previous(Container target):显示target容器中的前一张卡片
- next(Container target):显示target容器中的后一张卡片
- show(Container target,String name):显示target容器中的指定名字的卡片
如何使用CardLayout布局管理器来管理窗口
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class AWTTest {
public static void main(String[] args) {
Frame frame = new Frame("test");
//创建一个Panel,用来存储多张卡片
Panel p1 = new Panel();
//创建CardLayout,并且把该对象设置给之前创建的容器
CardLayout cardLayout = new CardLayout();
p1.setLayout(cardLayout);
//往Panel中存储多个组件
String[] names = {"第一张", "第二张", "第三张", "第四张", "第五张"};
for (int i = 1; i < names.length; i++) {
p1.add(names[i], new Button(names[i]));
}
//把Panel放到frame的中间区域
frame.add(p1);
//创建另外一个Panel p2,用来存储多个按钮组件
Panel p2 = new Panel();
//创建5个按钮组件
Button b1 = new Button("上一张");
Button b2 = new Button("下一张");
Button b3 = new Button("第一张");
Button b4 = new Button("最后一张");
Button b5 = new Button("第三张");
/**
frame.add(new Button("上一张"));
frame.add(new Button("下一张"));
frame.add(new Button("第一张"));
frame.add(new Button("最后一张"));
frame.add(new Button("第三张"));
*/
//创建一个事件监听器,监听按钮的点击动作
ActionListener listener = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
String actionCommand = e.getActionCommand(); //字符串为按钮上的文字
switch (actionCommand) {
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;
}
}
};
//把当前这个事件监听器和多个按钮绑定到一
6、绝对定位
绝对定位即就是随意拖动控件,创建绝对定位的步骤如下:
- 将Container的布局管理器设成null:setLayout(null)
- 向容器中添加组件时,先调用setBounds或setSize()方法来设置组件的大小、位置、或者直接创建GUI组件时通过构造参数指定该组件的大小、位置,然后将该组件添加到容器中。
如何使用绝对定位来控制窗口中的GUI组件
import java.awt.Button;
import java.awt.Frame;
public class NullLayoutTest{
Frame f = new Frame("测试窗口");
Button b1 = new Button("第一个按钮");
Button b2 = new Button("第二个按钮");
public void init() {
//设置使用null布局管理器
f.setLayout(null);
//下面强制设置每个按钮的大小、位置
b1.setBounds(20,30,90,28);
f.add(b1);
b2.setBounds(50,45,120,35);
f.add(b2);
f.setBounds(50,50,200,100);
f.setVisible(true);
}
public static void main(String[] args) {
new NullLayoutTest().init();
}
}
7、BoxLayout布局管理器
BoxLayout看可以在垂直和水平两个方向上摆放GUI组件。其提供了一个简单的构造器:
- BoxLayout(Container target,int axis):指定创建基于target容器的BoxLayout布局管理器,该布局管理器中的组件按axis方向排列,其中axis有BoxLayout.X_AXIS(横向)和BosLayout.Y_AXIS(纵向)两个方向。
BoxLayout有两个方法:
- static Box createHorizoontalBox():创建一个水平排列组件的Box容器
- static Box createVerticalBox():创建一个垂直排列组件的Box容器
如何使用BoxLayout布局管理器来控制容器中按钮的布局:
public static void main(String[] args) {
Frame frame = new Frame("BoxLayoutTest");
//创建一个水平排列组件的Box容器
Box hBox = Box.createHorizontalBox();
//往当前容器中添加两个按钮
hBox.add(new Button("水平按钮一"));
hBox.add(new Button("水平按钮二"));
//创建一个垂直排列组件的Box容器
Box vBox = Box.createVerticalBox();
//往当前容器中添加两个按钮
vBox.add(new Button("垂直按钮一"));
vBox.add(new Button("垂直按钮二"));
//把两个Box容器添加到Frame中显示
frame.add(hBox,BorderLayout.NORTH);
frame.add(vBox);
frame.setSize(500,500);
frame.setVisible(true);
}
Box类中,提供了5个方便的静态方法来生成间隔组件
- static Component createHorizontalStrut(int width):创建一条指定宽度(宽度固定了,不能拉伸)的水平Strut(可在垂直方向上拉伸的间距)
- static Component createVerticalStrut(int height):创建一条指定高度(高度固定了,不能拉伸)的垂直Strut(可在水平方向上拉伸的间距)
- static Component createHorizontalGlue():创建一条水平Glue(可在两个方向上同时拉伸的间距)
- static Component createVerticalGlue():创建一条垂直Glue(可在两个方向上同时拉伸的间距)
import javax.swing.*;
import java.awt.*;
public class BoxLayoutTest {
public static void main(String[] args) {
Frame frame = new Frame("BoxLayoutTest");
//创建一个水平排列组件的Box容器 hBox
Box hBox = Box.createHorizontalBox();
//往hBox容器中添加按钮,还需在多个按钮之间添加分割
hBox.add(new Button("水平按钮一"));
hBox.add(Box.createHorizontalGlue()); //该分割在两个方向都可以拉伸
hBox.add(new Button("水平按钮二"));
hBox.add(Box.createHorizontalStrut(30));
hBox.add(new Button("水平按钮三"));
//创建一个垂直排列组件的Box容器 vBox
Box vBox = Box.createVerticalBox();
//往vBox容器中添加按钮,还需在多个按钮之间添加分割
vBox.add(new Button("垂直按钮一"));
vBox.add(Box.createVerticalGlue());
vBox.add(new Button("垂直按钮二"));
vBox.add(Box.createVerticalStrut(30));
vBox.add(new Button("垂直按钮三"));
//把Box容器添加到Frame中显示
frame.add(hBox,BorderLayout.NORTH);
frame.add(vBox);
frame.setSize(500,500);
frame.setVisible(true);
}
}