Java AWT事件适配器

事件适配器是监听器接口的空实现——事件适配器实现了监听器接口,并为该接口里的每个方法都提供了实现,这种实现是一种空实现(方法体内没有任何代码的实现)。当需要创建监听器时,可以通过继承事件适配器,而不是实现监听器接口。因为事件适配器已经为监听器接口的每个方法提供了空实现,所以程序自己的监听器无需实现监听器接口里的每个方法,只需要重写自己感兴趣的方法,从而可以简化事件监听器的实现类代码。

如果某个监听器接口只有一个方法,则该监听器接口就无需提供适配器,因为该接口对应的监听器别无选择,只能重写该方法。如果不重写该方法,就没有必要实现该监听器。

从下表可以看出,所有包含多个方法的监听器接口都有一个对应的适配器,但只包含一个方法的监听器接口则没有对应的适配器。

/**
 * 程序通过事件适配器来创建事件监听器
 */
package codes11;

import java.awt.Frame;
import java.awt.TextArea;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

public class WindowAdapterTest {
	private Frame f = new Frame("测试");
	private TextArea ta = new TextArea(6, 40);

	public void init() {
		f.addWindowListener(new MyListener());
		f.add(ta);
		f.pack();
		f.setVisible(true);
	}

	class MyListener extends WindowAdapter {
		public void windowClosing(WindowEvent e) {
			System.out.println("用户关闭窗口!\n");
			System.exit(0);
		}
	}

	public static void main(String[] args) {
		new WindowAdapterTest().init();
	}

}

实现监听器对象形式

(1)内部类形式:将事件监听器类定义成当前类的内部类

        前面程序中的所有事件监听器类都是内部类形式,使用内部类可以很好的复用该监听器类,如上程序所示;监听器类是外部类的内部类,所以可以自由访问外部类的所有GUI组件,这也是内部类的两个优势

(2)外部类形式:将事件监听器类定义成一个外部类

        使用外部类定义事件监听器类的形势比较少见,主要有如下两个原因:

        1)事件监听器通常属于特定的GUI界面,定义成外部类不利于提高程序的内聚性

        2)外部类形式的事件监听器不能自由访问创建GUI界面类中的组件,编程不够简洁

        但如果某个事件监听器确实需要被多个GUI界面所共享,而且主要是完成某种业务逻辑的实现,则可以考虑使用外部类形式来定义时间监听器类。

/**
 * 下面程序定义了一个外部类作为事件监听器类,该事件监听器实现了发送邮件的功能
 */
package codes11;

import java.awt.TextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class MailerListener implements ActionListener {

	// 该TextField文本框用于输入发送邮件的地址
	private TextField mailAddress;

	public MailerListener() {

	}

	public MailerListener(TextField mailAddress) {
		super();
		this.mailAddress = mailAddress;
	}

	public void setMailAddress(TextField mailAddress) {
		this.mailAddress = mailAddress;
	}

	// 实现发送邮件
	@Override
	public void actionPerformed(ActionEvent arg0) {
		System.out.println("程序向“" + mailAddress.getText() + "”发送邮件...");
		// 发送邮件的真实实现
	}

}
上面的事件监听器类没有与任何GUI界面耦合,创建该监听器对象时传入一个FextField对象,该文本框里的字符串将被作为收件人地址。
/**
 * 下面程序使用了该事件监听器来监听窗口中的按钮
 */
package codes11;

import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.Frame;
import java.awt.TextField;

public class SendMailer {

	private Frame f = new Frame("测试");
	private TextField tf = new TextField(40);
	private Button send = new Button("发送");

	public void init() {
		// 使用MailerListener对象作为事件监听器
		send.addActionListener(new MailerListener(tf));
		f.add(tf);
		f.add(send, BorderLayout.SOUTH);
		f.pack();
		f.setVisible(true);
	}

	public static void main(String[] args) {
		new SendMailer().init();
	}

}
(3)类本身作为事件监听类:让当前类本身实现监听器接口或继承事件适配器

        类本身作为事件监听器类这种形式使用GUI界面类直接作为监听器类,可以直接在GUI界面类中定义事件处理器方法。这种形式非常简洁,也是早期AWT事件编程里比较喜欢采用的形式。

        但这种做法有如下两个缺点:

        1)这种形式可能造成混乱的程序结构,GUI界面的职责主要是完成界面初始化工作,但此时还需包含事件处理器方法,从而降低了程序的可能性

        2)如果GUI界面类需要继承事件适配器,将会导致该GUI界面类不能继承其他父类

/**
 * 下面程序使用GUI界面作为事件监听器类
 * GUI界面类继承WindowAdapter作为事件监听器类
 */
package codes11;

import java.awt.Frame;
import java.awt.TextArea;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

public class SimpleEventHandler extends WindowAdapter {

	private Frame f = new Frame("Test");
	private TextArea ta = new TextArea(6, 40);

	public void init() {
		// 将该类的默认对象作为事件监听器对象
		f.addWindowListener(this);
		f.add(ta);
		f.pack();
		f.setVisible(true);
	}

	public void windowClosing(WindowEvent e) {
		System.out.println("用户关闭窗口\n");
		System.exit(0);
	}

	public static void main(String[] args) {
		new SimpleEventHandler().init();
	}

}
(4)匿名内部类形式:使用匿名内部类创建事件监听器对象

        大部分时候,时间处理器都没有复用价值(可复用代码通常会被抽象成业务逻辑),因此大部分事件监听器只是临时使用一次,所以使用匿名内部类形式的事件监听器更合适。实际上,这种形式是目前使用最广泛的事件监听器形式

/**
 * 下面程序使用匿名内部类来创建事件监听器
 */
package codes11;

import java.awt.Frame;
import java.awt.TextArea;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

public class AnonymousEventHandler {

	private Frame f = new Frame("Test");
	private TextArea ta = new TextArea(6, 40);

	public void init() {
		// 以匿名内部类的形式来创建事件监听器对象
		f.addWindowListener(new WindowAdapter() {
			// 实现事件处理方法
			public void windowClosing(WindowEvent e) {
				System.out.println("用户关闭窗口\n");
				System.exit(0);
			}
		});
		f.add(ta);
		f.pack();
		f.setVisible(true);
	}

	public static void main(String[] args) {
		new AnonymousEventHandler().init();
	}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值