前面学习的只是如何布置使用 swing控件,可是对它们进行点击等动做时,相应控件没有任何反应。java
因此要给每一个控件添加一个事件处理机制,当咱们(用户)对 Swing组件 进行某些操做时,对应 Swing组件 会自动产生各类事件来响应用户行为。如当用户点击按钮时,Swing组件会产生一个 ActionEvent。web
Swing组件会产生许多事件,如:ActionEvents,ChangeEvents,ItemEvents等,来响应用户的鼠标点击等行为。小程序
动做事件监听器
动做事件监听器是 Swing 中比较经常使用的事件监听器,它的具体信息以下:框架
事件名称:ActionEvent。
事件监听接口: ActionListener。这个接口须要被 须要处理ActionEvent的类实现
事件相关方法:addActionListener() 添加监听,对于须要响应ActionEvent的控件(像须要响应点击的按钮等)要使用这个方法。removeActionListener() 删除监听等…ide
以按钮的单击响应为例编写一个小程序,当鼠标单击按钮时,文本框显示总共单击的次数
具体代码以下:
要导入的类,以后再也不赘述:svg
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); //设置可见 } }
运行结果:
没开始单击时界面
单击1次时界面
单击2次时界面
这是最简单的一种状况,只有一个按钮响应一个事件,可是在实际中,状况不是这么简单。学习
1.因为同一个控件(事件源)上可能发生多种事件,所以,Java 采起了受权模型(Delegation Model),控件(事件源)能够把在其自身上全部可能发生的事件分别受权给不一样的事件处理者(实现各个事件类的接口的类)来处理。eg:spa
//假设有两个分别实现两个不一样事件接口的监听类(伪码,有残缺,举例用) class ActionHander implements ActionListener{} class ChangeHander implements ChangeListener{} Jbutton jbutton; //一个按钮 //按钮上会发生上面两个事件,就分别受权给不一样事件处理者 jbutton1.addActionListener(new ActionHander()); //受权Action事件 jbutton1.addChangeListener(new ChangeHander()); //受权Change事件
2.当多个控件须要响应一个事件的时候,这里有三种方法,以ActionEvent动做事件,和两个按钮为例。当鼠标单击某个按钮时,文本框显示这个按钮总共单击的次数。3d
ActionEvent的三种实现方法
<1>基于if-slse语句的实现code
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); //设置可见 } }
运行结果:
没有开始单击时
第1次单击,单击按钮1
第2次单击,单击按钮1
第3次单击,单击按钮2
第4次单击,单击按钮1
第一种方法,在处理的事件比较少时比较方便,代码集中易于理解。
可是它的缺点也很明显,由于只有一个监听器,当程序比较复杂时,须要大串的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); //设置可见 } }