`

[转]Java Swing中的键盘事件处理

    博客分类:
  • cava
阅读更多

[转]Java Swing中的键盘事件处理

在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); 
  } 
 } 

  建立四个TextAction对象: 

TextAction whenFocusSon = new TextAction("focus son"); 
TextAction whenFocusFather = new TextAction("focus father"); 
TextAction window = new TextAction("window"); 
TextAction ancestor = new TextAction("ancestor"); 

  随后,在一个窗体中加入两个面板,名为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(); 
 } 
} 
 

<script type="text/javascript"></script><script src="http://pagead2.googlesyndication.com/pagead/show_ads.js" type="text/javascript"></script><script src="http://pagead2.googlesyndication.com/pagead/js/r20101117/r20101214/show_ads_impl.js"></script><script src="http://pagead2.googlesyndication.com/pagead/expansion_embed.js"></script><script src="http://googleads.g.doubleclick.net/pagead/test_domain.js"></script><script src="http://pagead2.googlesyndication.com/pagead/render_ads.js"></script><script></script>

分享到:
评论

相关推荐

    java swing模拟键盘

    在开发过程中,你可能需要对Java Swing API有深入的理解,包括组件、事件处理、布局管理等方面。同时,为了在iPad或其他移动设备上运行,你可能还需要考虑使用JavaFX或第三方库,如RoboVM,将Java应用程序转换为iOS...

    了解Swing中的键盘事件处理

    在Java Swing开发中,键盘事件处理是一项非常重要的功能,能够显著提升用户界面的交互性和可用性。本文将深入探讨Swing框架中处理键盘事件的不同机制,并详细介绍如何实现这些功能。 #### 二、键盘事件处理的历史...

    JAVA swing中文离线API文档

    本离线API文档详细阐述了Swing库中的各种组件、事件处理机制以及布局管理器等核心概念,对Java桌面开发人员来说是一份非常重要的参考资料。 在Java Swing中,开发者可以创建窗口、菜单、按钮、文本输入框等常见的...

    基于java swing实现答题系统

    在本文中,我们总结了基于Java Swing实现答题系统的技术要点,涵盖了GUI设计、事件处理、swing组件使用、Java图形化编程等多个方面的知识点。 七、结论 本文详细介绍了基于Java Swing实现答题系统的技术要点,涵盖...

    java swing 事件处理小项目(推箱子)

    总的来说,这个Java Swing事件处理小项目“推箱子”不仅展示了Swing的基本用法,还涵盖了事件处理、图形用户界面设计和简单的游戏逻辑实现。对于学习Java GUI编程和事件驱动编程的初学者来说,这是一个很好的实践...

    javaswing教程 精通javaswing

    它是所有组件的父类,提供了绘制的基础架构、键盘事件处理、add() 方法等功能。 简单的 Swing 小部件 JLabel 是 Swing 库中最基础的组件。它所做的正是您所期望的:呆在那儿,看起来很漂亮,描述其他组件。它可以...

    java事件 键盘事件 实例代码

    总之,Java中的键盘事件处理是构建用户友好应用程序的关键部分。通过理解`KeyEvent`类和事件监听器,开发者可以创建响应用户键盘输入的动态应用。在实际项目中,应根据需求选择合适的事件处理策略,确保代码的健壮性...

    基于JAVASwing的贪食蛇小游戏 键盘事件监听 多线程 文件IO 自取

    通过分析和实现这个项目,你将深入理解Java Swing的基本组件和事件处理,以及多线程和文件I/O在实际应用中的使用。这是一个很好的起点,对于任何想要提升Java编程技能的初学者来说,都是一个既实用又有趣的练习。

    学生选课和成绩管理系统 基于JAVASWing 键盘鼠标事件监听 JDBC 文件IO流

    《基于JAVA Swing的学生选课与成绩管理系统开发详解》 在信息技术高速发展的今天,教育领域的...通过深入理解和实践这些技术,开发者不仅可以掌握数据库应用开发的基本技能,还能提升在GUI设计和事件处理方面的能力。

    javaswing详解

    本篇文章将深入讲解Java Swing的基础知识、核心组件、事件处理以及实际案例应用。 一、Java Swing基础知识 1. 轻量级与重量级组件:Swing组件是轻量级的,基于Java的AWT(Abstract Window Toolkit)组件,比AWT...

    java swing实现pdf阅读器

    在Java中处理PDF文件,我们通常需要借助于如Apache PDFBox、iText或PDFJava等第三方库。 首先,要实现PDF阅读器,我们需要能够读取PDF文件。Apache PDFBox是Apache软件基金会的一个项目,提供了一系列API用于读取、...

    java swing 鼠标自动移动

    综上所述,"java swing 鼠标自动移动"项目结合了Java Swing GUI编程、鼠标事件处理、Robot类的使用、以及应用打包技术,为开发者提供了一个实用的示例,展示了如何在Java环境中实现鼠标自动移动。

    贪吃蛇java swing

    通过学习和实践这个Java Swing版的贪吃蛇游戏,开发者可以深入理解Java GUI编程,同时提升对事件处理、图形绘制、游戏逻辑设计等多方面的能力。这个项目也是进一步探索Java高级特性和软件工程实践的良好起点。

    Java swing编写的计算器界面.zip

    Java Swing 是Java编程语言中的一个图形用户界面(GUI)工具包,它...通过学习这个示例,开发者不仅可以掌握Java Swing的基本用法,还能了解GUI编程的设计原则和事件处理机制,对于提升Java桌面应用开发技能非常有帮助。

    Java swing 俄罗斯方块

    Java Swing 是Java GUI...通过理解Swing组件、事件处理、定时器和适当的数据结构,开发者可以构建出具有完整功能的俄罗斯方块游戏。这个项目不仅是对Java GUI编程技能的锻炼,也是对游戏逻辑设计和用户体验优化的实践。

    java swing

    1. **键盘事件处理**:Swing能够捕获用户的键盘输入,并将其转换为应用程序可以理解的事件。 2. **颜色控制**:Swing允许开发者轻松地更改UI的颜色方案。 3. **文本组件**:Swing提供了多种文本组件,如文本框、文本...

    javaswing 打飞机小游戏

    总的来说,这个“javaswing 打飞机小游戏”项目是一个很好的实践案例,可以帮助开发者熟悉Java Swing的基本用法,理解事件处理、图形绘制和游戏循环等概念,对于初学者来说是一个有价值的编程练习。

    java swing界面设计

    - "Java图形用户界面设计(Swing常用组件).ppt"和"JavaSwing界面设计(所有控件及示例).ppt"两个文件中可能包含了各种Swing组件的使用示例和实际应用,建议仔细学习和实践。 9. **学习资源** - Java官方文档:提供...

    java3D使用键盘对场景中物体的一些控制

    总的来说,通过Java 3D结合键盘事件处理,我们可以实现丰富的用户交互,让用户能够通过键盘控制3D场景中的物体,从而提高应用的可玩性和实用性。在实际项目中,你可能还需要处理其他细节,比如限制物体的移动范围、...

Global site tag (gtag.js) - Google Analytics