我如何以编程方式将ActionEvent发送到JButton?
如何以编程方式将ActionEvent
(例如按下的按钮/ ACTION_PERFORMED)发送到JButton
?
我知道:
button.doClick(0);
和
button.getModel().setArmed(true); button.getModel().setPressed(true); button.getModel().setPressed(false); button.getModel().setArmed(false);
但是不可能直接发送一个ActionEvent
吗?
编辑:这不是生产代码,只是一个小小的个人实验。
你可以得到一个按钮的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); }
即使你可以,你为什么要这样做? 通常当人们想要做这样的事情时,这意味着他们没有正确地将 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(); }
仅当您inheritance并公开受保护的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
你为什么要这样做? 我不知道,但我建议你遵循马克的建议
如果您不想在按钮上调用doClick(),那么您只需调用按钮操作调用的代码即可。 也许你希望拥有actionPerformed方法的任何类调用其他类可以调用的公共方法,并简单地调用此方法。
看来实际问题已经解决了(参见Mark Peters和jjnguy的答案)。 并且已经提到了fireActionPerformed
方法(参见OscarRyz的回答 ),以避免潜在的并发问题。
我想要添加的是,您可以使用reflection调用所有私有和受保护的方法(包括fireActionPerformed
),而无需子类化任何类。 首先,使用method = clazz.getDeclaredMethod()
获取私有或受保护方法的reflectionMethod
对象( clazz
需要是声明方法的类的Class
对象,而不是其子类之一(即, AbstractButton.class
用于方法fireActionPerformed
, 而不是 JButton.class
))。 然后,调用method.setAccessible(true)
来抑制在尝试访问私有或受保护的方法/字段时会发生的IllegalAccessException
。 最后,调用method.invoke()
。
然而,我对reflection知之甚少,能够列出使用reflection的缺点。 但是,它们存在,根据Reflection API路径 (参见“reflection的缺点”一节)。
这里有一些工作代码:
// 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 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); } }
- 如何在JTextField上删除MouseListener / ActionListener
- 如何使用匿名内部类actionlistener使JButton在单击时删除自身?
- “线程中的exception”AWT-EventQueue-0“java.lang.NullPointerException”。 我不知道我做错了什么
- 使用键盘在java中以角度移动圆圈
- 按下按钮后的KeyListener
- 在Java中使用具有相同标签的多个JButton
- 尝试将ActionListener添加到JButtons
- JLabel或JTable单元格上的ActionListener
- 如何在外部类中的ActionListeners中切换CardLayout中的面板