java丨事件驱动程序设计学习笔记(一)

来源:互联网 发布:淘宝助理顺丰新模板 编辑:程序博客网 时间:2024/05/22 14:32

一、事件和事件源

事件:事件可以定义为程序发生了某些事情的信号
源对象(源组件):能创建一个事件并触发该事件的组件成为源对象
事件类的根类:java.util.EventObject
可以使用EventObject类中的实例方法getSource()获得事件的源对象
如果一个组件可以触发某个事件,那么这个事件的任意子类都可以触发同类型的事件,如因为GUI组件的父类Component可以触发MouseEvent、KeyEvent、FocusEvent和ComponentEvent,所以任意的GUI组件都可以触发上述事件
二、监听器、注册以及处理事件
java使用一种基于委托的模型来处理事件:源对象触发一个事件,对此事件感兴趣的对象会处理它。将对此事件感兴趣的对象称为监听器。
一个对象要称为源对象上的事件监听器,需要具备两个条件:
(1)监听器对象的类必须是相应的事件监听器接口的实例,以确保监听器有处理这个事件的正确方法。
(2)监听器对象必须由源对象注册。注册方法依赖于事件的类型。
下面我们编写一个程序,使用两个按钮控制一个圆的大小

ControlCircle1.java

import javax.swing.*;import java.awt.*;public class ControlCircle1 extends JFrame{    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);//将画布添加到中央    this.add(panel,BorderLayout.SOUTH);//将装有两个按钮的面板添加到SOUTH的位置    }    public static void main(String[] args){    JFrame frame = new ControlCircle1();    frame.setTitle("ControlCircle1");    frame.setLocationRelativeTo(null);    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);    frame.setSize(200,200);    frame.setVisible(true);    }}class CirclePanel extends JPanel{private int radius = 5;//默认的圆的半径/**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和ShrinkListener的监听器类,实现ActionListener
(2)创建两个监听器,并且将它注册到jbtEnlarge和jbtShrink
(3)在CirclePanel中添加一个名为enlarge()的方法来增加半径,添加一个名为shrink()的方法来缩小半径,然后重新绘制面板
(4)实现EnlargeListener中的actionPerformed方法来调用canvas.enlarge()和canvas.shrink()
(5)为了让actionPerformed方法可以访问引用变量canvas,将EnlargeListener定义为ControlCircle2类的内部类。内部类定义在另一个类中。
(6)为了避免编译错误,CirclePanel类现在也定义为ControlCircle2的一个内部类
以下代码实现了通过Enlarge按钮放大圆,通过Shrink按钮缩小圆

ControlCircle2.java

import javax.swing.*;import java.awt.*;import java.awt.event.*;public class ControlCircle2 extends JFrame{    private JButton jbtEnlarge = new JButton("Enlarge");    private JButton jbtShrink = new JButton("Shrink");    private CirclePanel canvas = new CirclePanel();    public ControlCircle2(){        JPanel panel = new JPanel();//use the panel to group buttons        panel.add(jbtEnlarge);        panel.add(jbtShrink);        this.add(canvas,BorderLayout.CENTER);        this.add(panel,BorderLayout.SOUTH);        jbtEnlarge.addActionListener(new EnlargeListener());        jbtShrink.addActionListener(new ShrinkListener());        }        /**Main Method**/        public static void  main(String[] args){            JFrame frame = new ControlCircle2();            frame.setTitle("ControlCircle2");            frame.setLocationRelativeTo(null);            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);            frame.setSize(400,400);            frame.setVisible(true);        }        //定义一个名为EnlargeListener的监听器类,实现ActionListener        class EnlargeListener implements ActionListener{            public void actionPerformed(ActionEvent e){            canvas.enlarge();         }        }        //定义一个名为ShrinkListener的监听器类,实现ActionListener        class ShrinkListener implements ActionListener{            public void actionPerformed(ActionEvent e) {                canvas.shrink();            }        }        class CirclePanel extends JPanel{           private int radius = 5;//默认圆的半径为5           /**Enlarge the circle */           public void enlarge(){               radius++;               repaint();           }           public void shrink() {               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);               }              }  }

原始、放大、缩小

三、内部类
内部类或者嵌套类是定义在另一个类的范围内的类
两个独立的类:

public class Test{    ...}public class A{    ...}

内部类:

public class Test{    ...    //inner class     public class A{    ...    }}

内部类可以像常规类一样使用。如果内部类只是被外部类使用,那就将该类定义为内部类。
一个内部类有如下的特征:
(1)一个内部类被编译成一个名为OuterClassNameInnerlClassName.classTestATest A.class。
(2)内部类可以引用定义在它嵌套的外部类中的数据和方法,所以,不需要将外部类对象的引用传递给内部类的构造方法。因此,内部类可以使程序更加简单和简洁
(3)使用可见性修饰符定义内部类时,遵从和应用与在类成员上一样的可见性规则,
(4)可以将内部类定义为static。一个static内部类可以使用外部类的名字访问。一个static类是不能访问外部类的非静态成员的。
(5)内部类的对象经常在外部类中创建。但是,也可以从另一个类中创建一个内部类的对象。如果该内部类是非静态的,那就必须先创建一个外部类的实例,然后使用下面的语法创建一个内部类的对象:
OuterClass.InnerClass innerObject = outerObject.new InnerClass();
如果内部类是静态的,那么使用下面的语法为它创建一个对象:
OuterClass.InnerClass innerObject = new OuterClass.InnerClass();
内部类的一个简单应用就是将从属类合并到主类中。这可以减少源文件的数量。例如,将类A合并到类Test中,只创建一个源文件Test.java,最终的类文件是Test.class和Test$A.class
内部类的另一个实际应用是为了避免类命名冲突

阅读全文
0 0