您的位置 首页 java

深入java核心知识:事件处理中的动作——AWT事件模型,我还能学

动作

通常,激活一个命令可以有多种方式。用户可以通过菜单、击键或工具栏上的按钮选择特定的功能。在AWT事件模型中实现这些非常容易:将所有事件连接到同一个监听器上。例如,假设blueAction是一个动作监听器,它的actionPerformed方法可以将背景颜色改变成蓝色。将一个监听器对象加到下面几个事件源上:

• 标记为“Blue”的工具栏按钮。

• 标记为“Blue”的菜单项。

• 击键CTRL+B。

然后,无论改变背景颜色的命令是通过哪种方式下达的,是点击按钮、菜单选择,还是按下键盘,其操作动作都是一样的。

swing 提供了一种非常实用的机制来封装命令,并将它们连接到多个事件源,这就是Action接口。一个动作是一个封装下列内容的对象:

• 命令的说明(一个文本 字符串 和一个可选图标)。

• 执行命令所需要的参数(例如,在列举的例子中请求改变的颜色)。

Action接口包含下列方法:

 void actionPerformed(ActionEvent event)
void setEnabled(boolean b)
boolean isEnabled( )
void putValue(String key, Object value)
Object getValue(String key)
void addPropertyChangeListener(propertyChangeListener listener)
void removePropertyChangeListener(propertyChangeListener listener)  

第一个方法是ActionListener接口中大家很熟悉的一个:实际上,Action接口扩展于ActionListener接口,因此可以在任何需要ActionListener对象的地方使用Action对象。

接下来的两个方法允许启用或禁用该动作,并检查该动作当前是否启用。当一个连接到菜单或工具栏上的动作被禁用时,这个选项就会变成灰色。

putValue和getvalue方法允许存储和检索动作对象中的任意名/值对。有两个重要的预定义字符串:Action.NAME和Action.SMALL_ICON,用于将动作的名字和图标存储到一个动作对象中:

action.putValue(Action.NAME, “Blue”);

action.putValue(Action.SMALL_ICON, new ImageIcon(“blue-ball.gif”));

表8-3给出了所有预定义的动作表名称。

深入java核心知识:事件处理中的动作——AWT事件模型,我还能学

如果动作对象被添加到菜单或工具栏上,它的名称和图标就会被自动地提取出来,并显示在菜单项或工具栏项中。SHORT_DESCRIPTION值变成了工具提示。

Action接口的最后两个方法能够让其他对象在动作对象的属性发生变化时得到通告,尤其是菜单或工具栏触发的动作。例如,如果增加一个菜单,作为动作对象的属性变更监听器,而这个动作对象随后被禁用,那么菜单就会被调用,并将动作名称变为灰色。属性变更监听器是一种常用的构造形式,它是“JavaBeans”组件模型的一部分。有关这方面更加详细的信息请参阅卷II。

需要注意,Action是一个接口,而不是一个类。实现这个接口的所有类都必须实现刚才讨论的7个方法。庆幸的是,有一个类实现了该接口除actionPerformed方法之外的所有方法,它就是AbstractAction。这个类存储了所有名/值对,并管理着属性变更监听器。我们可以简单地扩展AbstractAction类,并在扩展类中实现actionPerformed方法。

下面构造一个用于执行改变颜色命令的动作对象。首先存储这个命令的名称、图标和需要的颜色。将颜色存储在AsbstractAction类提供的名/值对表中。下面是ColorAction类的代码。 构造器 设置名/值对,而actionPerformed方法执行改变颜色的动作。

深入java核心知识:事件处理中的动作——AWT事件模型,我还能学

在测试程序中,创建了三个这个类的对象,如下所示:

Action blueAction = new ColorAction(“Blue”, new ImageIcon(“blue-ball.gif”), Color.BLUE);

接下来,将这个动作与一个按钮关联起来。由于JButton有一个用Action对象作为参数的构造器,所以实现这项操作很容易。

JButton blueButton = new JButton(blueAction);

构造器读取动作的名称和图标,设置简要说明作为工具提示,将动作设置为监听器。从图8-9中可以看到图标和工具提示。

深入java核心知识:事件处理中的动作——AWT事件模型,我还能学

在下一章中会看到,将这个动作添加到菜单中也非常容易。

最后,想要将这个动作添加到击键中,以便让用户敲击键盘命令来执行这项动作。从现在开始,技术就有些复杂了。击键被传递给拥有焦点的组件。

在我们的示例应用程序由若干组件,即放置在面板内部的三个按钮组成。因此,在任何时刻,三个按钮当中的任何一个都可能会有焦点。每个按钮都需要处理键盘事件,并监听CTRL+Y、CTRL+B和CTRL+R键。

这是一个常见的问题,Swing设计者已经给出了一种很便捷的解决方案。

注意 :在JDK 1.2版本中,将键绑定到动作上有两种不同的实现方案:一种是利用JComponent类的registerKeyboardAction方法;另一种是利用JTextComponent命令的KeyMap概念。在JDK 1.3中,这两种机制统一起来。本节将讲述这种方式。

为了将动作与击键关联起来,首先需要生成KeyStroke类对象。这是一个很有用的类,它封装了对键的说明。要想生成一个KeyStroke对象,不要调用构造器,而是调用KeyStroke类中的静态getKeyStroke方法,并指定虚拟键码和标记(例如,SHIFT和CONTROL键的组合):

KeyStroke ctrlBKey = KeyStroke.getKeyStroke(KeyEvent.VK_B, InputEvent.CTRL_MASK);

除此之外,还可以用字符串对击键进行描述:

KeyStroke ctrlBKey = keyStroke.getKeyStroke(“ctrl B”);

每个JComponent有三个输入映射(imput map),每一个映射的KeyStroke对象都与动作关联。

三个输入映射对应着三个不同的条件(请参阅表8-4)。

击键处理将按照下列顺序检查这些映射:

1)检查具有输入焦点组件的WHEN_FOCUSED映射。如果这个击键存在,将执行对应的动作。

如果动作已启用,则停止处理。

2)从具有输入焦点的组件开始,检查其父组件的WHEN_ANCESTOR_OF_FOCUSED_COMPONENT

映射。一旦找到击键对应的映射,就执行对应的动作。如果动作已启用,将停止处理。

3)查看具有输入焦点的窗口中的所有可视的和启用的组件,这个击键被注册到WHEN_IN_FOCUSED_WINDOW映射中。给这些组件(按照击键注册的顺序)一个执行对应动作的机会。一旦第一个启用的动作被执行,就停止处理。如果一个击键在多个WHEN_IN_FOCUSED_WINDOW映射中出现,这部分处理就可能会出现问题。

深入java核心知识:事件处理中的动作——AWT事件模型,我还能学

可以使用getInputMap方法从组件中得到输入映射。例如:

InputMap imap = panel.getInputMap(JComponent.WHEN_FOCUSED);

WHEN_FOCUSED条件意味着在当前组件拥有键盘焦点时,会查看这个映射。在我们列举的例子中,并不想使用这个映射。是某个按钮拥有输入焦点,而不是面板。其他的两个映射都能够很好地完成增加颜色改变击键的任务。在我们的例子程序中使用的是WHEN_ANCESTOR_OF_FOCUSED_COMPONENT。

InputMap不能直接地将KeyStroke对象映射到Action对象。而是先映射到任意对象上,然后由ActionMap类实现将对象映射到动作上的第2个映射。这样很容易实现来自不同输入映射的击键共享一个动作的目的。

因而,每个组件都可以有三个输入映射和一个动作映射。为了将它们组合起来,需要为动作命名。下面是将键与动作关联起来的方式:

imap.put(KeyStroke.getKeyStroke(“ctrl Y”), “panel.yellow”);

ActionMap amap = panel.getActionMap( );

amap.put(“panel.yellow”, yellowAction);

习惯上,使用字符串“none”表示空动作。这样可以轻松地取消一个键动作:

imap.put(KeyStroke.getKeyStroke(“ctrl C”), “none”);

警告 :JDK文档提倡使用动作名作为动作键。我们并不认为这是一种好建议。对于在按钮和菜单项上显示的动作名,UI设计者可以随心所欲地改变它,也可以将它们翻译成多种语言。使用这种不牢靠的字符串作为查询键不是一种好的选择。

我们建议将动作名与显示的名字分开。

下面总结一下用同一个动作响应按钮、菜单项或击键的方式:

1)实现一个扩展于AbstractAction类的类。多个相关的动作可以使用同一个类。

2)构造一个动作类的对象。

3)使用动作对象创建按钮或菜单项。构造器将从动作对象中读取标签文本和图标。

4)为了能够通过击键触发动作,必须额外地执行几步操作。首先定位顶层窗口组件,例如,包含所有其他组件的面板。

5)然后,得到顶层组件的WHEN_ANCESTOR_OF_FOCUS_COMPONENT输入映射。为需要的击键创建一个KeyStrike对象。创建一个描述动作字符串这样的动作键对象。将(击键,动作键)对添加到输入映射中。

6)最后,得到顶层组件的动作映射。将(动作键,动作对象)添加到映射中。

例8-5给出了将按钮和击键映射到动作对象的完整程序代码。试试看,点击按钮或按下

CTRL+Y、CTRL+B或CTRL+R来改变面板颜色。

例8-5 ActionTest.java

深入java核心知识:事件处理中的动作——AWT事件模型,我还能学

深入java核心知识:事件处理中的动作——AWT事件模型,我还能学

深入java核心知识:事件处理中的动作——AWT事件模型,我还能学

javax.swing.Action 1.2

• void setEnabled(boolean b)

启用或禁用这个动作。

• boolean isEnabled( )

如果这个动作被启用,返回true。

• void putValue(String key, Object value)

将名/值对放置在动作对象内。

参数:key 用动作对象存储性能的名字。它可以是一个字符串,但预定义了几个名字,其含义参阅表8-3

value 与名字关联的对象

• Object getValue(String key)

返回被存储的名/值对的值。

javax.swing.JMenu 1.2

• JMenuItem add(Action a)

将一个菜单项添加到菜单中,当选择这个菜单项时将调用动作a,并返回被添加的菜单项。

javax.swing.KeySTroke 1.2

• static KeyStroke getKeyStroke (char keyChar)

创建一个KeyStroke对象,它封装了对应KEY_TYPED事件的一个击键。

• static keyStroke getKeyStroke(int keyCode, int modifiers)

• static keyStroke getKeyStroke(int keyCode, int modifiers, boolean onRelease)

创建一个KeyStroke对象,它封装了对应KEY_PRESSED或KEY_RELEASED事件的一个击键。

参数:keyCode 虚拟键码

modifiers 下列常量的任意组合:InputEvent.SHIFT_MASK、InputEvent.CTRL_MASK、

InputEvent.ATL_MASK、InputEvent.META_MASK

onRelease

当键被释放时,如果击键被识别,则返回true

• static keyStroke getKeyStroke(String description)

根据一个说明性描述构造击键。说明性描述是由空白符分隔的字符串序列,其格式如下所示:

1)字符串shift control ctrl meta alt button1 button2 button3转换为相应的掩码位。

2)字符串typed必须紧跟一个只有一个字符的字符串,例如,”typed a”。

3)字符串pressed或released表示按下一个键或释放一个键。(按下键是默认情况。)

4)否则,前缀为VK_的字符串对应一个KeyEvent常量,例如,”INSERT”对应KeyEvent.VK_INSERT。

例如,”released ctrl Y”对应getKeyStroke(KeyEvent.VK_Y, Event.CTRL_MASK, true)。

javax.swing.JComponent 1.2

•ActionMap getActionMap( ) 1.3

返回将击键映射到动作键的动作映射。

• InputMap getInputMap(int flag) 1.3

得到将动作键映射到动作对象的输入映射。

参数:flag 触发动作的键盘焦点条件。具体的值请参阅表8-4

觉得文章不错的话,可以转发关注小编一下!!

明天更新多点传送和实现事件源的内容,欢迎大家来围观~~~~~~~~

文章来源:智云一二三科技

文章标题:深入java核心知识:事件处理中的动作——AWT事件模型,我还能学

文章地址:https://www.zhihuclub.com/186370.shtml

关于作者: 智云科技

热门文章

网站地图