本教程针对 JDK 8 编写。本页面中描述的示例和实践不利用后续版本引入的改进,并可能使用不再可用的技术。
有关 Java SE 9 及后续版本中更新的语言特性的概述,请参阅Java 语言更改。
有关所有 JDK 发行版的新功能、增强功能和已删除或不推荐选项的信息,请参阅JDK 发行说明。
一个Action
可以用来将功能和状态与组件分离。例如,如果您有两个或更多执行相同功能的组件,请考虑使用Action
对象来实现该功能。Action
对象是一个动作监听器,它不仅提供了动作事件处理,还提供了对动作事件触发组件(如工具栏按钮、菜单项、常见按钮和文本字段)状态的集中处理。动作可以处理的状态包括文本、图标、助记符、启用状态和选中状态。
通常使用setAction
方法将一个动作附加到组件上。当在组件上调用setAction
时会发生以下情况:
Action
的状态相匹配。例如,如果设置了Action
的文本和图标值,组件的文本和图标将设置为这些值。Action
对象被注册为组件的动作监听器。Action
的状态发生变化,组件的状态会更新以与Action
相匹配。例如,如果更改了动作的启用状态,所有附加到它的组件的启用状态都会与该动作匹配。下面是创建执行相同功能的工具栏按钮和菜单项的示例:
Action leftAction = new LeftAction(); //LeftAction代码稍后会显示 ... button = new JButton(leftAction) ... menuItem = new JMenuItem(leftAction);
要创建Action
对象,通常创建一个AbstractAction
的子类,然后实例化它。在子类中,您必须实现actionPerformed
方法,以在发生动作事件时适当地作出反应。下面是创建和实例化AbstractAction
子类的示例:
leftAction = new LeftAction("Go left", anIcon, "This is the left button.", new Integer(KeyEvent.VK_L)); ... class LeftAction extends AbstractAction { public LeftAction(String text, ImageIcon icon, String desc, Integer mnemonic) { super(text, icon); putValue(SHORT_DESCRIPTION, desc); putValue(MNEMONIC_KEY, mnemonic); } public void actionPerformed(ActionEvent e) { displayResult("Action for first button/menu item", e); } }
当上述代码创建的动作附加到按钮和菜单项时,按钮和菜单项将显示与动作相关联的文本和图标。按钮和菜单项上使用L
字符作为助记符,并将其工具提示文本设置为SHORT_DESCRIPTION
字符串,后跟助记键的表示。
例如,我们提供了一个简单的示例,ActionDemo.java
,定义了三个动作。每个动作都附加到一个按钮和一个菜单项。由于为每个按钮的动作设置了助记值,按下键序列Alt-L
激活左按钮,Alt-M
激活中间按钮,Alt-R
激活右按钮。左按钮的工具提示显示这是左按钮。Alt-L。所有这些配置都是自动进行的,程序不需要显式调用设置助记符或工具提示文本的方法。正如我们将在后面展示的,程序确实调用了设置按钮文本的方法,但只是为了避免使用动作已经设置的值。
点击"Launch"按钮使用Java™ Web Start运行ActionDemo (下载JDK 7或更高版本)。或者,如果要编译和运行示例,请参考示例索引。
从左侧菜单中选择顶部项 (Menu > Go left)。
文本区域显示了一些文本,标识了事件源和接收事件的动作监听器。
点击工具栏中最左边的按钮。
文本区域再次显示了有关事件的信息。请注意,尽管事件的源不同,但两个事件都被同一个动作监听器检测到:附加到组件的Action
对象。
选择Action State菜单中的顶部项。
这将禁用"Go left"的Action
对象,进而禁用其关联的菜单项和按钮。
当"Go left"操作被禁用时,用户所见如下:
|
|
禁用"Go left"操作的代码如下:
boolean selected = ...//如果操作应该启用,则为true;否则为false leftAction.setEnabled(selected);
在使用Action
创建组件后,您可能需要进行自定义。例如,您可能希望通过添加或删除图标或文本来自定义其中一个组件的外观。例如,ActionDemo.java
的菜单中没有图标,按钮中也没有文本。下面的代码实现了这一点:
menuItem = new JMenuItem(); menuItem.setAction(leftAction); menuItem.setIcon(null); //在菜单中不使用图标 ... button = new JButton(); button.setAction(leftAction); button.setText(""); //仅有图标的按钮
我们选择通过将图标属性设置为null
,将文本设置为空字符串,从而从同一个操作创建一个仅有图标的按钮和仅有文本的菜单项。然而,如果Action
的属性发生更改,部件可能会尝试再次从Action
中重置图标和文本。
以下表格列出了常用的Action
构造函数和方法。使用Action
对象的API分为三个类别:
类 | 用途 |
---|---|
AbstractButton JComboBox JTextField |
这些组件及其子类可以通过setAction 直接分配一个动作。有关通常与动作相关联的组件的详细信息,请参阅关于工具栏按钮、菜单项、常见按钮和文本字段的部分。有关每个组件从Action 中获取的属性的详细信息,请参阅相关类的API文档中的configurePropertiesFromAction 方法。还请参阅buttonActions 表。 |
构造函数或方法 | 目的 |
---|---|
AbstractAction() AbstractAction(String) AbstractAction(String, Icon) |
创建一个Action 对象。通过参数,可以指定在附加了该动作的组件中使用的文本和图标。 |
void setEnabled(boolean) boolean isEnabled() |
设置或获取动作控制的组件是否启用。调用setEnabled(false) 禁用所有由该动作控制的组件。类似地,调用setEnabled(true) 启用该动作的组件。 |
void putValue(String, Object) Object getValue(String) |
设置或获取与指定键关联的对象。用于设置和获取与动作关联的属性。 |
此表定义了可以在动作上设置的属性。第二列列出了自动使用这些属性的组件(以及具体调用的方法)。例如,将ACCELERATOR_KEY
设置在附加到菜单项的动作上,意味着会自动调用JMenuItem.setAccelerator(KeyStroke)
。
属性 | 自动应用于: 类 (方法调用) |
目的 |
---|---|---|
ACCELERATOR_KEY | JMenuItem (setAccelerator) |
用作操作的加速器的KeyStroke 。有关加速器与助记符的讨论,请参见启用键盘操作。 |
ACTION_COMMAND_KEY | AbstractButton , JCheckBox , JRadioButton (setActionCommand) |
ActionEvent 相关联的命令字符串。 |
LONG_DESCRIPTION | 无 | 操作的更长描述。可用于上下文相关帮助。 |
MNEMONIC_KEY | AbstractButton , JMenuItem , JCheckBox , JRadioButton (setMnemonic) |
操作的助记符。有关加速器与助记符的讨论,请参见启用键盘操作。 |
NAME | AbstractButton , JMenuItem , JCheckBox , JRadioButton (setText) |
操作的名称。您可以在创建操作时使用AbstractAction(String) 或AbstractAction(String, Icon) 构造函数设置此属性。 |
SHORT_DESCRIPTION | AbstractButton , JCheckBox , JRadioButton (setToolTipText) |
操作的简短描述。 |
SMALL_ICON | AbstractButton , JMenuItem (setIcon) |
工具栏或按钮上使用的操作图标。您可以在创建操作时使用AbstractAction(name, icon) 构造函数设置此属性。 |
以下示例使用Action
对象。
示例 | 描述位置 | 注释 |
---|---|---|
ActionDemo |
本节 | 使用actions将按钮和菜单项绑定到相同的函数。 |
TextComponentDemo |
文本组件特性 | 使用文本actions创建文本编辑命令的菜单项,例如剪切、复制和粘贴,并将键盘快捷键绑定到光标移动。还实现自定义的AbstractAction 子类来实现撤销和重做。文本action的讨论在概念:关于编辑器工具包中开始。 |