副标题#e#
在java Swing编程进程中,常常需要处理惩罚键盘事件,譬喻处理惩罚快捷键等。这里就先容如何界说键盘事件,以及如那里理惩罚这些事件。
在jdk1.2中,别离针对Jcomponent和Text类的工具定制了差异的处理惩罚键盘事件的要领:在Jcomponent中,界说了registerKeyboardAction要领,利用这个要领来将需要处理惩罚的键盘事件以及处理惩罚事件的行为绑定在一起。Text类中具有keymap工具,同Jcomponent中的处理惩罚要领雷同,这个工具生存着需要处理惩罚的键盘事件和对应的行为。
而在jdk1.3中,利用一种新的要领来处理惩罚键盘事件,它将jdk1.2的两种要领整合在一起。不需要区分被处理惩罚的是Jcomponent照旧Text范例的组件。它界说了两个新的类:InputMap和ActionMap。他们均是简朴的表或映射。一个InputMap将一个Keystroke对应到一个工具,ActionMap将一个工具对应到一个行为(Action)。凡是InputMap中KeyStroke所对应的工具是一个字符串,通过这个字符串可以在ActionMap中查找到相应的行为。
InputMap和ActionMap中均有put要领。InputMap的put要领可以将Keystroke对应到一个工具,而ActionMap的put要领可以将一个工具对应到一个行为。
在每一个Jcomponent组件中,会有三个缺省的InputMap和一个缺省的ActionMap。他们可以通过挪用getInputMap(int condition)和getActionMap()获得。三个InputMap别离是当组件自己拥有核心时的InputMap(WHEN_FOCUSED),当组件的祖先拥有核心时的InputMap(WHEN_ANCESTOR_OF_FOCUSED_COMPONENT)和组件地址的窗体具有核心时的InputMap(WHEN_IN_FOCUSED_WINDOW)(括号内暗示为了获得这些InputMap,应该在getInputMap中配置的参数)。以下别离说明这三种InputMap:
1, 组件自己拥有核心时的InputMap:当组件拥有核心时,键盘按键按下,则java在这个InputMap中查找键盘事件所对应的KeyStroke工具。
2, 组件的祖先拥有核心时的InputMap:当组件的祖先拥有核心时,键盘按键按下,则java查找这个InputMap。
3, 组件地址的窗口拥有核心时的InputMap:当组件地址的窗口具有核心时,键盘按键按下,则java查找这个InputMap。
当一个键被按下,这个事件被转化成一个KeyStroke工具,java会查找这个Jcomponent的相应InputMap(譬喻,当组件的祖先具有核心时,java就查找这个Jcomponent的祖先拥有核心的InputMap)中是否有这个KeyStroke,假如有,取出它所对应的工具(凡是是字符串),操作这个工具在这个Jcomponent的ActionMap中查找,假如找到对应的行为(Action),则java执行这个行为的actionPerformed要领(随后先容这个要领)。从而达处处理惩罚键盘事件的目标。
每一个InputMap可以具有parent属性,这个属性的值是一个InputMap。当在一个InputMap中查找不到键盘事件的KeyStroke时,java会自动在它的parent属性指定的InputMap中查找,依次向上查找,直至找到。利用parent的长处是:当有一些牢靠的,不但愿用户举办窜改的键盘映射可以存放在parent属性所指定的InputMap中,从而制止被意外修改;别的可以将多个Jcomponent的缺省InputMap配置具有沟通的parent,使得可以共享一些键盘绑定的配置。可以通过InputMap类的setparent()要领配置它的parent属性。ActionMap也具有沟通的parent属性,利用要领也沟通。
以上是如何将一个键盘事件对应到一个行为,以下就简朴先容行为(Action)。
行为是一个实现了Action接口的类。在Action接口中界说了7个要领。个中最要害的是actionPerformed()要领。这个要领描写了这个行为的详细操纵进程。其他几个要领包罗setEnabled,isEnabled,putValue,getValue,addPropertyChangeListener,和removePropertyChangeListener要领。他们别离用来配置行为是否可用、判定行为可用的状态、配置和取得行为的一些属性,最后两个要领用来答允其他工具在动作工具的属性产生变革后获得通知。
凡是我们利用一个实现了Action接口的大部门要领的抽象类AbstractAction类作为基类,重载actionPerformed要领以实现我们的行为。
我们用一个例子来详细说明如何举办实际的操纵。
首先编写一个详细的行为,对指定的键盘事件举办处理惩罚:
public class TextAction extends AbstractAction
{
private String a;
public TextAction(String a)
{ this.a = a; }
public void actionPerformed(ActionEvent parm1)
{
String b = parm1.getActionCommand(); //获得行为的呼吁字符串
System.out.println("command="+b);
System.out.println("prompt="+this.a);
}
}
#p#副标题#e#
成立四个TextAction工具:
TextAction whenFocusSon = new TextAction("focus son");
TextAction whenFocusFather = new TextAction("focus father");
TextAction window = new TextAction("window");
TextAction ancestor = new TextAction("ancestor");
#p#分页标题#e#
随后,在一个窗体中插手两个面板,名为sonPanel和parentPanel,使得parentPanel是sonPanel的祖先。并在sonPanel中插手一个名为son的button,在parentPanel中插手名为parent的button。在fatherPanel外插手几个button。
获得son组件的三个InputMap,并建设一个名为focusFatherIm的InputMap,使得这个InputMap成为focusIm的parent:
//get default inputMap (when focus inputmap) and set a parent InputMap
focusIm = son.getInputMap();
focusFatherIm = new InputMap();
focusIm.setParent(focusFatherIm);
//get WHEN_ANCESTOR_OF_FOCUSED_COMPONENT inputMap
ancestorIm = son.getInputMap(WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
//get WHEN_IN_FOCUSED_WINDOW inputMap
windowIm = son.getInputMap(WHEN_IN_FOCUSED_WINDOW);
在这些InputMap中别离插手键盘绑定:
focusIm.put(KeyStroke.getKeyStroke('f'),"actionFocusSon");
focusFatherIm.put(KeyStroke.getKeyStroke('F'),"actionFocusFather");
ancestorIm.put(KeyStroke.getKeyStroke('a'),"actionAncestor");
windowIm.put(KeyStroke.getKeyStroke('w'),"actionWindow");
获得son组件的缺省的ActionMap,并将已经成立的行为与特定的工具(字符串)举办绑定:
am = son.getActionMap();
am.put("actionFocusSon",whenFocusSon);
am.put("actionFocusFather",whenFocusFather);
am.put("actionAncestor",ancestor);
am.put("actionWindow",window);
运行措施及其相应功效:
1, 单击son按钮,这时假如按下’f’,’F’,’a’,’w’,措施均会有相应的输出。这是因为,此时的核心在son按钮上,而son按钮组件的三个InputMap都是有效的。所以他们对应的事件城市产生。
2, 单击parent按钮,这时按下’w’,措施会有相应的输出。而按下’f’,’F’,’a’,措施没有回响。这是因为parent按钮具有核心,这个按钮不是son按钮的祖先,而son地址的窗口具有核心,所以只有组件地址窗口具有核心的InputMap是有效的。
3, 单击其他的按钮(parentPanel外的按钮),这时按下’w’,措施会有相应的输出。而按下’f’,’F’,’a’,措施没有回响。这是因为这些按钮具有核心,他们不是son按钮的祖先,而son地址的窗口具有核心,所以只有组件地址窗口具有核心的InputMap是有效的。
附:主要措施代码:
import java.awt.*;
import javax.swing.*;
import com.borland.jbcl.layout.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import com.sun.java.swing.plaf.motif.*;
public class EventPanel extends JPanel implements ActionListener
{
JButton btnYellow = new JButton();
JButton btnBlue = new JButton();
JButton btnRed = new JButton();
JPanel parentPanel = new JPanel();
JPanel sonPanel = new JPanel();
XYLayout xYLayout1 = new XYLayout();
JButton son = new JButton();
JButton parent = new JButton();
public EventPanel()
{
try{
jbInit();
}catch(Exception ex)
{ ex.printStackTrace(); }
}
void jbInit() throws Exception
{
btnYellow.setText("Yellow");
btnYellow.setBounds(new Rectangle(35, 23, 97, 29));
this.setLayout(null);
btnBlue.setBounds(new Rectangle(154, 21, 97, 29));
btnBlue.setText("Blue");
btnRed.setBounds(new Rectangle(272, 24, 97, 29));
btnRed.setText("Red");
parentPanel.setBorder(BorderFactory.createRaisedBevelBorder());
parentPanel.setBounds(new Rectangle(27, 68, 358, 227));
parentPanel.setLayout(xYLayout1);
sonPanel.setBorder(BorderFactory.createLoweredBevelBorder());
son.setText("son");
parent.setText("parent");
this.add(btnYellow, null);
this.add(btnBlue, null);
this.add(btnRed, null);
this.add(parentPanel, null);
parentPanel.add(sonPanel, new XYConstraints(58, 22, 229, 125));
sonPanel.add(son, null);
parentPanel.add(parent, new XYConstraints(150, 167, -1, -1));
btnYellow.addActionListener(this);
btnRed.addActionListener(this);
btnBlue.addActionListener(this);
InputMap focusIm,focusFatherIm,ancestorIm,windowIm;
ActionMap am;
//create four TextAction for diff purpose
TextAction whenFocusSon = new TextAction("focus son");
TextAction whenFocusFather = new TextAction("focus father");
TextAction window = new TextAction("window");
TextAction ancestor = new TextAction("ancestor");
//get default inputMap (when focus inputmap) and set a parent InputMap
focusIm = son.getInputMap();
focusFatherIm = new InputMap();
focusIm.setParent(focusFatherIm);
//get WHEN_ANCESTOR_OF_FOCUSED_COMPONENT inputMap
ancestorIm = son.getInputMap(WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
//get WHEN_IN_FOCUSED_WINDOW inputMap
windowIm = son.getInputMap(WHEN_IN_FOCUSED_WINDOW);
//put the keyStroke to the InputMap
focusIm.put(KeyStroke.getKeyStroke('f'),"actionFocusSon");
focusFatherIm.put(KeyStroke.getKeyStroke('F'),"actionFocusFather");
ancestorIm.put(KeyStroke.getKeyStroke('a'),"actionAncestor");
windowIm.put(KeyStroke.getKeyStroke('w'),"actionWindow");
//get the actionMap
am = son.getActionMap();
am.put("actionFocusSon",whenFocusSon);
am.put("actionFocusFather",whenFocusFather);
am.put("actionAncestor",ancestor);
am.put("actionWindow",window);
}
public void actionPerformed(ActionEvent e)
{
//this code is used to change the backgracolor
Object source=e.getSource();
Color color=null;//=getBackground();
if (source==btnYellow) color=Color.yellow;
else if (source==btnRed) color = Color.red;
else if (source == btnBlue) color = Color.blue;
setBackground(color);
repaint();
}
}