使用单一监听器实现JMenuItem与JButton的Command模式实践

本文展示了如何利用Command设计模式与Singleton模式,为Swing应用中的JMenuItem和JButton等组件实现全局单一监听器,通过统一接口处理所有UI事件,提升代码可维护性。

Command, Singleton, JMenuItem, JButton, AbstractButton - 为应用实现单一监听器

这里我将演示如何为整个系统使用单一监听器来处理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
package com.shaafshah.jmenus;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import javax.swing.AbstractButton;

// 实现ActionListener接口并采用Singleton模式
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();
    }

    // 添加Command并注册监听器
    public void addCommand(Command command){
        commandList.add(command);
        ((AbstractButton)command).addActionListener(this);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        ((Command)e.getSource()).execute();
    }
}

Command接口实现

定义Command接口及其实现类(注意实现类同时继承UI组件):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
public interface Command {
    public void execute();
}

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");
    }
}

工作机制

  1. TestCmd既是JMenuItem又是Command
  2. 所有事件由OneListener统一处理
  3. 触发事件时自动调用对应Command的execute()方法
  4. 开发者只需关注业务逻辑实现,无需管理监听器

点击下载示例代码

这种模式通过统一的事件处理机制,有效降低了UI组件与业务逻辑的耦合度。

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计