7.Java-GUI事件监听机制
Java事件监听机制
在上述的程序中,其中菜单条,菜单项,按钮等都是对象,当我们单击对象时,应该能够完成一些任务.例如在程序中通过鼠标操作时,单击,双击,鼠标移入,鼠标移出.能够执行一些任务,在Java中我们可以使用事件监听机制,在Java的事件监听机制中 ,当事件发生时(点击按钮,移动鼠标等,关闭窗口)会被一类对象发现并处理.
事件和事件源
在运行java图形用户界面程序时,用户与程序交互,用户执行了某些操作时,会发生一些事情, 那么事件(event)可以定义为程序发生了某些事情的信号.典型用户操作就是用户移动鼠标,点击按钮,敲击键盘等.程序可以选择相应事件或者忽略事件。
能够创建一个事件并触发该事件的组件称为源对象。例如由于按钮能够点击, 那么按钮就是一个源对象,按钮被点击就是一个事件。
一个事件是事件类的实例对象。事件类的根类是java.util.EventObject。
事件对象包含事件相关的属性,可以使用EventObject类中的实例方法getSource获得事件的源对象。
EventObject类的子类可以描述特定类型的事件
例如:
用户动作 |
源对象 |
触发的事件类型 |
点击按钮 |
JButton |
ActionEvent |
文本域按回车 |
JTextField |
ActionEvent |
窗口打开,关闭,最小化,关闭 |
Window |
WindowEvent |
单击,双击,移动,鼠标 |
Component |
MouseEvent |
点击单选框 |
JradioButton |
ItemEvent ActionEvent |
点击复选框 |
JcheckBox |
ItemEvent ActionEvent |
监听器
当源对象触发了一个事件,谁来处理这个事件?在Java中对此感兴趣的对象会处理它。对此感兴趣的对象称之为监听器(Listener)。
举例来说当我们点击一个按钮,想要按钮执行一些动作,需要一个对象来监控按钮,当点击按钮的事件发生时,该对象就会监听到按钮事件。进而可以执行一些动作。
例如:
Java中,对象表示的每个事件都是由java.util中EventObject类的子类,
例如: MouseEvent: 表示鼠标的动作,例如移动光标,单击,双击
KeyEvent: 表示键盘上的按键.
ActionEvent表示用户采取的用户界面操作,例如点击屏幕上的按钮.
事件处理
Java对组件都有对应的事件监听器,和添加事件监听器方法。
例如: 按钮: 源对象,会触发
体验:当用户点击按钮时,按钮上的信息会发生变化
import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JButton; import javax.swing.JFrame; public class ShowButton extends JFrame { public ShowButton() { JButton button = new JButton("点我"); add(button); // 添加鼠标监听事件 button.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { System.out.println("按钮被点击"); Object source = e.getSource(); JButton button = (JButton) source; String text = button.getText(); if ("按钮被点击".equals(text)) { button.setText("点我"); } else { button.setText("按钮被点击"); } } }); } public static void main(String[] args) { ShowButton frame = new ShowButton(); frame.setTitle("我的框架"); frame.setSize(400, 200); frame.setLocationRelativeTo(null); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible(true); } }
该案例中:构造方法创建了用户界面。只有一个JFrame框架和一个按钮。
按钮时事件的源。创建了一个监听器并注册到了按钮。通过匿名内部类的形式创建了监听器类
窗口事件
Window类
java.awt
类 Window
java.lang.Object
java.awt.Component
java.awt.Container
java.awt.Window
Window
对象是一个顶层窗口。窗口(Window)对应的事件叫做窗口事件(WindowEvent),任何窗口(Window)以及窗口的子类都可能触发窗口事件: 打开窗口,正在关闭窗口,激活窗口,变成非活动窗口,最小化窗口和还原窗口。
Window添加窗口事件(WindowEvent)监听器的方法
void addWindowListener(WindowListener l) 添加指定的窗口侦听器,以从此窗口接收窗口事件
监听Window窗口事件(WindowEvent)的监听器:WindowListener
java.awt.event
接口 WindowListener
用于接收窗口事件的侦听器接口。当通过打开、关闭、激活或停用、图标化或取消图标化而改变了窗口状态时,将调用该侦听器对象中的相关方法
WindowListener接口中定义的方法
抽象方法: void windowActivated(WindowEvent e) 激活窗口 void windowClosed(WindowEvent e) 关闭窗口 void windowClosing(WindowEvent e) 正在关闭窗口 void windowDeactivated(WindowEvent e) 变为非活动窗口 void windowDeiconified(WindowEvent e) 还原窗口 void windowIconified(WindowEvent e) 最小化窗口 void windowOpened(WindowEvent e) 打开窗口
案例: 框架的事件监听处理
javax.swing
类 JFrame
java.lang.Object
java.awt.Component
java.awt.Container
java.awt.Window
java.awt.Frame
javax.swing.JFrame
创建JFrame,Jfame是一个框架,属于窗体(Window)体系中的一员,也可以实现窗口的最大化,最小化,关闭,点击窗体,等一系列的操作。那么在用户触发这些事件发生时能够做一些工作,就需要注册事件监听器。
JFrame 是通过addWindowListener 方法就注册窗体事件监听器,该方法需要接受一个监听器(WindowListener)对象。查找API文档,发现WindowListener是一个接口,
我们需要窗口监听器(WindowListener)的实例对象,所以需要实现该接口,重写WindowListener接口的抽象方法。然后创建该实现类对象,作为参数传递给addWindowListener .
例如: 当像激活窗口这样的窗口事件发生时,windowActivated 方法就会触发。
代码如下:
import java.awt.event.WindowEvent; import java.awt.event.WindowListener; import javax.swing.JFrame; public class WindowEventDemo extends JFrame { WindowEventDemo() { // this对象时JFrame的子类,而JFrame 类是Window体系中的一员所以具备添加窗口事件的方法 this.addWindowListener(new MyWindow()); } public static void main(String[] args) { WindowEventDemo frame = new WindowEventDemo(); frame.setTitle("我的框架"); frame.setSize(400, 200); frame.setLocationRelativeTo(null); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible(true); } } // 实现WindowListener class MyWindow implements WindowListener { // 激活窗口 public void windowActivated(WindowEvent e) { System.out.println("激活窗口"); } // 关闭窗口 public void windowClosed(WindowEvent e) { System.out.println("关闭窗口"); } // 正在关闭窗口 public void windowClosing(WindowEvent e) { System.out.println("正在关闭窗口"); } // 变为非活动窗口 public void windowDeactivated(WindowEvent e) { System.out.println("变为非活动窗口"); } // 还原窗口 public void windowDeiconified(WindowEvent e) { System.out.println("还原窗口"); } // 最小化窗口 public void windowIconified(WindowEvent e) { System.out.println(" 最小化窗口"); } // 打开窗口 public void windowOpened(WindowEvent e) { System.out.println("打开窗口"); } }
总结:Window类或者Window类的任何子类都可能会触发WindowEvent。因为JFrame是Window的子类。所以也可以触发WindowEvent。
监听器接口适配器
因为WindowListener接口中的方法都是抽象的,所以即使程序中不想关注某些事件,但是还是要实现所以的方法,比较麻烦,为了方便起见,Java提供了一个针对WindowListener接口的实现类,该类中把WindowListener接口中的方法全部实现,只不过方法体都为空。
例如: 加入我们只对激活窗口感兴趣,那么只需要继承该实现类重写激活窗口的方法即可。简化了代码。
import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import javax.swing.JFrame; public class AdapterDemo extends JFrame { AdapterDemo() { addWindowListener(new MyAdapter()); } public static void main(String[] args) { AdapterDemo frame = new AdapterDemo(); frame.setTitle("我的框架"); frame.setSize(400, 200); frame.setLocationRelativeTo(null); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible(true); } class MyAdapter extends WindowAdapter { public void windowActivated(WindowEvent e) { System.out.println("windowActivated...."); } } }
那么这个WindowAdapter类就叫做适配器类,是为了简化代码的书写而出现的。
适配器 接口
WindowAdapter WindowListener
MouserAdapter MouserListener
KeyAdapter KeyListener
鼠标键盘事件
当在一个组件上按下,释放,点击,移动,或者拖动鼠标时,就会产生鼠标事件。MouseEvent对象捕获这个事件。
MouseEvent
java.awt.event.MouseEvent
Java对鼠标事件提供了MouseListener 监听器接口,可以监听鼠标的按下,释放,输入,退出和点击动作。
MouseListener
用于接收组件上“感兴趣”的鼠标事件(按下、释放、单击、进入或离开)的侦听器接口
方法:
void mouseClicked(MouseEvent e) 鼠标按键在组件上单击(按下并释放)时调用。 void mouseEntered(MouseEvent e) 鼠标进入到组件上时调用。 void mouseExited(MouseEvent e) 鼠标离开组件时调用。 void mousePressed(MouseEvent e) 鼠标按键在组件上按下时调用。 void mouseReleased(MouseEvent e) 鼠标按钮在组件上释放时调用。
按键事件可以利用键盘来控制和执行一些动作,如果按下、释放一个键就会触发按键事件。KeyEvent对象可以捕获按键的按下放开和敲击。KeyEvent提供了getkeyChar 来获取按键对应的字符。
java.awt.event.KeyEvent char getKeyChar() 返回与此事件中的键关联的字符。
Java提供了KeyListener监听器接口来监听按键事件。
KeyListener接口
用于接收键盘事件(击键)的侦听器接口。
void keyPressed(KeyEvent e) 按下某个键时调用此方法。 void keyReleased(KeyEvent e) 释放某个键时调用此方法。 void keyTyped(KeyEvent e) 键入某个键时调用此方法。
案例:
演示鼠标事件和键盘事件,当在文本域中输入q 时程序会退出。
public class MouseEventDemo extends JFrame { MouseEventDemo() { JButton button = new JButton("ok"); JTextArea text = new JTextArea(); add(button, BorderLayout.NORTH); add(text, BorderLayout.CENTER); button.addMouseListener(new MouseListener() { // 鼠标按钮在组件上释放时调用。 public void mouseReleased(MouseEvent e) { System.out.println("鼠标释放"); } // 鼠标按键在组件上按下时调用。 public void mousePressed(MouseEvent e) { System.out.println("鼠标按下组件"); } // 鼠标离开组件时调用。 public void mouseExited(MouseEvent e) { System.out.println("鼠标离开组件"); } // 鼠标进入到组件上时调用。 public void mouseEntered(MouseEvent e) { // 鼠标进入 System.out.println("鼠标进入组件"); } // 鼠标按键在组件上单击(按下并释放)时调用。 public void mouseClicked(MouseEvent e) { System.out.println("鼠标单击组件"); } }); text.addKeyListener(new KeyListener() { // 键入某个键时调用此方法。 public void keyTyped(KeyEvent e) { System.out.println("键入某个键"); if (e.getKeyChar() == 'q') { System.exit(0); } } // 释放某个键时调用此方法。 public void keyReleased(KeyEvent e) { System.out.println("按键释放"); } // 按下某个键时调用此方法。 public void keyPressed(KeyEvent e) { System.out.println("键盘按下"); } }); } public static void main(String[] args) { MouseEventDemo frame = new MouseEventDemo(); frame.setTitle("鼠标事件"); frame.setSize(400, 200); frame.setLocationRelativeTo(null); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible(true); } }
事件监听机制小结
一:确定事件源(容器或组件)
二:注册监听器
通过事件源对象的addXXXListener()方法将监听器对象注册到该事件源上。
三:监听器对象
注册监听器时,需要指定监听器对象。
以参数的形式进监听器对象传递给addXXXListener()
监听器对象是XXXListener的子类对象或者XXXAdapter的子类对象。
监听器对象一般用匿名内部类来表示。(简化书写)
在覆盖方法的时候,方法的参数一般是XXXEvent类型的变量接收。
事件触发后会把事件打包成对象传递给该变量。(其中包括事件源对象。通过getSource()或者getComponent()获取。)
四:常见的事件监听器
WindowListener 主要用于监听窗口
ActionListener 主要用于用监听组件对象的单击动作
MouseListener 鼠标监听器
KeyListener 监听键盘
…….
五:常见的事件适配器
WindowAdapter
MouseAdapter
KeyAdapter