KeyStroke类的使用

来源:互联网 发布:无线网络优化 编辑:程序博客网 时间:2024/06/05 20:13

KeyStroke类的使用
2007年05月16日 下午 08:03

在Java事件中处理组合键需要用到KeyStroke这个类,需要先对这个类有一些了解。
在JDK中说,KeyStroke是用来表示键盘的动作的,或者等价的输入设备。KeyStroke 用于定义高级操作事件。不用捕获每个 keystroke 并抛弃不感兴趣的 keystroke,这些重要的 keystroke 会自动在其注册的 Components上启动操作。KeyStroke是不可变的,而且是单例的,必须使用 getKeyStroke工厂方法, 这些工厂方法使得KeyStroke实现能够高效缓存和共享实例。

KeyStroke里面的getKeyStroke有多个实现,可以用String,int和char来构造KeyStroke。

JComponent中有四个常量WHEN_FOCUSED,WHEN_ANCESTOR_OF_FOCUSED_COMPONENT,WHEN_IN_FOCUSED_WINDOW,
UNDEFINED_CONDITION.
InputMap根据这个变量的值来觉得在什么范围内触发这个事件,默认是WHEN_FOCUSED。
WHEN_FOCUSED   即该JComponent获得焦点的时候
WHEN_ANCESTOR_OF_FOCUSED_COMPONENT 当这个JComponent获得焦点或者ANCESTOR获得焦点的时候
WHEN_IN_FOCUSED_WINDOW 当窗体或者焦点的时候
UNDEFINED_CONDITION 被某些api利用,不知道啥意思

JComponent有两个map,分别是InputMap,ActionMap。
InputMap代表了KeyStroke和Action的映射。
ActionMap代表了Action和actionListener的映射。
当触发热键的时候,会首先检查InputMap中的KeyStroke是否有这个热键,有的话则触发ActionMap中的actionListener,
两个map通过InputMap和ActionMap通过Action那个常量一对一映射。
不过不太明白为什么不让KeyStroke和actionListener直接映射。

下面看一个实例,全面的表现了KeyStroke的功能,代码如下:

import java.awt.Container;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;

import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.ActionMap;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.KeyStroke;

public class KeyStrokeSample extends JFrame {

private static final long serialVersionUID = 7306881762497576739L;

private static final String ACTION_KEY = "keyPressed";

private JButton buttonA = null;

private JButton buttonB = null;

private JButton buttonC = null;

private JButton buttonD = null;

private Action actionListener = null;

private ActionMap actionMap = null;

public KeyStrokeSample() {
   actionListener = ButtonAction.getInstance();
   initButtonA();
   initButtonB();
   initButtonC();
   initButtonD();
   initFrame();
}

private void initButtonA() {
   buttonA = new JButton("<html><center>当该按钮获得焦点时有效<br>热键:Ctrl+Alt+Z");
   KeyStroke ctrlAltZ = KeyStroke.getKeyStroke("control alt Z");
   buttonA.getInputMap().put(ctrlAltZ, ACTION_KEY);
   actionMap = buttonA.getActionMap();
   buttonA.getActionMap().put(ACTION_KEY, actionListener);
}

private void initButtonB() {
   buttonB = new JButton(
     "<html><center>当该按钮获得焦点时有效,触发Release事件<br>热键:Enter");
   KeyStroke enter = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0, true);
   buttonB.getInputMap().put(enter, ACTION_KEY);
   buttonB.setActionMap(actionMap);
}

private void initButtonC() {
   buttonC = new JButton("<html><center>当祖先获得焦点的时候有效<br>热键:Shift+F4");
   KeyStroke shiftF4 = KeyStroke.getKeyStroke(KeyEvent.VK_F4,
     KeyEvent.SHIFT_MASK);
   buttonC.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(
     shiftF4, ACTION_KEY);
   buttonC.setActionMap(actionMap);
}

private void initButtonD() {
   buttonD = new JButton("<html><center>当窗口获得焦点的时候有效<br>热键:空格");
   KeyStroke space = KeyStroke.getKeyStroke(' ');
   buttonD.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(space,
     ACTION_KEY);
   buttonD.setActionMap(actionMap);
}

private void initFrame() {
   this.setTitle("KeyStroke Sample");
   initFrameLocation();
   setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   setSize(400, 200);
   setResizable(false);
  
   setLocationRelativeTo(null);
}

private void initFrameLocation() {
   Container contentPane = getContentPane();
   contentPane.setLayout(new GridLayout(2, 2));
   contentPane.add(buttonA);
   contentPane.add(buttonB);
   contentPane.add(buttonC);
   contentPane.add(buttonD);
}

public static void main(String args[]) {
   KeyStrokeSample sample = new KeyStrokeSample();
   sample.setVisible(true);
}
}

/** button的action处理类 */
class ButtonAction extends AbstractAction {
private static final long serialVersionUID = 2115411141520208211L;

private static ButtonAction action = null;

private ButtonAction() {
}

public void actionPerformed(ActionEvent actionEvent) {
   JButton source = (JButton) actionEvent.getSource();
   JOptionPane.showMessageDialog(null, "激活:" + source.getText());
}

public static ButtonAction getInstance() {
   if (action == null) {
    action = new ButtonAction();
   }
   return action;
}
}

可以根据上面讲的内容读一下代码,比较容易理解。

原创粉丝点击