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

一、事件和事件源

事件:事件可以定义为程序发生了某些事情的信号
源对象(源组件):能创建一个事件并触发该事件的组件成为源对象
事件类的根类: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.class的类。例如:Test中的A被编译为TestInnerlClassName.class的类。例如:Test中的A被编译为TestA.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
内部类的另一个实际应用是为了避免类命名冲突

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

无敌的黑星星

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值