Swing是目前Java中不可缺少的窗口工具组,是用户建立图形化用户界面(GUI)程序的 强大工具。Java Swing组件自动产生各种事件来响应用户行为。如当用户点击按钮或选择菜单项目时,Swing组件会产生一个 ActionEvent。Swing组件会产生许多事件,如ActionEvents,ChangeEvents,ItemEvents等,来响应用户的鼠标点击行为,列表框中值的改变,计时器的开始计时等行为。在Java Swing编程中,通过注册监听器,我们可以监听事件源产生的事件,从而在事件处 理程序中处理我们所需要处理的用户行为。
  
  Java Swing中处理各组件事件的一般步骤是:
  
  1. 新建一个组件(如JButton)。
  
  2. 将该组件添加到相应的面板(如JPanel)。
  
  3. 注册监听器以监听事件源产生的事件(如通过ActionListener来响应用户点击按钮)。
  
  4. 定义处理事件的方法(如在ActionListener中的actionPerformed中定义相应方法)。
  
  以上步骤我们可以用多种方法实现。但人们通常用二种方法。第一种方法是只利用一个监听器以及多个if语句来决定是哪个组件产生的事件;第二种方法是使用多个内部类来响应不同组件产生的各种事件,其具体实现又分两种方式,一种是匿名内部类,一种是一般内部类。
  
   为了说明如何使用上述三种方法实现事件的处理方法,我们建立一个简单的应用程序。该程序界面有两个按钮,当用户点击相应的按钮,就会弹出一个对话框显示相应的内容。通过这个简单程序,你可以实现自己更多、更复杂的用户界面程序。 
  
  首先,我们利用单个监听器来实现该程序。我们定义一个名为Simple1的类来包括所有代码。所有的用户行为(如点击按钮)由一个监听器SimpleListenner中的actionPerformed方法来处理。以下是代码:

 /**
  * Simple1.java - 处理事件的第一种方法
  * 在这个例子中,利用一个ActionListener来监听事件源产生的事件
  * 用一些if语句来决定是哪个事件源
  */
  
  
  import java.awt.*;
  import java.awt.event.*;
  import javax.swing.*;
  
  public class Simple1
  {
       private static JFrame frame; // 定义为静态变量以便main使用
       private static JPanel myPanel; // 该面板用来放置按钮组件
       private JButton button1; // 这里定义按钮组件 
       private JButton button2; // 以便让ActionListener使用
   
       public Simple1() // 构造器, 建立图形界面
       {
           // 新建面板
           myPanel = new JPanel();
           // 新建按钮
           button1 = new JButton("按钮1"); // 新建按钮1
           button2 = new JButton("按钮2");
  
           SimpleListener ourListener = new SimpleListener();
          // 建立一个actionlistener让两个按钮共享
           button1.addActionListener(ourListener);
           button2.addActionListener(ourListener);
  
           myPanel.add(button1); // 添加按钮到面板
           myPanel.add(button2);
       }
  
       private class SimpleListener implements ActionListener
       {
       /**
       * 利用该内部类来监听所有事件源产生的事件
       * 便于处理事件代码模块化
       */
           public void actionPerformed(ActionEvent e)
           {
               // 利用getActionCommand获得按钮名称
               // 也可以利用getSource()来实现
               // if (e.getSource() ==button1)
  
               String buttonName = e.getActionCommand();
               if (buttonName.equals("按钮1"))
               JOptionPane.showMessageDialog(frame,
               "按钮1 被点击");
               else if (buttonName.equals("按钮2"))
               JOptionPane.showMessageDialog(frame,
               "按钮2 被点击");
               else
               JOptionPane.showMessageDialog(frame,
               "Unknown event" );
           }
       }
  
       public static void main(String s[])
       {
           Simple1 gui = new Simple1(); // 新建Simple1组件
           
           frame = new JFrame("Simple1"); // 新建JFrame
           // 处理关闭事件的通常方法
           frame.addWindowListener(new WindowAdapter() {
           public void windowClosing(WindowEvent e)
           {System.exit(0);} });
          
           frame.getContentPane().add(myPanel);
           frame.pack(); 
           frame.setVisible(true);
       }
  }
  

  让我们来看看以上代码是如何工作的。在main方法中,我们定义了一个JFrame,然后将面板Jpanel添加到窗体中,该面板包括两个按钮。相应的变量Frame,button1,button2定义在程序的开头部分。
  
  在程序入口main方法中,首先新建Simple1组件,通过构造器建立用户GUI,定义一个面板Jpanle,,增加两个按钮,然后利用 JButton.addActionListerner将两个按钮加入到一个活动监听器SimpleLister中,最后,两个按钮添加到面板。当GUI 建立后,我们将面板添加到窗体并显示结果。当用户点击按钮时,程序调用actionPerformed方法,通过if语句来判断是哪一个按钮被点击,然后在对话框中显示相应的内容。
  
  利用一个监听器来处理事件的缺点是,当程序比较复杂时,需要一大串的if 语句来实现,程序代码较难阅读与维护。当然,如果处理的事件较少,这种方式比较简单。
  
  通过使用匿名内部类可以解决上述存在的问题。使用简单的匿名内部类作为addActionListener的变量即可。以下是实现代码:

 /**
  * Simple2.java - 处理事件的第二种方法
  * 在这个例子中,利用匿名内部类来监听每一个事件源产生的事件
  * 避免使用一些if语句来决定是哪个事件源
  */
  
  import java.awt.*;
  import java.awt.event.*;
  import javax.swing.*;
  
  public class Simple2
  {
       private static JFrame frame; // 定义为静态变量以便main使用
       private static JPanel myPanel; // 该面板用来放置按钮组件
       private JButton button1; // 这里定义按钮组件 
       private JButton button2; // 以便让ActionListener使用
       
       public Simple2() // 构造器, 建立图形界面
       {
           // 新建面板
           myPanel = new JPanel();
           // 新建按钮
           button1 = new JButton("按钮1"); // 新建按钮1
           button2 = new JButton("按钮2");
          
           // 每一个事件源需要一个监听器
           // 定义一个匿名内部类来监听事件源产生的事件
           button1.addActionListener(
               new ActionListener()
               {
                   public void actionPerformed(ActionEvent e)
                   {
                       JOptionPane.showMessageDialog(frame,"按钮1 被点击");
                   }
               }
           );
          
           button2.addActionListener(
               new ActionListener()
               {
                   public void actionPerformed(ActionEvent e)
                   {
                       JOptionPane.showMessageDialog(frame,"按钮2 被点击");
                   }
               }
           );
          
           myPanel.add(button1); // 添加按钮到面板
           myPanel.add(button2);
        }
          
        public static void main(String s[])
        {
            Simple2 gui = new Simple2(); // 新建Simple2组件
                               
            frame = new JFrame("Simple2"); // 新建JFrame
            // 处理关闭事件的通常方法
            frame.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e)
            {System.exit(0);} });
            frame.getContentPane().add(myPanel);
            frame.pack(); 
            frame.setVisible(true);
        }
  }

  使用匿名内部类同样存在许多另外的问题。首先,根据组件在代码中被定义的不同位置,类的定义以及处理事件的代码将分散在程序的各个部分,不是集中在一块,同样不便于阅读与维护。各事件的处理全部由嵌套的程序块组成,视觉上很难定位程序代码。如果事件处理程序比较复杂,内部类中的代码将变得很长,你将找不到相应的组件定义位置。最后,当工具栏、菜单栏目等需要处理同样的用户行为时,该方法将使代码更难维护。
  
  我们使用一般的命名内部类可以解决以上许多问题。所有的事件处理方法都集中在一块,并且都具有有意义的名称,程序非常容易阅读与维护。单个的事件处理程序也可以被工具栏、菜单栏等重复使用,
  
  以下是实现代码:

 /**
  * Simple3.java - 处理事件的第三种方法
  * For this example, we will use inner member classes to
  * 在这个例子中,利用一般内部类来监听每个事件源产生的事件
  * 该方法避免了第二种方法中由于使用匿名内部类而导致的代码混乱
  * 便于集中处理事件代码
  * 每一个Hander可以被工具栏或菜单多次使用
  */
  import java.awt.*;
  import java.awt.event.*;
  import javax.swing.*;
  
  public class Simple3
  {
       private static JFrame frame; // 定义为静态变量以便main使用
       private static JPanel myPanel; // 该面板用来放置按钮组件
       private JButton button1; // 这里定义按钮组件 
       private JButton button2; // 以便让ActionListener使用
       
       // 利用一般内部类来监听每一个事件源产生的事件如(button1, button2)
       private class Button1Handler implements ActionListener
       {
           public void actionPerformed(ActionEvent e)
           {
               JOptionPane.showMessageDialog(frame,"按钮1 被点击");
           }
       }
       
       private class Button2Handler implements ActionListener
       {
           public void actionPerformed(ActionEvent e)
           {
               JOptionPane.showMessageDialog(frame,"按钮2 被点击");
           }
       }
       
       public Simple3() // // 构造器, 建立图形界面
       {
           // 新建面板
           myPanel = new JPanel();
           // 新建按钮
           button1 = new JButton("按钮1"); // 新建按钮1
           button2 = new JButton("按钮2");
          
           // 对每一个组件注册监听内部类
           button1.addActionListener(new Button1Handler());
           button2.addActionListener(new Button2Handler());
          
           myPanel.add(button1); // 添加按钮到面板
           myPanel.add(button2);
       }
      
       public static void main(String s[])
       {
           Simple3 gui = new Simple3(); // 新建Simple3组件
          
           frame = new JFrame("Simple3"); // 新建JFrame
           // 处理关闭事件的通常方法 
           frame.addWindowListener(new WindowAdapter() {
               public void windowClosing(WindowEvent e)
               {System.exit(0);} });
          
           frame.getContentPane().add(myPanel);
           frame.pack(); 
           frame.setVisible(true);
       }
  }

Java swing: 实现ActionListener监听器的三种途径的更多相关文章

  1. Java中获取键盘输入值的三种方法

    Java中获取键盘输入值的三种方法     Java程序开发过程中,需要从键盘获取输入值是常有的事,但Java它偏偏就没有像c语言给我们提供的scanf(),C++给我们提供的cin()获取键盘输入值 ...

  2. java Data、String、Long三种日期类型之间的相互转换

    java Data.String.Long三种日期类型之间的相互转换      // date类型转换为String类型   // formatType格式为yyyy-MM-dd HH:mm:ss// ...

  3. Java反射获取class对象的三种方式,反射创建对象的两种方式

    Java反射获取class对象的三种方式,反射创建对象的两种方式 1.获取Class对象 在 Java API 中,提供了获取 Class 类对象的三种方法: 第一种,使用 Class.forName ...

  4. droid开发中监听器的三种实现方法(OnClickListener)

    Android开发中监听器的实现有三种方法,对于初学者来说,能够很好地理解这三种方法,将能更好地增进自己对android中监听器的理解. 一.什么是监听器. 监听器是一个存在于View类下的接口,一般 ...

  5. iOS用三种途径实现一方法有多个返回值

    以前觉得这种标题有点偏向于理论,实际开发中怎么会有这种诡异的需求,但是真正遇到了这种硬需求时觉得还是有那么点价值的,理论付诸了实践在此也就做了个整理. 以我私下开发中的一处代码为例,本意是希望有这么一 ...

  6. C#生成XML的三种途径

    C#生成XML的三种途径 为了全面,这里都将XML保存到文件中,有三种生成XML的方式: 1.我认为是最原始,最基本的一种:利用XmlDocument向一个XML文件里写节点,然后再利用XmlDocu ...

  7. 虚拟化x86的三种途径

    虚拟化x86的三种途径 作者:缪天翔链接:https://www.zhihu.com/question/20145026/answer/34527331 x86上的全系统虚拟化有三种主要的途径: 二进 ...

  8. Java中 实现多线程成的三种方式(继承,实现,匿名内部类)

    ---------------------------------------------------------------------------------------------------- ...

  9. Java中OutOfMemoryError(内存溢出)的三种情况及解决办法

    转载自:http://blog.sina.com.cn/s/blog_701c951f0100n1sp.html 相信有一定java开发经验的人或多或少都会遇到OutOfMemoryError的问题, ...

随机推荐

  1. SQL的JOIN语法解析(inner join, left join, right join, full outer join的区别)

    原文链接:http://www.powerxing.com/sql-join/ 总的来说,四种JOIN的使用/区别可以描述为: left join 会从左表(shop)那里返回所有的记录,即使在右表( ...

  2. Android 5.1.1在外置SD卡中创建文件夹

    Android 4.4之后WRITE_MEDIA_STORAGE 权限仅提供给系统应用,不再授予第三方App,WRITE_EXTERNAL_STORAGE 权限,仅仅用于授权用户写 primary e ...

  3. vue.js学习之组件(下篇)

    本文的Demo和源代码已放到GitHub,如果您觉得本篇内容不错,请点个赞,或在GitHub上加个星星! https://github.com/zwl-jasmine95/Vue_test 以下所有知 ...

  4. 像VUE一样写微信小程序-深入研究wepy框架

    像VUE一样写微信小程序-深入研究wepy框架 微信小程序自发布到如今已经有半年多的时间了,凭借微信平台的强大影响力,越来越多企业加入小程序开发. 小程序于M页比相比,有以下优势: 1.小程序拥有更多 ...

  5. volatile可见性的一些认识

    一.前言 volatile的关键词的使用在JVM内存模型中已是老生常谈了,这篇文章主要结合自己对可见性的一些认识和一些直观的例子来谈谈volatile.文章正文大致分为三部分,首先会介绍一下happe ...

  6. Nodejs进阶:使用DiffieHellman密钥交换算法

    ## 简介 Diffie-Hellman(简称DH)是密钥交换算法之一,它的作用是保证通信双方在非安全的信道中安全地交换密钥.目前DH最重要的应用场景之一,就是在HTTPS的握手阶段,客户端.服务端利 ...

  7. JTAG基础知识

    前言 本知识翻译收集来自http://www.fpga4fun.com,版权归原网站所有. 1.什么是JTAG:Joint Test Action Group:联合测试工作组 JTAG是一种IEEE标 ...

  8. Web学习-jsp实现servlet过程赏析

    Jsp在某种程度上就是一种servelt. 来看看tomcat容器如何将jsp页面翻译成一个"servlet". 一. F:\apache-tomcat-6.0.51\work\C ...

  9. 如何为ubuntu server 版本 安装图形界面

    强烈建议使用命令行的交互方式,就算你在server上装了图形界面,但是在Linux上,大部分重要的操作还是要通过命令行的方式进行操作. 如何为ubuntu server 版本 安装图形界面 Ubunt ...

  10. vue.js基础知识篇(5):过渡、Method和Vue实例方法

    第8章:过渡 1.CSS过渡 2.JavaScript过渡 3.渐进过渡 第9章:method Vue.js的事件一般通过v-on指令配置在HTML中,虽然也可以在js的代码中使用原生的addEven ...