一,GUI what?
GUI =Graphical User Interface,图形用户接口、图形用户界面。
Java编写带图形界面的程序,有两套API
1,AWT(Abstract Window Toolkit)
AWT实现,真正实现是依赖于操作系统提供的底层函数来实现的。
2,SWING
不依赖于操作系统的底层实现 纯java写的API 跨平台,组件比AWT多,但界面比较丑,处理事件跟AWT一样。
二,AWT
AWT普通组件的继承关系图和容器组件继承关系图如下:
Window
顶级容器 可以独立存在Panel
不是顶级容器 不能独立存在,必须放到其他容器中(window、Panel…)
可作为容器来盛装其他组件,为放置组件提供空间,不能单独存在,必须放到其他容器中,默认使用FlowLayout。Frame
Frame代表常见的窗口,它是Window类的子类
Frame对象有标题,允许通过拖拉来改变窗口的位置、大小,初始化时为不可见,可用setVisible(true)使其显示出来,默认使用BorderLayout。- ScrollPane
ScrollPane是一个带滚动条的容器 也不是顶级容器 不能独立存在 必须添加到其他容器中,自动产生滚动条,默认使用BorderLayout。
三,AWT的布局管理器
为了使生成的图形用户界面具有良好的平台无关性,布局管理器可以根据不同的平台调整组件的大小,以实现标签的最佳大小(既没有冗余空间,也没有内容被阻挡),常见的布局有六种。
1.FlowLayout(流式布局)
组件从第一行开始,从左向右排列,排列到末尾折回,另起一行继续从左向右排列。Panel和Applet默认使用FlowLayout布局管理器。
示例代码:
public class TestFlowLayout {
public static void main(String[] args) {
Frame f = new Frame("测试窗口");
//从左向右显示 水平间距20px 垂直间距5px
f.setLayout(new FlowLayout(FlowLayout.LEFT,20,5));
f.add(new Button("按钮1"));
f.add(new Button("按钮2"));
f.add(new Button("按钮3"));
f.add(new Button("按钮4"));
f.pack();//设置窗口为最佳大小
f.setVisible(true);
}
}
注意:从右向左排列的时候,也是把第二个组件添加到第一个组件后面,这样之前添加的就被挤到左边来了。
2.BorderLayout
BorderLayout将容器分为EAST、SOUTH、WEST、NORTH、CENTER五个区域,普通组件可以被放置在这5个区域的任意一个中。如图:
注意:如果没有指定添加到哪个区域中,则默认添加到中间区域中。如果向同一个区域中添加多个组件时,后放入的组件会覆盖先放入的组件。
3.GridLayout
GridLayout把容器分成若干个大小相等的网格,默认从左往右,依次添加到网格中。
4.CardLayout
类似扑克牌,叠起来的,只能看见最上面的一张,先添加的卡片在上面。
first() 显示第一张卡片
last() 显示最后一张
previous () 显示前一张
next() 显示下一张
show () 显示指定名字的卡片
5.AbsoluteLayout(绝对布局)
给组件直接指定组件的位置、大小(不能跨平台了,不推荐)
6.BoxLayout
BoxLayout通常和Box容器结合使用,Box是一个特殊的容器,它有点像Panel容器,但该容器默认使用BoxLayout布局管理器。Box提供了如下两个静态方法来创建Box对象.
- createHorizontalBox():创建一个水平排列组件的Box容器。
- createVerticalBox():创建一个垂直排列组件的Box容器。
一旦获得了Box容器之后,就可以使用Box来盛装普通的GUI组件,然后将这些Box组件添加到其他容器中,从而形成整体的窗口布局。实例代码:
public class TestBox {
private Frame f = new Frame("测试窗口");
private Box horizontal = Box.createHorizontalBox();
private Box vertical = Box.createVerticalBox();
public void init(){
horizontal.add(new Button("水平按钮1"));
horizontal.add(new Button("水平按钮2"));
vertical.add(new Button("垂直按钮1"));
vertical.add(new Button("垂直按钮2"));
f.add(horizontal,BorderLayout.NORTH);
f.add(vertical);
f.pack();
f.setVisible(true);
}
public static void main(String[] args) {
new TestBox().init();
}
}
四,AWT的事件处理
1,基本概念
1.事件源(Event Source):事件发生来源,即谁发出了这个事件
2.事件监听器(Event Listener):发生事件后对事件的处理.
3.事件对象(Event): 对当前事件的一个具体描述。
2,事件的注册
- 内部类形式: 将事件监听器类定义成当前类的内部类。
- 顶级类形式: 将事件监听器类定义成一个顶级类(普通类)
- 类本身作为事件监听器类:让当前类本身实现监听器接口或继承事件适配器.
- 匿名内部类形式: 使用匿名内部类创建事件监听器对象.
内部类形式实例代码:
public class TestListener {
private Frame f=new Frame("监听测试");
public static void main(String[] args) {
new TestListener().init();
}
private void init() {
Button btn=new Button("点击");
btn.addActionListener(new MyActionListener());
f.add(btn);
f.setVisible(true);
f.pack();
}
private class MyActionListener implements ActionListener{
public void actionPerformed(ActionEvent e) {
System.out.println("你点击了我");
}
}
}
顶级类形式示例代码:
第一步:创建一个普通类MyActionListener:
public class MyActionListener implements ActionListener{
public void actionPerformed(ActionEvent e) {
System.out.println("你点击了我");
}
}
第二步,在另一个类中调用
public class TestListener {
private Frame f=new Frame("监听测试");
public static void main(String[] args) {
new TestListener().init();
}
private void init() {
Button btn=new Button("点击");
btn.addActionListener(new MyActionListener());
f.add(btn);
f.setVisible(true);
f.pack();
}
}
类本身作为事件监听器类代码示例:
public class TestListener implements ActionListener{
private Frame f=new Frame("监听测试");
public static void main(String[] args) {
new TestListener().init();
}
private void init() {
Button btn=new Button("点击");
btn.addActionListener(this);
f.add(btn);
f.setVisible(true);
f.pack();
}
public void actionPerformed(ActionEvent e) {
System.out.println("你点击了我");
}
}
匿名内部类形式:
public class TestListener {
private Frame f = new Frame("监听测试");
public static void main(String[] args) {
new TestListener().init();
}
private void init() {
Button btn = new Button("点击");
btn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.out.println("你点击了我");
}
});
f.add(btn);
f.setVisible(true);
f.pack();
}
}
以上4种推荐使用第一种和第四种,如果监听器类中的代码比较少可以使用匿名内部类,代码多的话最好使用第一种(内部类的形式),因为如果监听器类里面的代码过多时使用匿名内部类会影响代码的可读性