1、GUI组件介绍
2、事件处理
3、观察者模式
1、GUI组件介绍
GUI编程(Graphic User Interface,图形用户接口)
GUI的各种元素,如:容器、按钮、文本框等
1、Frame类
2、Button类
3、Panel类
5、Toolkit类
5、布局管理器
6、基本组件
package com.vince.gui;
import java.awt.*;
import java.awt.event.*;
/**
* Created by vince on 2017/7/3.
*/
public class MyFrame extends Frame implements ActionListener{
/**
* 初始化窗体的基本属性
*/
public MyFrame(){
this.setSize(600,400);
this.setTitle("我的第一个GUI窗体");
//创建一个按钮
Button button = new Button("点我一下,有惊喜");
//给按钮添加单击事件
button.addActionListener(this);
//创建一个线性布局
FlowLayout flowLayout = new FlowLayout();
//把布局应用到窗体上
this.setLayout(flowLayout);
//给窗体添加关闭事件
this.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
super.windowClosing(e);
System.exit(0);
}
});
//把按钮添加到窗体上
this.add(button);
this.setVisible(true);
}
//单击事件处理的方法
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("惊喜来了");
}
public static void main(String[] args) {
new MyFrame();
}
}
看这个显示乱码
解决一下
idea的setting
命令设一下
文件编码设一下 设为UTF-8
显示正常
然后实现窗体的监听事件
可是要实现的方法太多了
这里只需要Closing方法
不想写其他方法怎么办
以前的博客有 在事件处理的时候
写一个适配器 让适配器去实现此接口的所有方法 不过里面是空实现 什么都不实现
然后写这个窗体事件的时候 就继承这个适配器 重写我们需要的方法就行
ok这个事情 现在已经不用我们自己做了 JAVA API已经帮我们实现了
然后重写其中的方法就行了 不需要都实现
2、事件处理
事件处理:
事件(Event):用户对组件的一个操作,称之为一个事件
事件源(Event source) :产生事件的对象
事件处理方法(Event handler) : 能够接收、解析和处理事件类对象、实现和用户交互的方法 ,事件监听器。
为简化编程,针对大多数事件监听器接口定义了相应的实现类----事件适配器类,在适配器类中,实现了相应监听器接口中所有的方法,但不做任何事情。
这里有个主意的地方 降低Frame1和Frame2的耦合度
不想有直接的关联
怎么弄 答案 使用接口
实际上Frame2要把值传给Frame1 需要调用Frame1 但是没有调用
Frame2只是依赖了自己的接口
在Frame2里定义接口设置金额 谁想得到Frame2的金额 那么谁就去实现Frame2的接口
所以Frame1实现了接口
如果有Frame3想得到金额 那么Frame3去实现接口
在Frame2里定义接口
private MoneyListener moneyListener; 这个接口的对象是谁给得
是Frame1给的 Frame1在创建Frame2的时候设置了一个Listener
Frame1把自己实现的接口对象传进来 即Frame1.this
所以Frame2的set方法就能接到MoneyListener
这个MoneyListener实际上就是Frame1 但是从代码上看不是直接写的Frame1 是它的接口
然后用的时候 Frame2自己定义的接口自己用
然后由外部把这个接口对象传进来
这个方法叫接口回调
- 接口回调:
- 当一个对象需要给外部对象提供数据时,我们可以定义一个内部接口把数据通过接口传递出去,
- 所有外部对象需要这个数据时,就实现这个接口,这样的好处是
- 传递数据的对象不直接依赖接收数据的对象(降低耦合性)
第一个界面
package com.vince.gui;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
/**
* Created by vince on 2017/7/5.
*/
public class Frame1 extends Frame implements Frame2.MoneyListener{
private Label label = new Label("金额:");
private Button btn = new Button("购买");
public Frame1(){
this.setSize(400,200);
this.setLayout(new FlowLayout());
this.add(btn);
this.add(label);
btn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
new Frame2().setMoneyListener(Frame1.this);
}
});
this.setVisible(true);
}
@Override
public void setMoney(String money) {
label.setText(money);
}
public static void main(String[] args) {
new Frame1();
}
}
第二个界面
package com.vince.gui;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
/**
* Created by vince on 2017/7/5.
*
* 接口回调:
* 当一个对象需要给外部对象提供数据时,我们可以定义一个内部接口把数据通过接口传递出去,
* 所有外部对象需要这个数据时,就实现这个接口,这样的好处是
* 传递数据的对象不直接依赖接收数据的对象(降低耦合性)
*/
public class Frame2 extends Frame{
private TextField textField = new TextField(20);
private Button btn = new Button("付款");
public Frame2(){
this.setSize(400,200);
this.setLayout(new FlowLayout());
this.add(textField);
this.add(btn);
btn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
String money = textField.getText();
moneyListener.setMoney(money);
}
});
this.setVisible(true);
}
private MoneyListener moneyListener;
public void setMoneyListener(MoneyListener moneyListener) {
this.moneyListener = moneyListener;
}
public static interface MoneyListener{
public void setMoney(String money);
}
}
结果
显示Frame1窗口
点击购买 弹出Frame2
输入100 点击付款 Frame1金额显示100