`

(转) Swing事件处理

 
阅读更多

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语句来决定是哪个组件产生的事件;第二种方法是使用多个内部类来响应不同组件产生的各种事件,其具体实现又细分为两种方式:一种是匿名内部类,一种是一般内部类。

为了说明如何使用上述三种方法实现事件的处理方法,我们建立一个简单的应用程序。该程序界面有两个按钮,当用户点击相应的按钮,就会弹出一个对话框显示相应的内容。通过这个简单的程序,你可以了解Swing中事情处理的机制,从而实现更多、更复杂的用户界面程序。

首先,我们利用单个监听器来实现该程序。我们定义一个名为Simple1的类来包括所有代码。所有的用户行为(如点击按钮)由一个监听器SimpleListenner中的actionPerformed方法来处理。以下是实现代码:

package org.leno.swing.demo2;

/*

* Simple1.java - 处理事件的第一种方法

*    在这个例子中,利用一个ActionListener来监听事件源产生的事件

*    用一些if语句来决定是哪个事件源

*/

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的参数即可。以下是实现代码:

package org.leno.swing.demo2;

/*

* Simple2.java - 处理事件的第二种方法

*    在这个例子中,利用匿名内部类来监听每一个事件源产生的事件

*    避免使用一些if语句来决定是哪个事件源

*/

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);

       }
}

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

我们使用一般的命名内部类可以解决以上许多问题。所有的事件处理方法都集中在一块,并且都具有有意义的名称,程序非常容易阅读与维护。单个的事件处理程序也可以被工具栏、菜单栏等重复使用,以下是实现代码:

package org.leno.swing.demo2;

/*

* Simple3.java - 处理事件的第三种方法

*    For this example, we will use inner member classes to

*    在这个例子中,利用一般内部类来监听每个事件源产生的事件

*    该方法避免了第二种方法中由于使用匿名内部类而导致的代码混乱

*    便于集中处理事件代码

*    每一个Hander可以被工具栏或菜单多次使用

*/

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中三种事件处理的方式,其中利用一般内部类来实现的方法,从代码书写、阅读、维护以及程序的可扩展性角度来看,最为值得推荐。

分享到:
评论

相关推荐

    swing窗口旋转关闭

    以上就是关于Swing窗口旋转关闭的相关知识点,包括Swing窗口的基本创建、使用`AffineTransform`进行2D旋转、设置窗口位置以及处理窗口关闭事件。通过这些技术,你可以创建出具有动态效果和自定义行为的Swing应用程序...

    Swing插件下载,swing下载,java-swing下载,swing-plugin

    Swing库包含了各种组件类、布局管理器、事件处理机制等,这些都是创建GUI应用的关键组成部分。 "jigloo_464"可能是Jigloo的某个版本号。Jigloo是一款基于Swing的GUI设计器,它允许开发者通过直观的拖放界面来构建和...

    图形用户界面设计与事件处理

    总之,图形用户界面设计与事件处理是Java开发中必不可少的技能,掌握了AWT和Swing,开发者就能创建出功能强大、用户友好的应用程序。无论是组件的选择、事件的处理还是布局的管理,都需要深入理解和实践,才能打造出...

    java swing

    1. **键盘事件处理**:Swing能够捕获用户的键盘输入,并将其转换为应用程序可以理解的事件。 2. **颜色控制**:Swing允许开发者轻松地更改UI的颜色方案。 3. **文本组件**:Swing提供了多种文本组件,如文本框、文本...

    java实验报告———JavaSwing编程.pdf

    - 事件驱动编程:Swing基于事件模型,报告可能包含对事件监听器和事件处理的讲解,以及如何编写响应用户操作的代码。 - GUI设计原则:实验报告中可能探讨了设计良好GUI的原则,例如布局的一致性、简洁性和用户友好...

    Swing拖拽(文件拖入JEditorPane)

    接收控件的DropTargetDragEvent和DropTargetDropEvent事件处理函数需要解析这些路径,并根据需求进行相应的操作,比如打开文件或显示文件路径。 4. **实现步骤**: - **注册DragSource**:为你要拖动的组件注册...

    java Swing读取图片

    总之,Java Swing提供了方便的方式来读取和显示图片,无论是简单的展示还是复杂的图像处理,都能满足需求。结合`ImageIcon`、`BufferedImage`和Swing的组件,我们可以创建出富有交互性的图像应用。在实际开发中,要...

    java魔方小游戏(swing)

    通过这款Java魔方小游戏,我们可以学习到Swing库的使用、GUI设计、事件处理、算法实现以及软件工程中的许多实践原则。对于想要提升Java GUI编程能力或对游戏开发感兴趣的开发者来说,这是一个很好的学习项目。

    The Definitive Guide to Java Swing Third Edition

    - **事件处理**:Swing 提供了强大的事件处理机制,包括但不限于: - **ActionListener**:处理按钮点击等动作。 - **ItemListener**:处理复选框或选择框的改变。 - **DocumentListener**:处理文本字段的变化。...

    java swing拖放功能

    Java Swing 是 Java 语言中的一种图形用户界面(GUI)工具包,提供了丰富的可视组件和事件处理机制。其中,拖放(Drag and Drop)功能是 Java Swing 中的一种重要功能,允许用户在应用程序中实现拖放操作。在本文中...

    java swing深入学习例子

    随着对Swing的理解加深,我们将学习事件处理机制,包括事件监听器和适配器,例如ActionListener、MouseListener等,以及如何处理用户交互。中级阶段还会涉及模型-视图-控制器(MVC)设计模式,Swing中的许多组件遵循...

    javaswing课程设计——课程表

    Swing是基于事件驱动模型的,也就是说,用户在界面上的操作会触发特定的事件,程序通过监听这些事件并做出响应。例如,点击按钮就是一个事件,程序可以定义一个事件处理器来处理这个点击事件。 在课程表应用中,...

    java swing模拟键盘

    在开发过程中,你可能需要对Java Swing API有深入的理解,包括组件、事件处理、布局管理等方面。同时,为了在iPad或其他移动设备上运行,你可能还需要考虑使用JavaFX或第三方库,如RoboVM,将Java应用程序转换为iOS...

    swing 鼠标绘画

    通过实践"Swing鼠标绘画",初学者可以深入理解Swing组件、事件处理以及图形绘制的基本原理,这对于进一步学习Java GUI编程和Swing应用开发大有裨益。同时,这也是一个很好的练习,可以帮助开发者提升解决问题和实际...

    Java Swing 个人通讯录

    Java Swing 是Java平台上的一个图形用户界面(GUI...总的来说,这个“Java Swing 个人通讯录”项目涵盖了Java GUI编程、对象序列化、事件处理、MVC设计模式等多个重要知识点,是学习和实践Java桌面应用开发的很好实例。

    swing rich client

    Swing还支持事件处理,使得用户与界面的交互变得简单易行。 在文件名“LayeredPanes”中,我们可以推测这个压缩包可能包含了一些关于JLayeredPane的示例代码或教程。JLayeredPane是Swing中的一个特殊容器,它可以...

    组件模型与双事件处理线程

    组件模型与双事件处理线程是Java GUI编程中的重要概念,尤其在Swing库中扮演着核心角色。本文将深入探讨这两个主题,并结合一个图片文件`swing1.png`,推测可能是一个示例图像,用于说明相关概念。 首先,组件模型...

    JavaSwing实现简单计算器

    通过学习和实践这个"JavaSwing实现简单计算器"项目,开发者不仅可以熟悉Swing的基本用法,还能提升对事件处理、字符串解析、异常处理等核心Java编程概念的理解。同时,这也为开发更复杂的桌面应用程序奠定了基础。

    java swing 日期datepicker组件使用

    4. **Swing事件处理**:为了响应用户在DatePicker上的操作,如选择日期,我们需要添加事件监听器。这通常通过实现`ActionListener`接口或者使用`PropertyChangeListener`来实现,当日期改变时,会触发相应的方法,...

Global site tag (gtag.js) - Google Analytics