Java Swing中的键盘事件处理

Java Swing中的键盘事件处理,第1张

在java Swing编程过程中 经常需要处理键盘事件 例如处理快捷键等 这里就介绍如何定义键盘事件 以及如何处理这些事件 在jdk 中 分别针对Jponent和Text类的对象定制了不同的处理键盘事件的方法 在Jponent中 定义了registerKeyboardAction方法 使用这个方法来将需要处理的键盘事件以及处理事件的行为绑定在一起 Text类中具有keymap对象 同Jponent中的处理方法类似 这个对象保存著需要处理的键盘事件和对应的行为 而在jdk 中 使用一种新的方法来处理键盘事件 它将jdk 的两种方法整合在一起 不需要区分被处理的是Jponent还是Text类型的组件 它定义了两个新的类 InputMap和ActionMap 他们均是简单的表或映射 一个InputMap将一个Keystroke对应到一个对象 ActionMap将一个对象对应到一个行为(Action) 通常InputMap中KeyStroke所对应的对象是一个字符串 通过这个字符串可以在ActionMap中查找到相应的行为 InputMap和ActionMap中均有put方法 InputMap的put方法可以将Keystroke对应到一个对象 而ActionMap的put方法可以将一个对象对应到一个行为 在每一个Jponent组件中 会有三个缺省的InputMap和一个缺省的ActionMap 他们可以通过调用getInputMap(int condition)和getActionMap()得到 三个InputMap分别是当组件本身拥有焦点时的InputMap(WHEN_FOCUSED) 当组件的祖先拥有焦点时的InputMap(WHEN_ANCESTOR_OF_FOCUSED_PONENT)和组件所在的窗体具有焦点时的InputMap(WHEN_IN_FOCUSED_WINDOW)(括号内表示为了得到这些InputMap 应该在getInputMap中设置的参数) 以下分别说明这三种InputMap 组件本身拥有焦点时的InputMap 当组件拥有焦点时 键盘按键按下 则java在这个InputMap中查找键盘事件所对应的KeyStroke对象 组件的祖先拥有焦点时的InputMap 当组件的祖先拥有焦点时 键盘按键按下 则java查找这个InputMap 组件所在的窗口拥有焦点时的InputMap 当组件所在的窗口具有焦点时 键盘按键按下 则java查找这个InputMap 当一个键被按下 这个事件被转化成一个KeyStroke对象 java会查找这个Jponent的相应InputMap(例如 当组件的祖先具有焦点时 java就查找这个Jponent的祖先拥有焦点的InputMap)中是否有这个KeyStroke 如果有 取出它所对应的对象(通常是字符串) 利用这个对象在这个Jponent的ActionMap中查找 如果找到对应的行为(Action) 则java执行这个行为的actionPerformed方法(随后介绍这个方法) 从而达到处理键盘事件的目的 每一个InputMap可以具有parent属性 这个属性的值是一个InputMap 当在一个InputMap中查找不到键盘事件的KeyStroke时 java会自动在它的parent属性指定的InputMap中查找 依次向上查找 直至找到 使用parent的好处是 当有一些固定的 不希望用户进行改动的键盘映射可以存放在parent属性所指定的InputMap中 从而避免被意外修改 另外可以将多个Jponent的缺省InputMap设置具有相同的parent 使得可以共享一些键盘绑定的设置 可以通过InputMap类的setparent()方法设置它的parent属性 ActionMap也具有相同的parent属性 使用方法也相同 以上是如何将一个键盘事件对应到一个行为 以下就简单介绍行为(Action) 行为是一个实现了Action接口的类 在Action接口中定义了 个方法 其中最关键的是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 parm ){ String b = parm getActionCommand()//得到行为的命令字符串 System out println( mand= +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 InputMapfocusIm = son getInputMap()focusFatherIm = new InputMap()focusIm setParent(focusFatherIm)//get WHEN_ANCESTOR_OF_FOCUSED_PONENT inputMap ancestorIm = son getInputMap(WHEN_ANCESTOR_OF_FOCUSED_PONENT)//get WHEN_IN_FOCUSED_WINDOW inputMapwindowIm = 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)运行程序及其相应结果 单击son按钮 这时如果按下 f F a w 程序均会有相应的输出 这是因为 此时的焦点在son按钮上 而son按钮组件的三个InputMap都是有效的 所以他们对应的事件都会发生 单击parent按钮 这时按下 w 程序会有相应的输出 而按下 f F a 程序没有反应 这是因为parent按钮具有焦点 这个按钮不是son按钮的祖先 而son所在的窗口具有焦点 所以只有组件所在窗口具有焦点的InputMap是有效的 单击其他的按钮(parentPanel外的按钮) 这时按下 w 程序会有相应的输出 而按下 f F a 程序没有反应 这是因为这些按钮具有焦点 他们不是son按钮的祖先 而son所在的窗口具有焦点 所以只有组件所在窗口具有焦点的InputMap是有效的 附 主要程序代码 import java awt *import javax swing *import borland jbcl layout *import java awt event ActionEventimport java awt event ActionListenerimport 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 xYLayout = 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( ))this setLayout(null)btnBlue setBounds(new Rectangle( ))btnBlue setText( Blue )btnRed setBounds(new Rectangle( ))btnRed setText( Red )parentPanel setBorder(BorderFactory createRaisedBevelBorder())parentPanel setBounds(new Rectangle( ))parentPanel setLayout(xYLayout )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( ))sonPanel add(son null)parentPanel add(parent new XYConstraints( lishixinzhi/Article/program/Java/hx/201311/25647

Java提供了两个事件侦听接口用来管理鼠标移动和键盘动作,分别是MouseMotionListener和KeyListener,可以用它们来捕捉鼠标和键盘。

1)类KeyMonitor,是一个JPanel的扩展类,用来显示捕捉到的按键信息;

2)类MouseMonitor,也是一个JPanel的扩展类,用来显示到的鼠标移动信息;

3)入口类Main,用匿名类的方式实现了真正的监听接口

PS:Java提供的这两个侦听器都有很大的限制,鼠标监听只有在鼠标位于Java程序所在的窗口范围之内才能有效,而键盘监听限制更严格,仅当Java程序成为当前的活动窗口时才有效。单纯用Java来实现全屏幕、所有程序的鼠标和键盘活动是不可行的。

赞一个, 提前学习, 做好预先 , 是个好习惯.

java图形界面主要有AWT, SWING, SWT, JavaFx等技术

JButton  (按钮)是SWING里面很常用的组件. 直接添加按钮到窗口,并不会产生任何交互效果.

要想产生交互效果,就需要了解awt,swing的事件处理机制:

事件:用户对组件的一个 *** 作,称之为一个事件;

事件源:发生事件的组件就是事件源;

事件处理器:负责处理事件的方法;

比如 点击按钮,d出HelloWord,

那么 事件是 点击按钮 ,事件源就是按钮,事件处理器就会d出对话框,显示HelloWord.

常用的事件(Event) 有:

鼠标事件(MouseEvent: 鼠标按下,移入,移除,滚轮..)

键盘事件(KeyEvent: 键盘按下,释放..)

动作事件( ActionEvent:当按钮、菜单项被点击,在JTextField中按Enter键时...触发该事件。)

按钮添加接收器, 不同的事件,接收器不同.

比如ActionEvent 那么他的接收器是ActionListener

KeyEvent 那么他的接收器就是KeyListener

基础知识,大概就是这些.

所以想要JButton产生交互,你就需要给他添加事件处理器,当发生这些事件时,出发该处理器,进行处理.

写2个例子,第一个简单的:点击按钮,d出Hello World

//导入3个图形界面,常用的包

import java.awt.*

import java.awt.event.*

import javax.swing.*

public class ButtonDemo extends JFrame {

 

 public ButtonDemo() {

  

  JButton jbHello = new JButton("Hello")//按钮

  jbHello.addActionListener(new ActionListener() {//给按钮添加事件接收器

   @Override

   public void actionPerformed(ActionEvent e) {//接受到事件后,进行下面的处理

    System.out.println("Hello World")// 控制台打印输出

    JOptionPane.showMessageDialog(null, "Hello World")// d出对话框,显示Hello World

   }

  })

  add(jbHello)//把按钮添加到窗体

  

  // 窗体属性的设置

  setLayout(new FlowLayout())// 窗体流式布局, 按添加顺序从左到右排列组件

  setSize(300, 200)// 宽300像素,高200

  setLocationRelativeTo(null)// 窗体放在显示器中间

  setTitle("HelloWord")// 窗体的标题

  setDefaultCloseOperation(EXIT_ON_CLOSE)// 点击窗体右上角的关闭按钮时,结束程序

  setVisible(true)// 窗体可见

 }

 public static void main(String[] args) {

  new ButtonDemo()

 }

}

看明白了吧, addActionListener是关键

进阶版 :加法计算器.  代码稍微长一点,.但注释很多

参考代码如下

import java.awt.*

import java.awt.event.*

import javax.swing.*

//AddFrame继承自JFrame类, 并且实现了ActionListener 接口

public class AddFrame extends JFrame implements ActionListener {

 // 组件

 JTextField jtf1, jtf2, jtf3// 文本框,用于:显示数字

 JButton jbAdd// 按钮,用于:当点击按钮时,计算出加法的结果

 JButton jbClear// 按钮, 用于,清空数字

 public AddFrame() {// 构造方法

  // 初始化组件

  jtf1 = new JTextField(5)// 长度为5的文本框

  JLabel jl = new JLabel("+")//文字标签

  jtf2 = new JTextField(5)

  jtf3 = new JTextField(6)

  jtf3.setEditable(false)

  jbAdd = new JButton("=")

  jbAdd.addActionListener(this)//因为本类已经实现了ActionListener接口,所以添加事件的接收器就是自己(this)

  jbClear = new JButton("清除")

  jbClear.addActionListener(this)

  

  //把组件,添加到窗体

  add(jtf1)

  add(jl)

  add(jtf2)

  add(jbAdd)

  add(jtf3)

  add(jbClear)

  

  // 窗体属性的设置

  setLayout(new FlowLayout())//窗体流式布局, 按添加顺序从左到右排列组件

  setSize(380, 100)// 宽380像素,高100

  setLocationRelativeTo(null)// 窗体放在显示器中间

  setTitle("加法计算器")// 窗体的标题

  setDefaultCloseOperation(EXIT_ON_CLOSE)// 点击窗体右上角的关闭按钮时,结束程序

  setVisible(true)// 窗体可见

 }

 /*

  *  实现ActionListener接口 就必须重写actionPerformed方法

  */

 @Override

 public void actionPerformed(ActionEvent e) {// 当事件产生后,就会执行actionPerformed里的方法

  JButton jbTemp= (JButton) e.getSource()//得到事件源

  

  if(jbTemp==jbAdd) {//如果是从jbAdd产生的事件.那么执行加法 *** 作

   //因为是简单案例,就不判断和处理,用户乱输入字母汉字等情况,导致的异常了

   int x = Integer.parseInt(jtf1.getText())//从文本框1得到字符串,并转化成数字

   int y = Integer.parseInt(jtf2.getText())

   jtf3.setText(x+y+"")//计算2个数的和,并显示在文本框3上

   

  }else if(jbTemp==jbClear) {//如果事件源是 jbClear,那么清除文本框的文字

   

   jtf1.setText("")

   jtf2.setText("")

   jtf3.setText("")

  }

  

 }

 // main方法

 public static void main(String[] args) {

  new AddFrame()//创建一个AddFrame的实例

 }

}


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/12058307.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-20
下一篇 2023-05-20

发表评论

登录后才能评论

评论列表(0条)

保存