java - 如何实现和维护多个actionListener

标签 java actionlistener code-maintainability

好的,我有一个包含多个菜单和菜单项的类(我们称之为:MenuBarClass)。 我想为每个 MenuItem 分配一个 Action 监听器,但是..而不是做类似的事情:

menuitem_1.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) {} });
menuitem_2.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) {} });
menuitem_3.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) {} });
// ...
menuitem_N.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) {} });

我希望我的代码更易于维护并且..更重要..我不希望在一个巨大的 ActionListener 类中有很多“如果”,例如:

public void actionPerformed(ActionEvent e) {
  if (e.getSource().equals(menuitem_1)) {
    //do stuff..
  } else if (e.getSource().equals(menuitem_2)) {
    //do stuff..
  } else ...
}

如果可能的话,我该怎么做? 谁能帮忙?

最佳答案

您可以使用 reflection 减少冗长用于创建实用方法的 API:

package demo;    
import java.awt.event.*;
import java.lang.reflect.*;

public class ListenerProxies {    
  private static final Class<?>[] INTERFACES = { ActionListener.class };

  public static ActionListener actionListener(final Object target,
                                                    String method) {
    final Method proxied = method(target, method);
    InvocationHandler handler = new InvocationHandler() {
      @Override
      public Object invoke(Object proxy, Method method, Object[] args)
          throws Throwable {
        ActionEvent event = (ActionEvent) args[0];
        return proxied.invoke(target, event);
      }
    };
    return (ActionListener) Proxy.newProxyInstance(target.getClass()
        .getClassLoader(), INTERFACES, handler);
  }

  private static Method method(Object target, String method) {
    try {
      return target.getClass().getMethod(method, ActionEvent.class);
    } catch (NoSuchMethodException e) {
      throw new IllegalStateException(e);
    } catch (SecurityException e) {
      throw new IllegalStateException(e);
    }
  }
}

可以这样使用:

package demo;
import static demo.ListenerProxies.actionListener;
import java.awt.event.ActionEvent;
import javax.swing.*;

public class Demo {

  public static void main(String[] args) {
    Demo test = new Demo();
    JButton hello = new JButton("Say Hello");
    hello.addActionListener(actionListener(test, "sayHello"));
    JFrame frame = new JFrame();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.getContentPane().add(hello);
    frame.pack();
    frame.setVisible(true);
  }

  public void sayHello(ActionEvent event) {
    System.out.println("Hello");
  }
}

缺点是缺少编译时检查 sayHello(ActionEvent) 方法是否存在。

性能成本可以忽略不计。

关于java - 如何实现和维护多个actionListener,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10271924/

相关文章:

code-maintainability - 管理长期项目中的变通方法列表

java - 检测鼠标滚轮停止

Java:这些构造方法有什么区别

javascript - 如何继承和重写angularjs(java pendent)中的 Controller 方法?

java 1.5 : Best practice to keep constants for column name of db tables?

oracle11g - 有没有办法查询 Oracle DB 服务器名称并在条件编译中使用?

java - 在构造函数中添加一组而不是仅一个

java - 无法从另一个类访问数据

java - 无法从内部类访问封闭类的 JPasswordField 对象

java - 提高Java中定时器的速度