1、GUI组件介绍

GUI编程(Graphic User Interface, 图形用户接口)

GUI的各种元素, 如: 容器、 按钮、 文本框等

18、GUI事件处理 - 图1


2、事件处理

事件(Event): 用户对组件的一个操作, 称之为一个事件

事件源(Event source) : 产生事件的对象

事件处理方法(Event handler) : 能够接收、 解析和处理事件类对象、 实现和用户交互的方法 , 事件监听器。

为简化编程, 针对大多数事件监听器接口定义了相应的实现类——事件适配器类, 在适配器类中,实现了相应监听器接口中所有的方法, 但不做任何事情

MyFrame

  1. package com.vince.gui;
  2. import java.awt.*;
  3. import java.awt.event.*;
  4. /**
  5. */
  6. public class MyFrame extends Frame implements ActionListener{
  7. /**
  8. * 初始化窗体的基本属性
  9. */
  10. public MyFrame(){
  11. this.setSize(600,400);
  12. this.setTitle("我的第一个GUI窗体");
  13. //创建一个按钮
  14. Button button = new Button("点我一下,有惊喜");
  15. //给按钮添加单击事件
  16. button.addActionListener(this);
  17. //创建一个线性布局
  18. FlowLayout flowLayout = new FlowLayout();
  19. //把布局应用到窗体上
  20. this.setLayout(flowLayout);
  21. //给窗体添加关闭事件
  22. this.addWindowListener(new WindowAdapter() {
  23. @Override
  24. public void windowClosing(WindowEvent e) {
  25. super.windowClosing(e);
  26. System.exit(0);
  27. }
  28. });
  29. //把按钮添加到窗体上
  30. this.add(button);
  31. this.setVisible(true);
  32. }
  33. //单击事件处理的方法
  34. @Override
  35. public void actionPerformed(ActionEvent e) {
  36. System.out.println("惊喜来了");
  37. }
  38. public static void main(String[] args) {
  39. new MyFrame();
  40. }
  41. }

Frame1

  1. package com.vince.gui;
  2. import java.awt.*;
  3. import java.awt.event.ActionEvent;
  4. import java.awt.event.ActionListener;
  5. /**
  6. */
  7. public class Frame1 extends Frame implements Frame2.MoneyListener{
  8. private Label label = new Label("金额:");
  9. private Button btn = new Button("购买");
  10. public Frame1(){
  11. this.setSize(400,200);
  12. this.setLayout(new FlowLayout());
  13. this.add(btn);
  14. this.add(label);
  15. btn.addActionListener(new ActionListener() {
  16. @Override
  17. public void actionPerformed(ActionEvent e) {
  18. new Frame2().setMoneyListener(Frame1.this);
  19. }
  20. });
  21. this.setVisible(true);
  22. }
  23. @Override
  24. public void setMoney(String money) {
  25. label.setText(money);
  26. }
  27. public static void main(String[] args) {
  28. new Frame1();
  29. }
  30. }

Frame2

  1. package com.vince.gui;
  2. import java.awt.*;
  3. import java.awt.event.ActionEvent;
  4. import java.awt.event.ActionListener;
  5. /**
  6. *
  7. * 接口回调:
  8. * 当一个对象需要给外部对象提供数据时,我们可以定义一个内部接口把数据通过接口传递出去,
  9. * 所有外部对象需要这个数据时,就实现这个接口,这样的好处是
  10. * 传递数据的对象不直接依赖接收数据的对象(降低耦合性)
  11. */
  12. public class Frame2 extends Frame{
  13. private TextField textField = new TextField(20);
  14. private Button btn = new Button("付款");
  15. public Frame2(){
  16. this.setSize(400,200);
  17. this.setLayout(new FlowLayout());
  18. this.add(textField);
  19. this.add(btn);
  20. btn.addActionListener(new ActionListener() {
  21. @Override
  22. public void actionPerformed(ActionEvent e) {
  23. String money = textField.getText();
  24. moneyListener.setMoney(money);
  25. }
  26. });
  27. this.setVisible(true);
  28. }
  29. private MoneyListener moneyListener;
  30. public void setMoneyListener(MoneyListener moneyListener) {
  31. this.moneyListener = moneyListener;
  32. }
  33. public static interface MoneyListener{
  34. public void setMoney(String money);
  35. }
  36. }

3、观察者模式

1、 观察者模式原理

观察者模式定义: 简单地说, 观察者模式定义了一个一对多的依赖关系, 让一个或多个观察者对象监察一个主题对象。 这样一个主题对象在状态上的变化能够通知所有的依赖于此对象的那些观察者对象, 使这些观察者对象能够自动更新

2、 观察者模式实现

Subject( 被观察的对象接口)
规定ConcreteSubject的统一接口;
每个Subject可以有多个Observer;

ConcreteSubject( 具体被观察对象)
维护对所有具体观察者的引用的列表;
状态发生变化时会发送通知给所有注册的观察者。

Observer( 观察者接口)
规定ConcreteObserver的统一接口;
定义了一个update()方法,
在被观察对象状态改变时会被调用。

ConcreteObserver( 具体观察者)
维护一个对ConcreteSubject的引用;
特定状态与ConcreteSubject同步;
实现Observer接口, 通过update()方法
接收ConcreteSubject的通知。

18、GUI事件处理 - 图2

3、 观察者模式作用

观察者模式在被观察者和观察者之间建立一个抽象的耦合。 被观察者角色所知道的只是一个具
体观察者列表。

由于被观察者和观察者没有紧密地耦合在一起, 因此它们可以属于不同的抽象化层次。 如果被
观察者和观察者都被扔到一起, 那么这个对象必然跨越抽象化和具体化层次。

观察者模式支持广播通讯。 被观察者会向所有的登记过的观察者发出通知。


MessageSubject

  1. package com.vince.gui.abserver;
  2. /**
  3. * 被观察者的接口
  4. */
  5. public interface MessageSubject {
  6. //注册观察者
  7. public void registerObserver(Observer o);
  8. //移除观察者
  9. public void removeObserver(Observer o);
  10. //通知所有观察者
  11. public void notifyObservers();
  12. }

Observer

  1. package com.vince.gui.abserver;
  2. /**
  3. * 观察者接口
  4. */
  5. public interface Observer {
  6. //更新消息
  7. public void update(String message);
  8. }

Message

  1. package com.vince.gui.abserver;
  2. import java.util.ArrayList;
  3. import java.util.List;
  4. /**
  5. * 具体的被观察者
  6. */
  7. public class Message implements MessageSubject{
  8. //维护的观察者列表
  9. private List<Observer> list = new ArrayList<>();
  10. private String message;
  11. public void setMessage(String message) {
  12. this.message = message;
  13. notifyObservers();
  14. }
  15. @Override
  16. public void registerObserver(Observer o) {
  17. list.add(o);
  18. }
  19. @Override
  20. public void removeObserver(Observer o) {
  21. list.remove(o);
  22. }
  23. @Override
  24. public void notifyObservers() {
  25. for (int i=0;i<list.size();i++){
  26. Observer observer = list.get(i);
  27. observer.update(message);
  28. }
  29. }
  30. }

User

  1. package com.vince.gui.abserver;
  2. /**
  3. * 具体的观察者
  4. */
  5. public class User implements Observer {
  6. private String name;
  7. public User(String name){
  8. this.name = name;
  9. }
  10. @Override
  11. public void update(String message) {
  12. System.out.println("["+name+"]收到消息:"+message);
  13. }
  14. }

TestDemo

  1. package com.vince.gui.abserver;
  2. import org.junit.Test;
  3. /**
  4. */
  5. public class TestDemo {
  6. @Test
  7. public void testObserver(){
  8. Message message = new Message();
  9. Observer user1 = new User("lily");
  10. Observer user2 = new User("tom");
  11. Observer user3 = new User("vince");
  12. message.registerObserver(user1);
  13. message.registerObserver(user2);
  14. message.registerObserver(user3);
  15. message.setMessage("亲们,么么哒");
  16. message.removeObserver(user1);
  17. message.setMessage("有在的吗,我要发红包啦");
  18. }
  19. }