AWT事件处理机制

任何支持GUI的操作系统都要不断的监视敲击键盘或点击鼠标这样的事件。操作系统将这些事件报告给正在运行的应用程序。那么如果这个程序是用Java写的,那么Java是如何做出反应的呢?

我们都知道Swing的出现使得Java图形用户界面开始真正有意义起来。但这并不代表AWT过时了,没用了。恰恰相反,Swing仅仅提供了强大的,可移植的,高效的用户界面组件(比如JButton),但要实现相应用户动作的业务逻辑,还需要使用基本的A WT事件处理机制

AWT的事件处理机制,实际上是一种委托模型 。比如按钮,当我们发出点击按钮的动作之后,真正响应事件的业务逻辑并非按钮本身,而是由按钮委托的相应监听器来完成的。在深入探讨这个过程之前,我们先看看三个比较重要的概念:

(1) 事件(event)
    我们都知道,点击鼠标的动作会产生一个事件。像Java这样面向对象的语言,会将事件的相关信息封装在一个事件对象中,这就是ActionEvent类。
    实际上,ActionEvent类不光是点击按钮,如果其它组件发生了与组件定义的动作相关的语义事件时,也会产生ActionEvent对象,比如时钟Timer类发生定时性动作时。
    另外还有很多其他的事件类,如组件被移动、大小被更改或可见性被更改的事件——ComponentEvent等。
    这些事件类都继承了java.awt.AWTEvent,而这个类又直接继承java.util.EventObject。

(2) 事件源(event source)
    顾名思义,就是发生事件的组件,比如说按钮Button就是一个事件源,他可以发生ActionEvent这样的事件。这些事件源类型的父类就是Component。

(3) 事件监听器(event listener)
    这是一些相应事件,并完成相应逻辑功能的对象。
    比如点击按钮,产生了一个ActionEvent对象,但需要完成相应的业务逻辑。必须使用到ActionListener监听器。但要注意ActionListener并不是类,而是接口,不同的业务逻辑要封装在完成ActionListener接口的不同类中。
    这些监听器接口都继承了接口java.util EventListener 。

 

当我们鼠标点击Button按钮时,发生了什么呢?我们来解析一下Button按钮中的一些重要方法源码。

Java代码
  1.     //1、当按下按钮并释放时,执行按钮上的这个操作,并产生一个ActionEvent事件   
  2.      public boolean doAccessibleAction(int i) {   
  3.            if (i == 0) {   
  4.                // 模拟按钮点击   
  5.                 Toolkit.getEventQueue().postEvent(   
  6.                        new ActionEvent(Button.this,   
  7.                                         ActionEvent.ACTION_PERFORMED,   
  8.                                         Button.this.getActionCommand()));   
  9.                return true;   
  10.             } else {   
  11.                return false;   
  12.             }   
  13.         }   
  14.   
  15.      //2、当按下按钮并释放时,AWT 通过调用按钮的 processEvent,将产生的ActionEvent事件发送给按钮处理。   
  16. protected void processEvent(AWTEvent e) {   
  17.         //注意,如果事件是ActionEvent类型或其子类,则会调用processActionEvent()方法。   
  18.     if (e instanceof ActionEvent) {   
  19.          processActionEvent((ActionEvent)e);   
  20.         return;   
  21.      }   
  22.     super.processEvent(e);   
  23.         }   
  24.   
  25. //3、调用监听器的actionPerformed方法   
  26. protected void processActionEvent(ActionEvent e) {   
  27.      ActionListener listener = actionListener;   
  28.     if (listener != null) {   
  29.          listener.actionPerformed(e);  //真正执行响应后的业务逻辑的是监听器。   
  30.      }   
  31.         }  
     //1、当按下按钮并释放时,执行按钮上的这个操作,并产生一个ActionEvent事件
      public boolean doAccessibleAction(int i) {
            if (i == 0) {
                // 模拟按钮点击
                Toolkit.getEventQueue().postEvent(
                        new ActionEvent(Button.this,
                                        ActionEvent.ACTION_PERFORMED,
                                        Button.this.getActionCommand()));
                return true;
            } else {
                return false;
            }
        }

      //2、当按下按钮并释放时,AWT 通过调用按钮的 processEvent,将产生的ActionEvent事件发送给按钮处理。
 protected void processEvent(AWTEvent e) {
         //注意,如果事件是ActionEvent类型或其子类,则会调用processActionEvent()方法。
  if (e instanceof ActionEvent) {
      processActionEvent((ActionEvent)e);
      return;
  }
  super.processEvent(e);
        }
  
 //3、调用监听器的actionPerformed方法
 protected void processActionEvent(ActionEvent e) {
  ActionListener listener = actionListener;
  if (listener != null) {
      listener.actionPerformed(e);  //真正执行响应后的业务逻辑的是监听器。
  }
        }

通过这三个源码,我们可以看到AWT的事件相应机制是这样完成的:
(1) 由事件源(Button)产生一个与动作(按下按钮并释放)相适应的ActionEvent事件。
(2) 事件源会将这个ActionEvent事件发送给监听器,并执行监听器的actionPerformed(e)方法来完成事件响应。

 

可事件源是如何知道由哪一个监听器来完成呢。这是我们必须为事件源指定某一个监听器,依然看看Button中的源代码:

Java代码
  1. public class Button extends Component implements Accessible {   
  2.     // 按钮中的监听器对象   
  3.     transient ActionListener actionListener;   
  4.     // 注册指定的监听器   
  5.     public synchronized void addActionListener(ActionListener l) {   
  6.     if (l == null) {   
  7.         return;   
  8.      }   
  9.      actionListener = AWTEventMulticaster.add(actionListener, l);   
  10.          newEventsOnly = true;   
  11.      }   
  12. }  
public class Button extends Component implements Accessible {
    // 按钮中的监听器对象
    transient ActionListener actionListener;
    // 注册指定的监听器
    public synchronized void addActionListener(ActionListener l) {
 if (l == null) {
     return;
 }
 actionListener = AWTEventMulticaster.add(actionListener, l);
        newEventsOnly = true;
    }
}

现在很明白了,只要向按钮注册指定的监听器就OK了。

综上所述,AWT事件处理机制概要如下:
(1) 将响应事件所需要的业务逻辑封装在实现监听器接口的类中。
   
Class ClickAction implements ActionListener{
          public void actionPerformed(ActionEvent e){
              // ....more work to do.
      }
    }

(2) 创建事件源并注册完成所需业务逻辑的监听器。
   
ActionListener click=new ClickAction();
    Button btn=new Button();
    btn.addActionListener(click);

(3) 当事件发生时,事件源就会像上面所说的将事件对象传递给所有注册的监听器。

(4) 接着调用监听器的actionPerformed方法来完成事件响应。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java AWT(Abstract Window Toolkit)提供了一套GUI组件,它们可以用来创建用户界面。在AWT中,事件处理的核心是事件机制,其基本的原理是事件源生成一个事件对象,并将此事件对象传递给事件监听器进行处理。AWT事件机制包括事件源、事件对象、事件监听器和事件处理器四个部分。其中,事件源指用户操作的组件,如按钮、文本框等;事件对象则是被传递的事件;事件监听器则是对事件的响应处理;而事件处理器则是负责实现特定事件处理的方法。具体来说,当一个组件被触发时,它就会产生相应的事件,并将该事件传递给监听器进行处理。 在AWT中,布局管理器用于控制组件在容器中的位置和大小。常见的布局管理器有FlowLayout、BorderLayout、GridLayout和CardLayout等。下面是一个使用BorderLayout布局管理器的AWT程序示例代码: ``` import java.awt.*; public class AWTExample extends Frame { private Button btn1, btn2, btn3, btn4, btn5; public AWTExample() { setLayout(new BorderLayout()); btn1 = new Button("Button 1"); btn2 = new Button("Button 2"); btn3 = new Button("Button 3"); btn4 = new Button("Button 4"); btn5 = new Button("Button 5"); add(btn1, BorderLayout.NORTH); add(btn2, BorderLayout.SOUTH); add(btn3, BorderLayout.EAST); add(btn4, BorderLayout.WEST); add(btn5, BorderLayout.CENTER); setSize(300, 300); setVisible(true); } public static void main(String[] args) { new AWTExample(); } } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值