package com.lovo.action; import java.awt.event.*; public class TestMain { /* 事件处理,所谓事件就是在GUI界面上发生了一个触发动作, 然后我们的程序根据这个触发动作做出相应的处理。 通常"事件"的概念当中,参与的角色是两方:事件的发起者和 事件的承受者。在GUI中事件的发起者是使用程序的那个人,他 来点击按钮,移动鼠标和敲击键盘。他是不受代码控制的,那么 我们的代码就只能写在事件的承受者上了,比如:在按钮上添加 代码,一旦事件发生就去执行这段特殊代码。大部分编程语言在 设计的时候都采用了这种方式,比如HTML: <input type="button" value="确定" οnclick="调用JS代码"/> Java的GUI在设计"事件处理的时候",使用的是另一种方式---委托事件模型。 在这个模型当中,除了事件的发起者和承受者,多了一个对象"事件的监听者"。 1、发起者仍然是用户,不用写代码; 2、事件的承受者就是GUI的组件或容器; 3、然后有一个专门的监听器对象,我们要把事件发生后要做的事情写在 它身上。 所以,我们要知道的开发步骤: 1、组件或容器负责自身的内容、样式、位置,其他的不管; 2、在监听器上书写事件发生后要执行的代码; 注意:监听器不是万能的,而是各自有各自的职责,处理不同的事件; 比如:ActionListener -- 主要任务的点击事件(通常按钮就用它) KeyListener --- 键盘事件 MouseListener --- 鼠标事件 ...... Java提供的监听器全部都是接口,这些接口里面提供了关于 各种的事件发生以后会去自动调用的方法,当然只有方法的 申明没有方法的实现。 另外为了方便开发人员的操作,多方法的监听器接口,JDK当中还提供了 对应的抽象类---Adaptor---适配器 3、让监听器和被监听的组件和容器进行绑定; */ public static void main(String[] args) { new AlertFrame(); } }
package com.lovo.action; import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; /* 监听器实现的方式一:单独书写一个监听器类 优点: 1、没有额外的语法难度; 2、可以实现一个事件源对应一个监听器类,从而达到职责单一 缺点: 1、由于监听器类是独立的,所以如果要操作除了事件源对象之外的其他 组件或容器对象,必须传参; 2、每个事件源都会对应一个单独的监听器类,会导致我们的类文件数目 增加,不利用我们的工程文件管理。 */ public class MyButtonListener implements ActionListener { private AlertFrame frame; public MyButtonListener(AlertFrame frame){ this.frame = frame; } //参数ActionEvent对象里面系统封装了本次事件发生的一些详细信息 @Override public void actionPerformed(ActionEvent e) { JButton btn = (JButton) e.getSource();//得到事件源对象 if(btn.getText().equals("警报")) { this.frame.getContentP().setBackground(Color.RED); this.frame.getRedBtn().setEnabled(false); this.frame.getGreenBtn().setEnabled(true); }else { this.frame.getContentP().setBackground(Color.GREEN); this.frame.getRedBtn().setEnabled(true); this.frame.getGreenBtn().setEnabled(false); } } }
package com.lovo.action; import javax.swing.*; import java.awt.*; import java.awt.event.*; /* 监听器实现的方式二:让容器对象同时充当监听器对象 优点: 1、代码语法简单; 2、访问当前容器的组件或子容器无需传参 3、没有增加额外的Java类文件,有利于文件管理; 缺点: 由于一个类只能实现一个接口一次,所以只有一个actionPerformed 方法,导致所有的点击事件都要写在这个方法内部,然后用if-else分辨, 违背了单一职责。 */ public class AlertFrame extends JFrame implements ActionListener { private Container contentP; private JButton redBtn; private JButton greenBtn; public AlertFrame(){ this.setSize(500,500); this.setLocationRelativeTo(null); this.setResizable(false); this.addContent(); this.setVisible(true); } private void addContent(){ this.contentP = this.getContentPane(); this.contentP.setLayout(new FlowLayout()); this.contentP.setBackground(Color.GREEN); //监听器实现一的绑定代码 // //产生的是承受者对象(事件源对象) // this.redBtn = new JButton("警报"); // this.redBtn.setActionCommand("red"); // //产生的是监听器对象 // MyButtonListener myButtonListener = new MyButtonListener(this); // //让事件源对象绑定了监听器对象 // this.redBtn.addActionListener(myButtonListener); // // this.greenBtn = new JButton("安全"); // this.greenBtn.setEnabled(false); // this.greenBtn.addActionListener(myButtonListener); //监听器实现二的绑定代码 // //产生的是承受者对象(事件源对象) // this.redBtn = new JButton("警报"); // this.greenBtn = new JButton("安全"); // this.greenBtn.setEnabled(false); // //不需要new新的监听器对象,因为当前容器对象就是监听器对象 // this.redBtn.addActionListener(this); // this.greenBtn.addActionListener(this); //监听器实现方式三的绑定代码 //产生的是承受者对象(事件源对象) this.redBtn = new JButton("警报"); this.greenBtn = new JButton("安全"); this.greenBtn.setEnabled(false); /* 在事件源绑定监听器对象的同时,完成监听器类的实现。 使用匿名内部类的语法。 先说这种方式的优劣: 1、访问当前容器的组件或子容器无需传参 2、没有增加额外的Java类文件,有利于文件管理 3、职责单一,每个组件都有自己的监听器类 唯一的缺点就是:匿名内部类的语法问题 1、 new 接口(){ 声明属性; 重写方法; 新增方法; } 2、 匿名内部类的this 和 外部类的this之间的区别 3、匿名内部类如果要操作它所在外部类的方法的局部变量, 只能把该局部变量当成常量(也就是只能访问不能修改它的值) */ this.redBtn.addActionListener(new ActionListener(){ @Override public void actionPerformed(ActionEvent e) { AlertFrame.this.contentP.setBackground(Color.RED); AlertFrame.this.redBtn.setEnabled(false); AlertFrame.this.greenBtn.setEnabled(true); } }); this.greenBtn.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { AlertFrame.this.contentP.setBackground(Color.GREEN); AlertFrame.this.redBtn.setEnabled(true); AlertFrame.this.greenBtn.setEnabled(false); } }); this.contentP.add(this.redBtn); this.contentP.add(this.greenBtn); this.addWindowListener(new WindowListener() { @Override public void windowOpened(WindowEvent e) { System.out.println("窗体打开"); } @Override public void windowClosing(WindowEvent e) { } @Override public void windowClosed(WindowEvent e) { System.out.println("窗体关闭"); } @Override public void windowIconified(WindowEvent e) { System.out.println("窗体最小化"); } @Override public void windowDeiconified(WindowEvent e) { System.out.println("窗体非最小化"); } @Override public void windowActivated(WindowEvent e) { System.out.println("窗体激活"); } @Override public void windowDeactivated(WindowEvent e) { System.out.println("窗体非激活"); } }); } public Container getContentP() { return contentP; } public void setContentP(Container contentP) { this.contentP = contentP; } public JButton getRedBtn() { return redBtn; } public void setRedBtn(JButton redBtn) { this.redBtn = redBtn; } public JButton getGreenBtn() { return greenBtn; } public void setGreenBtn(JButton greenBtn) { this.greenBtn = greenBtn; } @Override public void actionPerformed(ActionEvent e) { JButton btn = (JButton) e.getSource();//得到事件源对象 if(btn.getText().equals("警报")) { this.contentP.setBackground(Color.RED); this.redBtn.setEnabled(false); this.greenBtn.setEnabled(true); }else { this.contentP.setBackground(Color.GREEN); this.redBtn.setEnabled(true); this.greenBtn.setEnabled(false); } } }