




已阅读5页,还剩19页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第9章 Java事件处理第8章介绍了常用的GUI组件对象的创建、布局以及设置观感效果。在实际运用中,这些内容只是图形界面设计的一部分,要充分体现GUI用户交互性,就需要这些GUI组件能完成具体的动作。本章将对Java事件处理做一个详细介绍。具体涉及到事件处理机制、常用的事件处理等内容。9.1 事件处理概述9.1.1 事件处理模式从JDK1.1开始起,Java语言采用基于代理的事件处理模型。基于代理事件处理模型是引进了监听器接口,每个事件类都有相关联的监听器接口。当用户对GUI组件有所动作,GUI组件会自动产生相应的事件来响应用户的动作。假设这些GUI组件已经注册了相关的监听器对象,监听器对象会一直监听已注册的组件对象是否有事件发生。当监听器对象监听到组件有相对应的事件发生,就会调用监听器对象中方法,即事件处理器来实现一定的动作。就这样,通过对目标监听器对象的相关Java方法调用,实现事件从事件源到监听者的传递。从上面描述,可以归纳出采用基于代理的事件处理模式涉及到三个基本概念:事件源、事件对象和事件监听器。(1)事件源。事件的产生者,通常是GUI组件对象,如按钮、窗口以及文本框等组件的实例对象;发出某种特定事件的事件源的标识是:通过指定方法注册到事件监听器对象,并接受对指定事件监听器对象的引用。(2)事件对象。所有的事件对象继承自java.util.EventObject类的子类对象。伴随着事件的发生,会产生相应的状态(如事件发生、监听器要求处理事件等信息),而这些状态信息封装在事件对象中。事件对象作为单参数传递给响应该事件的监听器对象中的方法。(3)事件监听器。每个明确的事件的发生,会有一个对应的Java方法执行事件处理。这些方法都集中定义在继承java.util.EventListener的某事件监听器接口中。事件监听器实际上指的是监听器接口的实例对象,可以实现监听器接口的一个或多个方法。监听器对象可以根据事件对象的状态来响应事件。为了实现事件的处理,需要执行如下四个步骤:第1步,程序导入java.awt.event包或javax.swing.event包,即import java.awt.event.*; 或 import javax.swing.event.*;通过导入这些关于事件处理的包,可以引入关于事件处理的监听接口,如java.awt.event.ActionListener等以及事件处理中事件类,如java.awt.event.ActionEvent等。第2步,创建事件源,实际上就是通过调用GUI组件的构造方法,创建和初始化GUI组件对象。第3步,给事件源注册事件监听器,形如:事件源对象.addXXXListener(XXXListener);对于同一个事件源而言,允许有多个事件监听器;但是同一个监听器只能被同一个事件源注册一次。第4步,根据监听得到事件的类型,实现事件监听器接口的对应方法。例9.1 利用Swing包的类JColorChooser,设计一个文字框的文字颜色设置的程序。import javax.swing.*;import java.awt.*;import java.awt.event.*; /导入java.awt.event包public class SimpleEventHandling extends JFrame implements ActionListener/实现接口JTextField text; /定义文本框textJButton colorButton; /定义选颜色的按钮colorButtonContainer container; public SimpleEventHandling()super(一个简单示例);container=getContentPane();container.setLayout(new FlowLayout();text=new JTextField(选择颜色的示例文字); 图9-1 例9.1的运行结果colorButton=new JButton(选择颜色);colorButton.addActionListener(this); /注册监听器container.add(text);container.add(colorButton);pack();setVisible(true);public void actionPerformed(ActionEvent e)/实现接口ActionListener的方法actionPerformed() if(e.getSource()=colorButton) /判断事件源是否是按钮 Color colorstyle=Color.black; /定义颜色对象,默认颜色为黑色 colorstyle=JColorChooser.showDialog(this,选择颜色,colorstyle); /选择颜色 text.setForeground(colorstyle); /设置文本框的前景颜色为选择的颜色 colorButton.setForeground(colorstyle); /设置按钮的前景色为选择的颜色 public static void main(String args)SimpleEventHandling seh=new SimpleEventHandling();seh.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);从例9.1中可以看出,事件处理的过程是:首先,导入事件处理的软件包java.awt.event,然后定义文本框组件和按钮组件;再将按钮组件注册相应的监听器对象。由于这个例子是实现一个ActionListener接口,所以,注册按钮组件到实现该接口的实例对象。为了让按钮动作发生时,能出现颜色的选择处理,对ActionListener接口的方法actionPerformed()进行定义,来实现颜色选择的动作。9.1.2 事件处理的方式从9.1.1节中,已经了解到在实现事件处理的过程是利用监听器接口实现事件处理,其实就是在同一个类中实现一个事件的接口。对该接口的方法进行定义,实现特定的功能。一般形式如下:public class 事件发生类名 implements 事件监听器接口 public事件发生类名() 组件.addXXXListener(this); /注册到监听器对象,this表示当前对象。 public void 监听器接口说明的方法1() public void 监听器接口说明的方法n() 这种方法的优点在于:可以直接对监听器接口的方法进行处理和调用,并且应用简单方便。但是,这种方式存在一个问题,由于实现接口的方法和定义类的方法处于平行定义,如果要求对多个组件有不同的处理,这种方法无疑会增加阅读程序的困难。Java语言在具体应用中,还允许用其他三种方式来实现事件的处理:利用独立监听器类实现事件处理;利用内部类实现事件处理;以及利用匿名内部类实现事件处理。利用监听器类实现事件处理,就是通过扩展一个监听器接口,定义监听器类,然后对要求发生动作的组件在注册到这个监听器类的对象中。这种方法的一般形式如下:public class 自定义监听类名extends 事件适配器(或 implements事件监听器)/定义监听器类 public void 监听器接口说明的方法1() public void 监听器接口说明的方法n() public class 事件发生类名 /定义事件发生的类 public自定义监听类名() 组件.addXXXListener(new自定义监听类名(); /注册组件到监听器对象 .为了说明问题,我们将例9.1用定义监听器类的方式来改写。例9.2 定义监听器类,实现一个文字框的文字颜色设置的程序。import javax.swing.*; /定义自定义的按钮import java.awt.*;public class SimpleButton extends JButton JTextField text; Color color; public SimpleButton(JTextField text) setText(选择颜色); /设置按钮的文本信息 this.text=text; /接受文本框对象 this.color=Color.black; public void setTextColor(Color c) /设置文本框的前景颜色 text.setForeground(c); import java.awt.event.*; /NewActionListener.javaimport javax.swing.*;import java.awt.*;public class NewActionListener implements ActionListener/定义一个实现ActionListener的事件类 Color colorstyle=Color.black; public void actionPerformed(ActionEvent e) SimpleButton button=(SimpleButton)e.getSource(); if(e.getSource() instanceof JButton) /如果事件源是按钮 colorstyle=JColorChooser.showDialog(null,选择颜色,colorstyle); button.setTextColor(colorstyle); import javax.swing.*; /SimpleEventTest.javaimport java.awt.*;public class SimpleEventTest extends JFrame /定义测试类 private SimpleButton button; private JTextField text; Container container; public SimpleEventTest() super(一个简单示例); container=getContentPane(); container.setLayout(new FlowLayout(); text=new JTextField(颜色选择的示例文字); /定义文本框对象 button=new SimpleButton(text); /定义自定义的按钮 button.addActionListener(new NewActionListener(); /注册监听器 container.add(text); container.add(button); pack(); setVisible(true); public static void main(String args) SimpleEventTest seh=new SimpleEventTest(); seh.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 观察例9.2,该例通过定义一个关于事件的具体处理的监听器类NewActionListener。而在事件发生的类SimpleEventTest中,只需要创建一个监听器类的对象,将自定义SimpleButton组件对象button注册给监听器对象即可。这种事件处理的方式优点在于,处理事件的方法清晰明了,可读性强。另外,允许扩展事件适配器(具体内容见9.3节)来定义新的监听器的类,可以减少不需要的方法的处理。但是,在事件发生的主类中,会增加事件发生对监听器对象的方法的额外调用。为此,Java语言提供的第三种方式:利用内部类实现事件处理。这种方式无疑可以克服上述方法的缺点。这种方法就是将独立的监听器类定义成事件发生类的内部类。形式如下:public class 自定义监听类名 /定义事件发生的类 public自定义监听类名() 组件.addXXXListener(new自定义监听类名(); /注册组件到监听器对象 . class 自定义监听类名extends 事件适配器 (或 implements事件监听器)/定义内部监听器类 public void 监听器接口说明的方法1() public void 监听器接口说明的方法n() /结束内部类为了说明问题,用第三种方法来改写例9.1。具体内容见例9.3。例9.3 定义监听内部类,实现一个文字框的文字颜色设置的程序。import javax.swing.*;import java.awt.*;import java.awt.event.*;public class SimpleEventHandling2 extends JFrame /定义事件发生的类public JTextField text;public JButton colorButton;Container container;public SimpleEventHandling2()super(一个简单示例);container=getContentPane();container.setLayout(new FlowLayout();text=new JTextField(选择颜色的示例文字); /定义文本框colorButton=new JButton(选择颜色); /定义按钮colorButton.addActionListener(new NewActionListener2(); /注册监听器container.add(text);container.add(colorButton);pack();setVisible(true); class NewActionListener2 implements ActionListener /定义内部类 public void actionPerformed(ActionEvent e) if(e.getSource()=colorButton) Color colorstyle=Color.black; colorstyle=JColorChooser.showDialog(null,选择颜色,colorstyle); text.setForeground(colorstyle); colorButton.setForeground(colorstyle); /结束内部类public static void main(String args)SimpleEventHandling2 seh=new SimpleEventHandling2();seh.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);利用内部类来实现事件处理,具有上述两种方法的优点。但是随着发生事件的组件增多,程序会变得比较庞大,增加对程序的理解。为了减少程序代码的长度,以及让发生事件的组件在具体处理的时候更有针对性,可以采用第四种方式:利用匿名内部类实现事件处理。不过,利用匿名内部类更会增加程序阅读的难度。具体实现的情况见例9.4。例9.4 利用匿名内部类实现事件处理的示例。import javax.swing.*;import java.awt.*;import java.awt.event.*;public class SimpleEventHandling3 extends JFramepublic JTextField text;public JButton colorButton;Container container;public SimpleEventHandling3()super(一个简单示例);container=getContentPane();container.setLayout(new FlowLayout();text=new JTextField(选择颜色的示例文字);colorButton=new JButton(选择颜色);colorButton.addActionListener(new ActionListener()/定义匿名内部类public void actionPerformed(ActionEvent e)Color colorstyle=Color.black;if(e.getSource()=colorButton)colorstyle=JColorChooser.showDialog(null,颜色选择,colorstyle);colorButton.setForeground(colorstyle);text.setForeground(colorstyle);); /结束匿名类定义container.add(text);container.add(colorButton);pack();setVisible(true); public static void main(String args)SimpleEventHandling3 seh=new SimpleEventHandling3();seh.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 本节介绍的四种方法各有特点,在具体的应用中依据具体情况采用不同事件处理方式。9.1.3 事件处理类型不同的GUI组件会产生不同的事件类型。根据事件类型的不同,会导致需要监听器对事件处理方法的不同。Java语言根据这些情况,针对不同GUI组件,有不同的事件处理类型。在特定事件处理类型中,特定的事件类对应于特定的事件监听接口。Java语言中提供事件处理的包主要有java.awt.event和javax.swing.event包。其中,java.awt.event包提供了对awt包和swing包常见组件的支持,与事件处理相关常见的的事件类和事件监听器接口见表9-1。至于swing包提供了对高级事件处理。本节只对AWT包的事件处理详细介绍。表9-1 常见的事件类和事件监听接口 事件类事件监听器接口ActionEventActionListenerItemEventItemListenerMouseEventMouseMotionListenerMouseListenerMouseWheelEventMouseWheelListenerKeyEventKeyListenerFocusEventFocusListenerAdjustmentEventAdjustmentLlistenerWindowEventWindowListenerWindowStateListenerWindowFocusListener9.2 常用的事件处理9.2.1 动作事件处理动作事件处理上最简单和最常用的事件处理。当用户点击按钮或在文本框中按回车键或选择菜单项或使用列表等组件时,都可以采用动作事件来处理这些组件引发的动作。动作事件处理涉及到接口ActionListener与动作事件类ActionEvent。通过接口ActionListener可以实现对组件发生动作事件ActionEvent对象的监听与处理。其中,ActionEvent的主要方法见表9-2。表9-2 ActionEvent的主要方法方 法功 能String getActionCommand()获取动作命令字符串int getModifiers()获取事件发生的期间的组合键long getWhen()获取事件发生的时间戳String paramString()获取标识此动作事件的参数字符串实现动作事件,必须依赖于动作事件的监听器ActionListener接口。动作的执行是通过调用监听器对象的方法来实现的。ActionListner接口的主要方法见表9-3。表9-3 ActionListener的主要方法方 法功 能public void actionPerformed(ActionEvent)动作发生时被调用下面通过几个具体例子来说明如何应用动作事件处理具体问题。例9.5 设计一个程序,可以实现一个由文本框和文本区组成的简易聊天室界面,该程序允许用户启动聊天也可以禁止聊天。import javax.swing.*;import java.awt.*;import java.awt.event.*;public class SimpleChatRoom extends JFrame implements ActionListenerJPanel chatPanel; /定义聊天面板; JTextArea displayArea; /定义聊天显示区; JTextField inputText; /定义输入文本框; JButton startButton,stopButton; /定义启用和禁止按钮 JLabel statusLabel; /状态标签 public SimpleChatRoom() setGUIComponent(); getContentPane().setLayout(new BorderLayout(); getContentPane().add(chatPanel,BorderLayout.CENTER); getContentPane().add(statusLabel,BorderLayout.SOUTH); pack(); setVisible(true); public void setGUIComponent() /设置GUI组件 chatPanel=new JPanel(); chatPanel.setLayout(new GridBagLayout(); GridBagConstraints constraints=new GridBagConstraints(); displayArea=new JTextArea(10,20); displayArea.setEditable(false); constraints.gridx=0; constraints.gridy=0; constraints.gridwidth=7; constraints.gridheight=4; chatPanel.add(new JScrollPane(displayArea),constraints); inputText=new JTextField(20); inputText.setEditable(false); inputText.addActionListener(this); /注册到监听器 constraints.gridwidth=7; constraints.gridheight=1; constraints.gridy=GridBagConstraints.RELATIVE; chatPanel.add(inputText,constraints); startButton=new JButton(启用); startButton.addActionListener(this); /注册到监听器 constraints.gridwidth=3; constraints.gridheight=1; constraints.gridy=5; chatPanel.add(startButton,constraints); stopButton=new JButton(禁用); stopButton.setEnabled(false); stopButton.addActionListener(this); /注册到监听器 constraints.gridwidth=3; constraints.gridheight=1; constraints.gridx=GridBagConstraints.RELATIVE; chatPanel.add(stopButton,constraints); statusLabel=new JLabel(初始化状态); public void actionPerformed(ActionEvent e) /处理事件 if(e.getSource()=startButton) /启动聊天 startButton.setEnabled(false); stopButton.setEnabled(true); inputText.setEditable(true); statusLabel.setText(启动状态); 图9-2例9.5的运行结果 else if(e.getSource()=stopButton) /禁止聊天 startButton.setEnabled(true); stopButton.setEnabled(false); inputText.setEditable(false); statusLabel.setText(禁止状态); else if(e.getSource()=inputText) /聊天信息录入 displayArea.append(inputText.getText()+n); inputText.setText(); public static void main(String args) SimpleChatRoom scr=new SimpleChatRoom(); scr.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 9.2.2 鼠标事件处理鼠标是一种最常见的输入方式。用户可以用鼠标绘制图形,利用鼠标实现特殊的控制,例如游戏操作的控制等功能。Java语言中主要提供了三种不同类型的鼠标事件:鼠标键事件、鼠标移动事件和鼠标轮滚动事件。鼠标键事件多用于鼠标的单击处理,鼠标移动事件是用于鼠标移动的处理,至于鼠标轮滚动事件是从JDK1.4后引入的鼠标事件,用于鼠标轮的动作处理。这三种类型的鼠标事件一般是以容器组件作为事件源,它们各有自己的监听器。1 鼠标键事件处理鼠标键事件处理是一种最常见的鼠标事件处理方式。鼠标键事件处理涉及到监听器接口MouseListener和鼠标事件MouseEvent。对于这种事件处理的具体步骤是:(1) 组件通过方法addMouseListener()到注册MouseListener中。允许监听器对象在程序运行过程中监听组件是否有鼠标键事件MouseEvent对象发生。(2) 实现MouseListener接口的所有方法,提供事件发生的具体处理办法。鼠标键事件对应的是事件类MouseEvent,该类的主要方法见表9-4。鼠标键事件对应的监听器接口是MouseListener,这种监听器接口的主要方法见表9-5。表9-4 MouseEvent的主要方法方 法功 能int getButton()获取鼠标按键变更的状态int getClickCount()获取鼠标点击的次数Point getPoint()获取鼠标点击的位置int getX()获取鼠标的X位置int getY()获取鼠标的Y位置String getMouseModifiersText(int)获取控制键与鼠标的组合键的字符串表9-5 MouseListener的方法方 法功 能void mousePressed(MouseEvent)鼠标按下调用void mouseReleased(MouseEvent)鼠标释放调用void mouseEntered(MouseEvent)鼠标进入调用void mouseExited(MouseEvent)鼠标离开调用void mouseClicked(MouseEvent)鼠标点击调用例9.6 设计一个程序,可以获取并显示鼠标位置和鼠标状态。当鼠标按下时,能在当前位置绘制一个正方形。import java.awt.*;import java.awt.event.*;import javax.swing.*;public class MouseStatus extends JFrame implements MouseListenerContainer container;JTextArea displayArea; /定义显示详细信息的文本区JPanel panel; /定义绘制区面板JLabel statusLabel; /定义状态标签public MouseStatus()super(鼠标事件示例);container=getContentPane(); container.setLayout(new BorderLayout();displayArea=new JTextArea(10,20);panel=new JPanel();panel.setSize(100,100);panel.setBackground(Color.yellow);panel.addMouseListener(this); /注册鼠标监听器statusLabel=new JLabel(鼠标初始化状态);container.add(new JScrollPane(displayArea),BorderLayout.WEST);container.add(panel,BorderLayout.CENTER);container.add(statusLabel,BorderLayout.SOUTH); setSize(400,300); setVisible(true);public void mouseEntered(MouseEvent e) /鼠标进入statusLabel.setText(鼠标进入面板);displayArea.append(鼠标进入,X位置:+e.getX()+Y位置:+e.getY()+n);public void mouseExited(MouseEvent e) /鼠标退出statusLabel.setText(鼠标离开面板);displayArea.append(鼠标离开+n);public void mouseClicked(MouseEvent e) /鼠标点击statusLabel.setText(鼠标在面板点击);displayArea.append(鼠标点击,X位置:+e.getX()+Y位置:+e.getY()+n);public void mousePressed(MouseEvent e) /鼠标按下statusLabel.setText(鼠标在面板按下);Graphics g=panel.getGraphics(); /获取图形上下文g.setColor(Color.blue); /设置颜色g.drawRect(e.getX(),e.getY(),40,40); /在当前位置绘制正方形panel.paintComponents(g);displayArea.append(鼠标按下,X位置:+e.getX()+Y位置:+e.getY()+n);public void mouseReleased(MouseEvent e) /鼠标释放statusLabel.setText(鼠标在面板释放);displayArea.append(鼠标释放,X位置:+e.getX()+Y位置:+e.getY()+n);public static void main(String args)MouseStatus ms=new MouseStatus();ms.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);图9-3例9.6的运行结果2 鼠标移动事件处理事件类MouseEvent还对应另一个监听器接口MouseMotionListener。该接口可以实现鼠标的两种运动的处理:鼠标移动处理和鼠标拖动的处理。实现鼠标移动事件处理的一般步骤如下:(1) 组件通过方法addMouseMotionListener()到注册MouseMotionListener中。允许MousMotionListener监听器对象在程序运行过程中监听组件是否有鼠标键事件MouseEvent对象发生。(2) 实现MouseMotionListener接口的所有方法,提供事件发生的具体处理办法。接口MouseMotionListener的方法见表9-6。表9-6 MouseMotionListener的方法方 法功 能void mouseDragged(MouseEvent)鼠标拖动调用void mouseMoved(MouseEvent)鼠标移动调用例9.7 设计一个程序,可以实现文字“Hello, Java世界”随着鼠标移动而移动,如果鼠标拖动的时候,会将文字放大显示。import java.awt.*;import java.awt.event.*;import javax.swing.*;public class MouseMotionText extends JPanel int x=20,y=20; /设置初试坐标 int mode=1; /表示默认绘制模式,1:拖动,2:移动 public MouseMotionText() addMouseMotionListener(new MouseMotionListener()/创建匿名内部类 public void mouseDragged(MouseEvent e) /鼠标拖动 x=e.getX(); /x轴的坐标y=e.getY(); /y轴的坐标 repaint(); public void mouseMoved(MouseEvent e) /鼠标移动 mode=2; /设置为移动模式 x=e.getX(); y=e.getY(); repaint(); ); public void paintComponent(Graphics g) g.clearRect(0,0,400,200); /清屏 if(mode=1) g.setFont(new Font(宋体,Font.BOLD,g.getFont().getSize()+10); draw(g,x,y); public void draw(Graphics g,int x,int y) g.drawString(Hello, Java世界,x,y); pub
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 职工安全健康培训教材
- 2025年排尿障碍患者的康复护理方案模拟测试卷答案及解析
- 2025年影像科医学影像设备操作竞赛答案及解析
- 建筑工人安全操作标准与考核细则
- 2025年中医药食疗养生方案设计与实施考核试卷答案及解析
- 2025年云南省交通运输厅交通工程“银龄工程师”招募笔试备考题库及参考答案详解1套
- 2025年产科紧急情况处理应对对策检测答案及解析
- 地产品牌推广营销方案
- 客户数据隐私保护政策制定
- 2025年卫生防疫科传染病疫情监测处置应急演练试卷答案及解析
- 频谱监测及瞬态信号捕获技术课件
- 宣城万里纸业有限公司年产15万吨高强度瓦楞包装用纸及5万吨纱管纸技改项目环境影响报告书
- 贵州某二级公路施工组织设计KK
- 推广普通话课件
- GB/T 16714-2007连续式粮食干燥机
- 五年级《欧洲民间故事》知识考试题库(含答案)
- 派车单(标准样本)
- 少先队大队委申请表
- 浦东机场手册
- 柴油机负荷特性曲线比较课件
- 《认识液体》-完整版PPT
评论
0/150
提交评论