前面学习的只是如何布置使用 swing控件,但是对它们进行点击等动作时,相应控件没有任何反应。

所以要给每个控件添加一个事件处理机制,当我们(用户)对 Swing组件 进行某些操作时,对应 Swing组件 会自动产生各种事件来响应用户行为。如当用户点击按钮时,Swing组件会产生一个 ActionEvent。

Swing组件会产生许多事件,如:ActionEvents,ChangeEvents,ItemEvents等,来响应用户的鼠标点击等行为。

动作事件监听器
动作事件监听器是 Swing 中比较常用的事件监听器,它的具体信息如下:

事件名称:ActionEvent。
事件监听接口: ActionListener。这个接口需要被 需要处理ActionEvent的类实现
事件相关方法:addActionListener() 添加监听,对于需要响应ActionEvent的控件(像需要响应点击的按钮等)要使用这个方法。removeActionListener() 删除监听等…

以按钮的单击响应为例编写一个小程序,当鼠标单击按钮时,文本框显示总共单击的次数
具体代码如下:
要导入的类,之后不再赘述:

import javax.swing.JPanel; //中间容器 (嵌板)最常用的面板
import javax.swing.JButton;  //按钮
import javax.swing.JFrame;   //顶层容器 (框架)
import javax.swing.JTextField;  //文本框实现类
import java.awt.event.ActionEvent;   //动作事件
import java.awt.event.ActionListener;  //动作事件监听接口
public class text_ ActionEvent
{
	static int clicks = 0;  //记录点击次数
	public static void main(String[] args) 
	{
		JFrame jframe = new JFrame("动作监听");  //窗口
		jframe.setSize(200, 100);   //设置窗口大小
		JPanel jpanel1 = new JPanel();  //面板
		JButton jbutton1 = new JButton("按钮1");  //按钮1
		JTextField jtextfield1 = new JTextField("",15);  //用于显示的文本框,为15列
		
		//创建响应动作监听的类,它需要重写ActionListener接口的actionPerformed()方法
		class jbutton1hander implements ActionListener
	    {
	        @Override
	        public void actionPerformed(ActionEvent e)
	        {
	        	jtextfield1.setText("按钮1被单击 " + (++clicks) + " 次");
	        	//当单击设置了动作响应的按钮的时候,会显示单击的总次数
	        }
	    }
		
		jbutton1.addActionListener(new jbutton1hander()); //这句话很关键,添加动作监听器
		jpanel1.add(jtextfield1);  //文本框添加入面板
		jpanel1.add(jbutton1);    //按钮1添加入面板
		jframe.add(jpanel1);    //面板添加入窗口
		
		jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//设置关闭时操作
		jframe.setVisible(true);   //设置可见
	}
}

运行结果:

没开始单击时界面

java 主动触发事件 java动作事件_文本框


单击1次时界面

java 主动触发事件 java动作事件_java_02


单击2次时界面

java 主动触发事件 java动作事件_文本框_03


这是最简单的一种情况,只有一个按钮响应一个事件,但是在实际中,情况不是这么简单。

1.由于同一个控件(事件源)上可能发生多种事件,因此,Java 采取了授权模型(Delegation Model),控件(事件源)可以把在其自身上所有可能发生的事件分别授权给不同的事件处理者(实现各个事件类的接口的类)来处理。eg:

//假设有两个分别实现两个不同事件接口的监听类(伪码,有残缺,举例用)
class ActionHander implements ActionListener{}
class ChangeHander implements ChangeListener{}
Jbutton jbutton; //一个按钮
//按钮上会发生上面两个事件,就分别授权给不同事件处理者
jbutton1.addActionListener(new ActionHander());  //授权Action事件
jbutton1.addChangeListener(new ChangeHander());  //授权Change事件

2.当多个控件需要响应一个事件的时候,这里有三种方法,以ActionEvent动作事件,和两个按钮为例。当鼠标单击某个按钮时,文本框显示这个按钮总共单击的次数。

ActionEvent的三种实现方法
<1>基于if-slse语句的实现

public class text_ ActionEvent
{
	static int clicks1 = 0;  //用于保存按钮1单击次数
	static int clicks2 = 0;  //用于保存按钮2单击次数
	public static void main(String[] args) 
	{
		JFrame jframe = new JFrame("动作监听");  //窗口
		jframe.setSize(200, 100);  //设置窗口大小
		JPanel jpanel1 = new JPanel();  //面板
		JButton jbutton1 = new JButton("按钮1");  //按钮1
		JButton jbutton2 = new JButton("按钮2");  //按钮2
		JTextField jtextfield1 = new JTextField("",15);  //用于显示的文本框,为15列
		
		//创建响应动作监听的类,它需要重写ActionListener接口的actionPerformed()方法
		class jbutton1hander implements ActionListener
	    {
	        @Override
	        public void actionPerformed(ActionEvent e)
	        {
	        //下面是重点
	        	String name = e.getActionCommand();   //这个方法用于获取动作命令
	            if(name.equals("按钮1"))
	            {
	            	jtextfield1.setText("按钮1被单击 " + (++clicks1) + " 次");
	            }
	            else
	            {
	            	jtextfield1.setText("按钮2被单击 " + (++clicks2) + " 次");
	            }  
	        }
	    }
		jbutton1.addActionListener(new jbutton1hander()); //这句话很关键,添加动作监听器
		jbutton2.addActionListener(new jbutton1hander()); //两个按钮添加同一个动作监听器
		
		jpanel1.add(jtextfield1);  //文本框添加入面板
		jpanel1.add(jbutton1);    //按钮1添加入面板
		jpanel1.add(jbutton2);    //按钮2添加入面板
		jframe.add(jpanel1);    //面板添加入窗口
		
		jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//设置关闭时操作
		jframe.setVisible(true);   //设置可见
	}
}

运行结果:

没有开始单击时

java 主动触发事件 java动作事件_java_04


第1次单击,单击按钮1

java 主动触发事件 java动作事件_控件_05


第2次单击,单击按钮1

java 主动触发事件 java动作事件_java 主动触发事件_06


第3次单击,单击按钮2

java 主动触发事件 java动作事件_java 主动触发事件_07


第4次单击,单击按钮1

java 主动触发事件 java动作事件_控件_08


第一种方法,在处理的事件比较少时比较方便,代码集中易于理解。

但是它的缺点也很明显,因为只有一个监听器,当程序比较复杂时,需要大串的if-else语句来实现,程序代码就变得难阅读与维护。

<2>使用匿名内部类的实现

public class text_ ActionEvent
{
	static int clicks1 = 0;   //记录按钮1的点击次数
	static int clicks2 = 0;   //记录按钮2的点击次数
	public static void main(String[] args) 
	{
		JFrame jframe = new JFrame("动作监听");  //窗口
		jframe.setSize(200, 100);   //设置窗口大小
		JPanel jpanel1 = new JPanel();  //面板
		JButton jbutton1 = new JButton("按钮1");  //按钮1
		JButton jbutton2 = new JButton("按钮2");  //按钮1
		JTextField jtextfield1 = new JTextField("",15);  //用于显示的文本框,为15列
		//下面很关键
		//使用匿名内部类添加监听器
		jbutton1.addActionListener
		(
			new ActionListener()  //需要实现的接口
			{
				@Override        //必须重写ActionListener接口的actionPerformed方法
				public void actionPerformed(ActionEvent e)
				{
					jtextfield1.setText("按钮1被单击 " + (++clicks1) + " 次");
				}
			}
		);
		
		jbutton2.addActionListener
		(
			new ActionListener()  //需要实现的接口
			{
				@Override        //必须重写ActionListener接口的actionPerformed方法
				public void actionPerformed(ActionEvent e)
				{
					jtextfield1.setText("按钮2被单击 " + (++clicks2) + " 次");
				}
			}
		);
		
		jpanel1.add(jtextfield1);  //文本框添加入面板
		jpanel1.add(jbutton1);    //按钮1添加入面板
		jpanel1.add(jbutton2);    //按钮2添加入面板
		jframe.add(jpanel1);    //面板添加入窗口
		
		jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//设置关闭时操作
		jframe.setVisible(true);   //设置可见
	}
}

运行结果同上不再赘述

第二种方法也会出现一定的问题,现实中,因为整个程序中的组件不是全部定义在一起的,当组件变多,分散在程序中,也不便于阅读和修改。

<3>使用一般的命名内部类的实现

public class text_ ActionEvent
{
	static int clicks1 = 0;  //记录按钮1的单击次数
	static int clicks2 = 0;  //记录按钮2的单击次数
	public static void main(String[] args) 
	{
		JFrame jframe = new JFrame("动作监听");  //窗口
		jframe.setSize(200, 100);   //设置窗口大小
		JPanel jpanel1 = new JPanel();  //面板
		JButton jbutton1 = new JButton("按钮1");  //按钮1
		JButton jbutton2 = new JButton("按钮2");  //按钮1
		JTextField jtextfield1 = new JTextField("",15);  //用于显示的文本框,为15列
		
		//下面很关键
		//使用一般类创建动作监听者
		class jbutton1Handler implements ActionListener
		{
			@Override        //必须重写ActionListener接口的actionPerformed方法
			public void actionPerformed(ActionEvent e)
			{
				jtextfield1.setText("按钮1被单击 " + (++clicks1) + " 次");
			}
		}
		
		class jbutton2Handler implements ActionListener
		{
			@Override        //必须重写ActionListener接口的actionPerformed方法
			public void actionPerformed(ActionEvent e)
			{
				jtextfield1.setText("按钮2被单击 " + (++clicks2) + " 次");
			}
		}
		
		//按钮分别添加不同动作监听者
		jbutton1.addActionListener(new jbutton1Handler());
		jbutton2.addActionListener(new jbutton2Handler());
		
		jpanel1.add(jtextfield1);  //文本框添加入面板
		jpanel1.add(jbutton1);    //按钮1添加入面板
		jpanel1.add(jbutton2);    //按钮2添加入面板
		jframe.add(jpanel1);    //面板添加入窗口
		
		jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//设置关闭时操作
		jframe.setVisible(true);   //设置可见
	}
}