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. ExoPlayer Talk 01 缓存策略分析与优化

    操作系统:Windows8.1 显卡:Nivida GTX965M 开发工具:Android studio 2.3.3 | ExoPlayer r2.5.1 使用 ExoPlayer已经有一段时间了, ...

  2. VMware Workstation 12 Pro 之安装林耐斯优麒麟 X64系统

    VMware Workstation 12 Pro 之安装林耐斯优麒麟 X64系统... --------------------- 先去官网下载ISO格式的系统安装包:http://www.ubun ...

  3. 《HelloGitHub》第 17 期

    公告 本月 hellogitub.com 动态 服务器迁移到了国内,国内浏览速度有了质的飞跃. 代码重构 项目 运行更加简单,直接 clone.执行安装依赖命令.运行 上线了"我的收藏&qu ...

  4. 通俗语言解释内外网IP与端口映射

    IP:分为外网IP和内网IP 也就是我们说的外网IP属于实体IP 实体IP,它是独一无二的,在网络的世界里,每一部计算机的都有他的位置,一个 IP 就好似一个门牌!例如,你要去百度的网站的话,就要去『 ...

  5. 迈向angularjs2系列(7):表单

    目录 一:校验表单的使用 1.搭建脚手架 2.校验表单的使用 3.select下拉列表的用法 一: 校验表单的使用 对于CRUD型的应用,表单是必备组件. 1.搭建脚手架 git clone http ...

  6. DOM树节点和事件

    一.前言:DOM树节点是JS的基础语句.通过节点,能够取到HTML代码中的任意标签,从而对其进行修改和添加各种视觉效果. 二.DOM树节点    DOM节点分为三大类: 元素节点,属性节点,文本节点  ...

  7. 求最长公共前缀和后缀—基于KMP的next数组

    KMP算法最主要的就是计算next[]算法,但是我们知道next[]求的是当前字符串之前的子字符串的最大前后缀数,但是有的时候我们需要比较字符串中前后缀最大数,比如 LeetCode的shortest ...

  8. 【Linux】ssh免密登录

    一.ssh免密配置 ssh 无密码登录要使用公钥与私钥.linux下可以用用ssh-keygen生成公钥/私钥对,下面我以CentOS为例.有机器A(192.168.1.155),B(192.168. ...

  9. split添加limit参数

    String str = "I love you"; /**这里被分割为I 和love you**/ String[] spiltStr = str.spit(" &qu ...

  10. exjs上传图片异常:com.jspsmart.upload.SmartUploadException: File can't be saved (1120).

    错误: 文件名格式不对:未命??.jpg SmartUpload mySmartUpload = new SmartUpload(); com.jspsmart.upload.File myFile ...