# 如何编写动作侦听器

> 原文： [https://docs.oracle.com/javase/tutorial/uiswing/events/actionlistener.html](https://docs.oracle.com/javase/tutorial/uiswing/events/actionlistener.html)

动作侦听器可能是最容易实现的 - 也是最常见的 - 事件处理程序。您可以实现一个动作侦听器来定义用户执行某些操作时应该执行的操作。

只要用户执行了某个操作，就会发生操作事件。示例：当用户单击[按钮](../components/button.html)时，选择[菜单项](../components/menu.html)，在[文本字段](../components/textfield.html)中按 Enter 键。结果是`actionPerformed`消息被发送到在相关组件上注册的所有动作侦听器。

要编写动作侦听器，请按照以下步骤操作：

1.  声明一个事件处理程序类，并指定该类实现 ActionListener 接口或扩展实现 ActionListener 接口的类。例如：

    ```
    public class MyClass implements ActionListener { 

    ```

2.  将事件处理程序类的实例注册为一个或多个组件上的侦听器。例如：

    ```
    someComponent.addActionListener(instanceOfMyClass);

    ```

3.  包含在侦听器接口中实现方法的代码。例如：

    ```
    public void actionPerformed(ActionEvent e) { 
        ...//code that reacts to the action... 
    }

    ```

通常，要检测用户何时单击屏幕上的按钮（或等效的键盘），程序必须具有实现 ActionListener 接口的对象。程序必须使用 addActionListener 方法将此对象注册为按钮（事件源）上的动作侦听器。当用户单击屏幕上的按钮时，该按钮将触发一个动作事件。这导致调用动作侦听器的 actionPerformed 方法（ActionListener 接口中唯一的方法）。该方法的单个参数是一个 ActionEvent 对象，它提供有关事件及其来源的信息。

让我们编写一个简单的程序，显示用户点击按钮的次数。首先，这是设置 TextField，button 和 numClicks 变量的代码：

```
public class AL extends Frame implements WindowListener,ActionListener {
TextField text = new TextField(20);
Button b;
private int numClicks = 0;

```

在上面的示例中，事件处理程序类是 AL，它实现了 ActionListener。

我们想处理按钮单击事件，因此我们向按钮 b 添加一个动作侦听器，如下所示：

```
b = new Button("Click me");
b.addActionListener(this); 

```

在上面的代码中，Button b 是一个组件，在该组件上注册了事件处理程序类 AL 的实例。

现在，我们要显示用户单击按钮的次数的文本。我们可以通过编写如下代码来完成此操作：

```
public void actionPerformed(ActionEvent e) {
         numClicks++;
         text.setText("Button Clicked " + numClicks + " times");

```

现在，当用户单击 Button b 时，该按钮将触发一个动作事件，该事件将调用动作侦听器的 actionPerformed 方法。每次用户按下按钮时，都会附加 numClicks 变量，并在文本字段中显示消息。

这是完整的程序（AL.java）：

```
import java.awt.*;
import java.awt.event.*;

public class AL extends Frame implements WindowListener,ActionListener {
        TextField text = new TextField(20);
        Button b;
        private int numClicks = 0;

        public static void main(String[] args) {
                AL myWindow = new AL("My first window");
                myWindow.setSize(350,100);
                myWindow.setVisible(true);
        }

        public AL(String title) {

                super(title);
                setLayout(new FlowLayout());
                addWindowListener(this);
                b = new Button("Click me");
                add(b);
                add(text);
                b.addActionListener(this);
        }

        public void actionPerformed(ActionEvent e) {
                numClicks++;
                text.setText("Button Clicked " + numClicks + " times");
        }

        public void windowClosing(WindowEvent e) {
                dispose();
                System.exit(0);
        }

        public void windowOpened(WindowEvent e) {}
        public void windowActivated(WindowEvent e) {}
        public void windowIconified(WindowEvent e) {}
        public void windowDeiconified(WindowEvent e) {}
        public void windowDeactivated(WindowEvent e) {}
        public void windowClosed(WindowEvent e) {}

}

```

更多示例：`Beeper`程序示例可在此跟踪事件简介[事件监听器简介](intro.html)中找到。您可以在 [`Beeper.java`](../examples/events/BeeperProject/src/events/Beeper.java) 中找到整个程序。该部分中描述的另一个例子 [`MultiListener.java`](../examples/events/MultiListenerProject/src/events/MultiListener.java) 有两个动作源和两个动作监听器，一个监听器监听两个源，另一个监听一个监听器。

_ 因为`ActionListener`只有一个方法，所以它没有相应的适配器类。_

| 方法 | 目的 |
| :-- | :-- |
| [actionPerformed（actionEvent）](https://docs.oracle.com/javase/8/docs/api/java/awt/event/ActionListener.html#actionPerformed-java.awt.event.ActionEvent-) | 在用户执行操作后调用。 |

| 方法 | 目的 |
| :-- | :-- |
| [String getActionCommand（）](https://docs.oracle.com/javase/8/docs/api/java/awt/event/ActionEvent.html#getActionCommand--) | 返回与此操作关联的字符串。大多数可以触发动作事件的对象都支持一个名为`setActionCommand`的方法，可以让你设置这个字符串。 |
| [int getModifiers（）](https://docs.oracle.com/javase/8/docs/api/java/awt/event/ActionEvent.html#getModifiers--) | 返回一个整数，表示操作事件发生时用户按下的修饰键。您可以使用`ActionEvent`定义的常量`SHIFT_MASK`，`CTRL_MASK`，`META_MASK`和`ALT_MASK`来确定按下了哪些键。例如，如果用户按住 Shift 键选择菜单项，则以下表达式为非零：

```
actionEvent.getModifiers() & ActionEvent.SHIFT_MASK

```

 |
| [对象 getSource（）](https://docs.oracle.com/javase/8/docs/api/java/util/EventObject.html#getSource--)
（`java.util.EventObject` 中的 _）_ | 返回触发事件的对象。 |

下表列出了一些使用动作侦听器的示例。

| 例 | 在哪里描述 | 笔记 |
| :-- | :-- | :-- |
| [`Beeper`](../examples/events/index.html#Beeper) | 本节和[事件监听器简介](intro.html) | 包含一个带有一个动作侦听器的按钮，单击该按钮时会发出蜂鸣声。 |
| [`MultiListener`](../examples/events/index.html#MultiListener) | [事件监听器简介](intro.html) | 在一个按钮上注册两个不同的动作侦听器。还在两个不同的按钮上注册相同的动作侦听器。 |
| [`RadioButtonDemo`](../examples/components/index.html#RadioButtonDemo) | [如何使用单选按钮](../components/button.html#radiobutton) | 在五个单选按钮上注册相同的动作侦听器。侦听器使用`getActionCommand`方法确定触发事件的单选按钮。 |
| [`MenuDemo`](../examples/components/index.html#MenuDemo) | [如何使用菜单](../components/menu.html) | 显示如何在菜单项上侦听操作事件。 |
| [`TextDemo`](../examples/components/index.html#TextDemo) | [如何使用文本字段](../components/textfield.html) | 在文本字段上注册动作侦听器的 applet。 |
| [`IconDemo`](../examples/components/index.html#IconDemo) | [如何使用图标](../components/icon.html) | 在动作侦听器中加载图像。因为加载图像可能需要一段时间，所以此程序使用`SwingWorker`在后台线程中加载图像。 |
| [`TableDialogEditDemo`](../examples/components/index.html#TableDialogEditDemo) | [如何使用表格](../components/table.html) | 通过颜色选择器对话框的“确定”按钮上的工厂方法注册动作侦听器。 |
| [`SliderDemo`](../examples/components/index.html#SliderDemo) | [如何使用滑块](../components/slider.html) | 在控制动画循环的计时器上注册动作侦听器。 |