事件驱动程序设计
来源:互联网 发布:datagridview添加数据 编辑:程序博客网 时间:2024/05/01 23:47
事件和事件源
运行java图形用户界面程序时,程序与用户进行交互,事件驱动程序的执行.事件(event)可以定义为程序发生了某些事情的信号.外部用户动作和内部程序动作都可以触发事件,外部用户动作的例子有移动鼠标,点击按钮和敲击键盘等,而内部程序动作的例子有定时器.程序可以选择响应事件或忽略事件.
能创建一个事件并触发该事件的组件称为源对象(source object)或源组件(source component).例如,按钮是按钮点击动作事件的源对象.一个事件是事件类的实例.事件类的根类是java.util.EventObject.
事件对象包含与事物相关的一切属性.可以使用EventObject类中的实例方法getSource()获得事件的源对象.EventObject类的子类处理特定类型的事件,例如,动作事件,窗口事件,组件事件,鼠标事件以及按键事件.
外部动作用户,源对象和事件类型
注意:如果一个组件可以触发某个事件,那么这个组件的任意子类都可以触发同类型的事件.例如,每个GUI组件都可以触发MouseEvent,KeyEvent,FocusEvent和ComponentEvent,因为Component是所有GUI组件的父类.
注意:上图除了ListSelectionEvent和ChangeEvent之外的所有事件类都包括在java.awt.event包中,ListSelectionEvent和ChangeEvent在javax.swing.event包中.AWT是为AWT组件设计的,但是许多Swing组件都会触发它们.
监听器,注册以及处理事件
Java使用一种基于委托的模型来处理事件:源对象触发一个事件,对此事件感兴趣的对象会处理它.将对此事件感兴趣的对象称为监听器(listener).一个对象要成为源对象上的事件监听器,需要具备两个条件:
1.监听器对象的类必须是相应的事件监听器接口的实例,以确保监听器有处理这个事件的正确方法.Java为每一种类型的事件都提供个监听器接口.通常,事件XEvent的监听器接口命名为XListener,监听器MouseMotionListener例外.例如,事件ActionEvent对应的监听器接口是ActionListener,ActionEvent的每个监听器都因该实现ActionListener接口.事件类型,对应的监听器接口以及定义在监听器接口中的方法.包含处理事件的监听器接口称为处理器(handler)的方法.
2.监听器对象必须由源对象注册.注册方法依赖与事件的类型.如果事件类型是ActionEvent,那么对应的注册方法是addActionListener.一般来说,XEvent的注册方法命名为addXListener.一个源对象可以触发几种类型的事件.一个源对象针对每个事件都维护着一个注册的监听器列表,通过调用监听器对象上的处理器来通知所有注册的监听器响应这个事件,
JButton jbtOK = new JButton("OK");ActionListener listener1 = new OKListenerClass();jbtOK.addActionListener(listener1);
点击该按钮时,JButton对象触发一个ActionEvent,然后将它作为参数传递以调用监听器的actionPerformed方法来处理这个事件
事件,事件监听器和监听器方法
现在我们可以编写一个程序,使用两个按钮控制一个圆的大小
**ControlCircle1.java代码:**package chapter16;import javax.swing.*;import java.awt.*;public class ControlCircle1 extends JFrame{ /** * */ private static final long serialVersionUID = 1L; private JButton jbtEnlarge = new JButton("Enlarge"); private JButton jbtShrink = new JButton("Shrink"); private CirclePanel canvas = new CirclePanel(); public ControlCircle1() { JPanel panel = new JPanel();//Use the panel to group buttons panel.add(jbtEnlarge); panel.add(jbtShrink); this.add(canvas,BorderLayout.CENTER);//Add canvas to center this.add(panel, BorderLayout.SOUTH);//Add buttons to the frame } public static void main(String[] args) { JFrame frame = new ControlCircle1(); frame.setTitle("ControlCircle1"); frame.setLocationRelativeTo(null); frame.setSize(200, 200); frame.setVisible(true); }}class CirclePanel extends JPanel{ /** * */ private static final long serialVersionUID = 1L; private int radius = 5;//Default circle radius /*Repaint重画 the circle*/ protected void paintComponent(Graphics g) { super.paintComponent(g); g.drawOval(getWidth()/2-radius, getHeight()/2-radius, 2*radius, 2*radius); }}
运行结果,但不能扩大缩小圆的大小:
如何使用按钮放大和缩小这个圆呢?当点击Enlarge按钮时,希望能用一个比较大的半径来重新绘制这个圆。该如何完成它呢?
1.定义一个名为EnlargeListener的监听器类,实现ActionListener.
2.创建一个监听器,并且将它注册到jdtEnlarge.
3.在CirclePanel中添加一个名为enlarge()的方法来增加半径,然后重新绘制面板.
4.实现EnlargeListener中的actionPerformed方法来调用canvas.enlarge().
5.为了让actionPerformed方法可以访问引用变量canvas,将EnlargeListener定义为ControlCircle2类的内部类.内部类定义在另一个类中
6.为了避免编译错误,CirclePanel类现在也定义为ControlCircle2的一个内部类.
package chapter16;import javax.swing.*;import java.awt.*;import java.awt.event.*;public class ControlCircle2 extends JFrame{ private static final long serialVersionUID = 1L; private JButton jbtEnlarge = new JButton("Enlarge"); private JButton jbtShrink = new JButton("Shrink"); private CirclePanel canvas = new CirclePanel(); public ControlCircle2() { JPanel panel = new JPanel(); panel.add(jbtEnlarge); panel.add(jbtShrink); this.add(canvas,BorderLayout.CENTER);//Add canvas to center this.add(panel, BorderLayout.SOUTH);//Add buttons to the frame jbtEnlarge.addActionListener(new EnlargeListener()); } public static void main(String[] args) { JFrame frame = new ControlCircle2(); frame.setTitle("ControlCircle2"); frame.setLocationRelativeTo(null); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setSize(200, 200); frame.setVisible(true); } class EnlargeListener implements ActionListener//Inner class { public void actionPerformed(ActionEvent e) { canvas.enlarge(); } } class CirclePanel extends JPanel//Inner class { private static final long serialVersionUID = 1L; private int radius = 5;//Default circle radius /*Enlarge the circle*/ public void enlarge() { radius++; repaint(); } /*Repaint the circle*/ protected void paintComponent(Graphics g) { super.paintComponent(g); g.drawOval(getWidth()/2-radius, getHeight()/2-radius, 2*radius, 2*radius); } }}
内部类
内部类(inner class)或者潜套类(nested class)是定义在另一个类的范围的类.如下图a中的代码定义了两个独立的类:Test和A.图b的代码定义A为Test的一个内部类.
图c中定义在OuterClass中的InnerClass类是内部类的另一个例子.内部类可以像常规类一样使用.通常,如果内部类只是被外部类使用,那就将该类定义为内部类.一个内部类有如下特征:
1.一个内部类被编译成一个名为OuterClassName$InnerClassName.class的类.例如,在图b中Test中的内部类A被编译成Test$A.class
2.内部类可以引用定义在它嵌套的外部类中的数据和方法,所以,不需要将外部类对象的引用传递个内部类的构造方法.因为这个原因,内部类可以使程序更加简单和简洁.
3.使用可见性修饰符定义内部类时,遵从和应用与在类成员上一样的可见性规则.
4.可以将内部类定义为static,一个static内部类可以使用外部类的名字访问.一个static类是不能访问外部类的非静态成员的.
5.内部类的对象经常在外部类中创建.但是,也可以从另一个类中创建一个内部类的对象。如果该内部类是非静态的,就必须先创建一个外部类的实例,然后使用下面的语法创建一个内部类的对象:
OuterClass.InnerClass innerObject = outerObject.new InnerClass();
如果内部类是静态的,那么使用下面的语法为它创建一个对象:
OuterClass.InnerClass innerObject = new OuterClass.InnerClass();
- 事件驱动程序设计
- [Java]事件驱动程序设计
- 事件驱动程序设计-窗口事件
- 事件驱动程序设计学习笔记
- 第16章 事件驱动程序设计
- VB.NET之旅-事件驱动程序设计
- Java学习笔记----事件驱动程序设计
- 【JAVA语言程序设计基础篇】--事件驱动程序设计--鼠标事件
- 【JAVA语言程序设计基础篇】--事件驱动程序设计--键盘事件
- 【JAVA语言程序设计基础篇】--事件驱动程序设计--键盘事件
- 【JAVA语言程序设计基础篇】--事件驱动程序设计--窗口事件
- 【JAVA语言程序设计基础篇】--事件驱动程序设计--匿名类监听器
- 【JAVA语言程序设计基础篇】--事件驱动程序设计--贷款计算器
- 【JAVA语言程序设计基础篇】--事件驱动程序设计--setActionCommand()
- 【JAVA语言程序设计基础篇】--事件驱动程序设计--匿名类监听器
- 【JAVA语言程序设计基础篇】--事件驱动程序设计--几个问题
- java丨事件驱动程序设计学习笔记(一)
- java丨事件驱动程序设计学习笔记(二)
- 全选和反选
- java多线程开发基础
- 如何方便快速在指定文件夹打开命令行
- 瀑布流
- mysql 查询基础知识
- 事件驱动程序设计
- 在oracle下触发器实现主键自增
- DocumentFragment
- 从锦绣未央讲起
- 懒加载
- IE/FF/Chrome下document.documentElement和document.body的 scrollHeight/scrollTop/clientHeight 以及判断滚动条是否已拉
- 原型模式(Prototype)
- 6、适配器模式(Adapter)
- 7、装饰模式(Decorator)