How to programmatically send an ActionEvent to JButton?

How to programmatically send an ActionEvent (e.g., pressing the / ACTION _PERFORMED button) to JButton ?

I know:

 button.doClick(0); 

and

 button.getModel().setArmed(true); button.getModel().setPressed(true); button.getModel().setPressed(false); button.getModel().setArmed(false); 

But is it not possible to directly send its ActionEvent ?

EDIT: This is not production code, this is just a small personal experiment.

+12
java event-handling swing actionlistener jbutton
Jan 20 2018-11-21T00:
source share
5 answers

You can get the ActionListener s button, and then call the actionPerformed method directly.

 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); } 
+14
Jan 20 2018-11-11T00:
source share

Even if you could, why do you need it? Usually, when people want to do something like this, it means that they did not correctly separate the problems from the user interface from the business logic. Usually they want to invoke some logic that occurs in the ActionListener without having to perform an action.

 public void actionPerformed(ActionEvent ae) { //SomeLogic } //... public void someOtherPlace() { //I want to invoke SomeLogic from here though! } 

But in fact, the solution is to extract this logic from the ActionListener and call it from both the ActionListener and the second location:

 public void someLogic() { //SomeLogic } public void actionPerformed(ActionEvent ae) { someLogic(); } //... public void someOtherPlace() { someLogic(); } 
+13
Jan 20 2018-11-11T00:
source share

Only if you inherit and expose the fireActionPerformed method, which is protected:

 class MockButton extends JButton { // bunch of constructors here @Override public void fireActionPerformed( ActionEvent e ) { super.fireActionPerformed( e ); } } 

Then you can, but, of course, you need to use the link, for example:

 MockButton b = .... b.fireActionPerformed( new Action... etc. etc 

Why do you need this? I don’t know, but I suggest you follow Mark advice

+3
Jan 20 2018-11-11T00:
source share

If you do not want to call doClick () on the button, you can simply call the code called by the action of the button. Perhaps you want any class containing the actionPerformed method to call a public method that other classes can call, and just call that method.

+1
Jan 20 2018-11-11T00:
source share

A practical problem has been resolved, it seems (see Mark Peters and jjnguy's answers). And the fireActionPerformed method fireActionPerformed also been mentioned (see OscarRyz answer ) to avoid potential concurrency issues.

What I wanted to add is that you can call all private and protected methods (including fireActionPerformed ), without having to subclass any classes using reflection. First, you get a Method object to reflect a private or protected method using method = clazz.getDeclaredMethod() ( clazz must be a Class object of the class that declares the method, and not one of its subclasses (i.e. AbstractButton.class for method fireActionPerformed , not JButton.class )). Then you call method.setAccessible(true) to suppress the IllegalAccessException , which otherwise occurs when you try to access private or protected methods / fields. Finally, you call method.invoke() .

I don’t know enough about reflection to be able to list the disadvantages of using reflection. They exist, however, in accordance with the Reflection API (see the "Disadvantages of Reflection" section).

Here is the working code:

 // 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); } } 
0
May 23 '14 at 20:36
source share



All Articles