这里我将演示如何为整个系统使用单一监听器来处理JMenuItem的简单用法。一个典型的使用场景可能是单实例桌面应用程序。
让我们看看具体实现方式。首先创建一个OneListener类,它需要能够监听ActionEvents并能向自身添加Commands。如果您想了解更多关于这种模式及其用法的信息,请参考我之前关于Command和Singleton的帖子。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
package com.shaafshah.jmenus;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import javax.swing.AbstractButton;
// 实现ActionListener接口且为单例
public class OneListener implements ActionListener{
private static OneListener oneListener = null;
// 保存注册到此监听器的所有命令列表
private ArrayList<Command> commandList = null;
// 私有构造函数
private OneListener(){
commandList = new ArrayList<Command>();
}
// 确保单例实例
public static OneListener getInstance(){
if(oneListener != null)
return oneListener;
else return oneListener = new OneListener();
}
// 添加命令并将自己添加为监听器
public void addCommand(Command command){
commandList.add(command);
((AbstractButton)command).addActionListener(this);
}
// 所有事件都在这里处理
@Override
public void actionPerformed(ActionEvent e) {
((Command)e.getSource()).execute();
}
}
|
在上面的代码中,addCommand方法添加命令对象并为其添加监听器。
这是如何实现的呢?基本上是因为我将UI对象在系统中归类为Commands,并且假设这些命令当前是AbstractButton,即JMenuItem、JButton。让我们看看Command接口及其实现。
1
2
3
|
public interface Command {
public void execute();
}
|
实现部分请注意,Command是一个接口,而类仍然扩展了UI对象。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
import javax.swing.JMenuItem;
public class TestCmd extends JMenuItem implements Command{
public TestCmd() {
super("Test");
OneListener.getInstance().addCommand(this);
}
@Override
public void execute() {
System.out.println("HelloWorld");
}
}
|
个人不喜欢在类的构造函数中调用OneListener,但为了本文的简洁性,我保留了这种方式。有很多不同的方法可以避免这样做。
因此TestCmd是一个JMenuItem,但也是一个Command,这就是OneListener所理解的。
由于这些命令的监听器也是OneListener,所有ActionEvents都被发送到那里,并且只从那里调用Command.execute。
所以现在您不必担心自己处于哪个监听器中。您唯一知道的是当execute被调用时,您需要执行自己的操作。
您可以从[这里]下载代码。
希望这对您有所帮助。