如何以编程方式将ActionEvent
(例如按下的按钮/ ACTION_PERFORMED)发送到JButton
?
我知道:
button.doClick(0);
和
button.getModel().setArmed(true);
button.getModel().setPressed(true);
button.getModel().setPressed(false);
button.getModel().setArmed(false);
但是不能直接发送ActionEvent
吗?
编辑:这不是生产代码,只是一个小小的个人实验。
答案 0 :(得分:15)
您可以获得按钮ActionListener
,然后直接调用actionPerformed
方法。
ActionEvent event;
long when;
when = System.currentTimeMillis();
event = new ActionEvent(button, ActionEvent.ACTION_PERFORMED, "Anything", when, 0);
for (ActionListener listener : button.getActionListeners()) {
listener.actionPerformed(event);
}
答案 1 :(得分:13)
即使你可以,你为什么要这样做?通常当人们想要做这样的事情时,这意味着他们没有正确将UI的关注点与业务逻辑分开。通常,他们希望调用ActionListener中发生的某些逻辑而不需要执行操作。
public void actionPerformed(ActionEvent ae) {
//SomeLogic
}
//...
public void someOtherPlace() {
//I want to invoke SomeLogic from here though!
}
但实际上解决方案是从ActionListener中提取该逻辑并从ActionListener和第二个位置调用它:
public void someLogic() {
//SomeLogic
}
public void actionPerformed(ActionEvent ae) {
someLogic();
}
//...
public void someOtherPlace() {
someLogic();
}
答案 2 :(得分:3)
仅当您继承并公开受保护的fireActionPerformed方法时:
class MockButton extends JButton {
// bunch of constructors here
@Override
public void fireActionPerformed( ActionEvent e ) {
super.fireActionPerformed( e );
}
}
然后你就可以了,但当然,你必须使用这样的引用:
MockButton b = ....
b.fireActionPerformed( new Action... etc. etc
你为什么要这样做?我不知道,但我建议您关注Mark's advice
答案 3 :(得分:1)
如果您不想在按钮上调用doClick(),则只需调用按钮操作调用的代码即可。也许您希望拥有actionPerformed方法的任何类调用其他类可以调用的公共方法,并简单地调用此方法。
答案 4 :(得分:0)
看来实际问题已经解决了(见Mark Peters'和jjnguy's答案)。并且还提到了fireActionPerformed
方法(请参阅OscarRyz' answer),以避免潜在的并发问题。
我想要添加的是可以调用所有私有和受保护的方法(包括fireActionPerformed
),而无需使用反射对任何类进行子类化。首先,使用Method
获取私有或受保护方法的反射method = clazz.getDeclaredMethod()
对象(clazz
需要是声明方法的类的Class
对象,而不是其子类(即AbstractButton.class
用于方法fireActionPerformed
,不是 JButton.class
))。然后,您调用method.setAccessible(true)
来禁止在尝试访问私有或受保护的方法/字段时会发生的IllegalAccessException
。最后,请致电method.invoke()
。
然而,我对反射知之甚少,能够列出使用反射的缺点。但是,根据Reflection API trail,它们存在(参见“反思的缺点”)。
这里有一些工作代码:
// ButtonFireAction.java
import javax.swing.AbstractButton;
import javax.swing.JButton;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.lang.reflect.Method;
public class ButtonFireAction
{
public static void main(String[] args) throws ReflectiveOperationException
{
JButton button = new JButton("action command");
Class<AbstractButton> abstractClass = AbstractButton.class;
Method fireMethod;
// signature: public ActionEvent(Object source, int id, String command)
ActionEvent myActionEvent = new ActionEvent(button,
ActionEvent.ACTION_PERFORMED,
button.getActionCommand());
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e)
{
System.out.println(e.getActionCommand());
}
});
// get the Method object of protected method fireActionPerformed
fireMethod = abstractClass.getDeclaredMethod("fireActionPerformed",
ActionEvent.class);
// set accessible, so that no IllegalAccessException is thrown when
// calling invoke()
fireMethod.setAccessible(true);
// signature: invoke(Object obj, Object... args)
fireMethod.invoke(button,myActionEvent);
}
}