将 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)),它是为 JButton
、JToggleButton
和 JMenuItem
,例如(请参阅 "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
我有以下问题:
我有这样的功能:
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)),它是为 JButton
、JToggleButton
和 JMenuItem
,例如(请参阅 "Direct Known Subclasses" 和 class 定义树以找出实际提供方法的位置)。
第二种方法只有在实际上有一个 superclass 定义方法时才有效。如果不止一个,则必须使用 if-else
结构和 instanceof
+ 显式转换来检查可能的 classes(而不是保留原始 Object
签名)。
如果您提供有关原始问题的更多信息(例如,为什么需要这种方法),我们可能会找到更好的方法。
如果允许更改 addActionListenerObject
:
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