将 ActionListener 添加到未知对象

Add ActionListener to unknown Object

我有以下问题:

我有这样的功能:

public void addActionListenerObject(Object object) {
    object.addActionListener(this);
}

我的问题如下:我需要一个解决方案,我可以将任何对象作为参数传递给 addActionListener 函数。 列表可以在这里找到:https://docs.oracle.com/javase/tutorial/uiswing/events/eventsandcomponents.html

有没有办法不用多次实例就可以解决这个问题?

谢谢

你要找的是多态性。 Component 类型的所有实例都有 addActionListener 方法。更改您的方法签名以期望 Component,而不是 Object.

我以为 addActioListener 是继承自 Component。它不是。 该方法单独添加到每个组件类型,没有父组件 class.

保留签名

如果你不能改变你的方法签名(即,如果你必须接收一个Object,如果有这样的方法定义则调用addActionListener()),一个更general/robust的解决方案将使用 Java Reflections 检查实际对象是否定义了 addActionListener() 方法,并通过反射调用它。无论如何,这听起来是一个非常 hacky 的方法。

更改签名

如果您可以更改您的方法签名,请尝试使用 AbstractButton (https://docs.oracle.com/javase/7/docs/api/javax/swing/AbstractButton.html#addActionListener(java.awt.event.ActionListener)),它是为 JButtonJToggleButtonJMenuItem,例如(请参阅 "Direct Known Subclasses" 和 class 定义树以找出实际提供方法的位置)。

第二种方法只有在实际上有一个 superclass 定义方法时才有效。如果不止一个,则必须使用 if-else 结构和 instanceof + 显式转换来检查可能的 classes(而不是保留原始 Object签名)。

如果您提供有关原始问题的更多信息(例如,为什么需要这种方法),我们可能会找到更好的方法。

如果允许更改 addActionListenerObject:

的签名,则传递功能接口(仅限 >= Java 1.8)
public class Just {
    private ActionListener actionListener;
    public void addActionListener(ActionListener actionListener) {
        this.actionListener = actionListener;
    }
    public void doIt() {
        System.out.println("Hello");
        actionListener.actionPerformed(new ActionEvent(this, 3, "World"));
    }
}

public class MyActionListener implements ActionListener {
    public void addActionListenerObject(Consumer<ActionListener> consumer) {
        consumer.accept(this);
    }
    @Override
    public void actionPerformed(ActionEvent e) {
        System.out.println(e.getActionCommand());
    }
}

这样,添加动作侦听器的类(在我的示例中是Just)不需要实现接口。

使用它:

Just just = new Just();

MyActionListener listener = new MyActionListener();
listener.addActionListenerObject(just::addActionListener); // Aha!

just.doIt();

这会打印:

Hello
World