[疯狂Java]监听器的实现:内部(闭包)、反射、外部
来源:互联网 发布:pdf修改软件绿色版 编辑:程序博客网 时间:2024/05/22 02:09
1. 用内部类和闭包实现监听器:
1) 之前讲的所有形式都是内部类实现监听器,即在类内部定义一个监听器;
2) 但最常用的还是闭包了,即匿名内部类和Lambda表达式:
i. 因为监听器通常都是临时使用的代码,往往不会在其它地方被复用;
ii. 即使要复用肯定会被抽象到业务逻辑层面单独编写;
iii. 因此通常为了方便会用匿名内部类或者Lambda表达式来实现监听器;
3) 匿名内部类示例:
Frame f = new Frame("Test");f.addWindowListener(new WindowAdapter() {@Overridepublic void windowClosing(WindowEvent e) {// TODO Auto-generated method stub// super.windowClosing(e);System.exit(0);}});!!由于WindowAdapter不只有一个方法(7个),因此不是函数式接口,不能使用Lambda表达式;
4) Lambda表达式:只适用于函数是接口,注意!函数式监听器接口(ActionListener等)没有对应的适配器,因为只有一个方法,没必要提供适配器
Button btn = new Button("button");btn.addActionListener(e -> System.out.println(e.getActionCommand()));
2. 反射:
1) 反射一词来自MFC,即组件自己监听自己的意思,这种组件就是智能组件,这种反射就叫做组件反射;
2) 当然在Java中就是让类自己来监听自己的组件,这就叫类反射,当然MFC式的组件反射也可以实现;
3) 反射的示例:类反射和组件反射
public class AwtTest extends WindowAdapter { // 类自己监听自己的组件Frame f = new Frame("WindowAdapter Test");class MyButton extends Button implements ActionListener { // 组件自己监听自己public MyButton(String label) throws HeadlessException {super(label);// TODO Auto-generated constructor stubthis.addActionListener(this); // 组件自反射}@Overridepublic void actionPerformed(ActionEvent e) {// TODO Auto-generated method stubSystem.out.println("Button pushed!");}}@Overridepublic void windowClosing(WindowEvent e) {// TODO Auto-generated method stubSystem.exit(0);}public void init() {f.addWindowListener(this); // 类自反射f.add(new MyButton("button"));f.pack();f.setVisible(true);}public static void main(String[] args) {new AwtTest().init();}}!像这样的按钮只要new出来随便用就行了,它产生的事件都由它自己来处理(自定义按钮);
!!注意this的应用是实现反射的关键;
4) 反射的缺点:
i. 通常组件、GUI类(用于显示界面的类,上面的类就是GUI类,PS:其实组件也是GUI类,用于显示组件本身)就只负责显示界面;
ii. 监听、处理事件应该放到另一个模块来处理,因为这符合MVC设计思想;
iii. 因此反射的缺点就是程序结构混乱,模块耦合度高;
3. 外部:
1) 将监听器单独定义成外部类,然后GUI界面调用它;
2) 最大的缺点:
i. 监听器通常属于特定的GUI界面,定义在外部降低了程序的内聚性;
ii. 外部类不能自由访问GUI界面类中的数据(组件),编程不简洁;
3) 示例:监听邮件发送按钮的监听器定义在外部
i. 监听器:
public class MailerListener implements ActionListener {private TextField mailAdress;public MailerListener() {}public MailerListener(TextField mailAdress) {this.mailAdress = mailAdress;}public TextField getMailAdress() {return mailAdress;}public void setMailAdress(TextField mailAdress) {this.mailAdress = mailAdress;}@Overridepublic void actionPerformed(ActionEvent e) {// TODO Auto-generated method stubSystem.out.println("sending mail to '" + mailAdress.getText() + ".'\n");}}ii. GUI:
public class AwtTest extends WindowAdapter { // 类自己监听自己的组件@Overridepublic void windowClosing(WindowEvent e) {// TODO Auto-generated method stub// super.windowClosing(e);System.exit(0);}public void init() {Frame f = new Frame("Sending Mail Test");TextField tf = new TextField(40);Button btn = new Button("send");f.addWindowListener(this);btn.addActionListener(new MailerListener(tf));f.add(tf);f.add(btn, BorderLayout.SOUTH);f.pack();f.setVisible(true);}public static void main(String[] args) {new AwtTest().init();}}!!可以看到监听器和GUI之间存在数据的共享,这加大了模块之间的耦合度,这无疑是对程序健壮性的一种危害!!要慎重使用;
- [疯狂Java]监听器的实现:内部(闭包)、反射、外部
- Eclipse Java工程导入外部jar包与内部jar包(导入项目有红色感叹号的解决办法)(转)
- python函数的闭包问题(内部函数与外部函数详述)
- java 监听器的实现
- Java监听器用法(三):外部类监听器
- jar包调用jar包内部和外部的配置文件
- jar包调用jar包内部和外部的配置文件
- jar包调用jar包内部和外部的配置文件
- jar包读取jar包内部和外部的配置文件
- 疯狂java之反射(InvocationHandler)
- Java工程导入外部jar包与内部jar包(导入项目有红色感叹号的解决办法)
- 实现RecyclerView的item点击事件的内部监听器
- Jar包读取内部和外部的文件
- Jar包读取内部和外部的文件
- Jar包读取内部和外部的文件
- Android~外部类监听器~实现Activity的跳转
- 疯狂java笔记之常用的内部排序
- JAVA监听器添加的四种方式(自身、外部类、内部类、匿名类)
- iOS runloop
- Android Gallery组件实现循环显示图像
- iMindMap Android版中怎样添加导图图标
- dedecms 5.6 创建图片集时 出现 数据保存到数据库附加表 `dede_addonimages` 时出错,请把相关信息提交给
- 文件的写入本地以及删除
- [疯狂Java]监听器的实现:内部(闭包)、反射、外部
- 目标检测——从RCNN到Faster RCNN 串烧
- 108.Which two statements are true regarding the COUNT function? (Choose two.)
- 字符串(一)——String类(String No. 1)
- C#中使用自定义消息
- Species Tree(HashTable实现)
- rapidxml使用
- Web 网页通信之长连接、长轮询
- 在.net(C# or vb.net)中如何用户自定义消息,并在窗体中处理这些消息