Frage

Wie sende ich programmatisch eine ActionEvent (EG -Taste gedrückt/action_performed) zu a JButton?

Ich weiß von:

button.doClick(0);

und

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

Aber ist es nicht möglich, es direkt zu senden und eine ActionEvent?

Bearbeiten: Dies ist kein Produktionscode, es ist nur ein kleines persönliches Experiment.

War es hilfreich?

Lösung

Sie können einen Knopf bekommen ActionListeners, und rufe dann das an actionPerformed Methode direkt.

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);
}

Andere Tipps

Warum möchten Sie, auch wenn Sie könnten? Normalerweise bedeutet dies, wenn Menschen so etwas tun wollen, nicht richtig nicht richtig trennte die Bedenken der Benutzeroberfläche aus der Geschäftslogik. Normalerweise möchten sie eine Logik aufrufen, die in einem ActionListener auftritt, ohne dass die Aktion stattfinden muss.

public void actionPerformed(ActionEvent ae) {
    //SomeLogic
}

//...

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

Aber die Lösung besteht jedoch darin, diese Logik aus dem ActionListener zu extrahieren und sie sowohl vom ActionListener als auch aus dem zweiten Ort aufzurufen:

public void someLogic() {
    //SomeLogic
}

public void actionPerformed(ActionEvent ae) {
    someLogic();
}

//...

public void someOtherPlace() {
    someLogic();
}

Nur wenn Sie die erben und enthüllen fireactionperformiert Methode, die geschützt ist:

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

Dann können Sie in der Lage sein, aber natürlich müssen Sie eine solche Referenz verwenden:

MockButton b = .... 

b.fireActionPerformed( new Action... etc. etc

Warum möchten Sie das tun? Ich weiß es nicht, aber ich würde Ihnen vorschlagen, zu folgen Marks Rat

Wenn Sie nicht Doclick () auf der Schaltfläche anrufen möchten, können Sie einfach den Code aufrufen, der von der Aktion der Schaltfläche aufgerufen wird. Vielleicht möchten Sie die Klasse haben, die die actionPersformed -Methode aufnimmt, eine öffentliche Methode, die andere Klassen aufrufen können, und diese Methode einfach aufzurufen.

Das praktische Problem wurde anscheinend gelöst (siehe Mark Peters ' und Jjnguy's Antworten). Und die fireActionPerformed Die Methode wurde auch bereits erwähnt (siehe Oscarryz 'Antwort), um potenzielle Parallelitätsprobleme zu vermeiden.

Was ich hinzufügen wollte war, dass Sie kann Rufen Sie alle privaten und geschützten Methoden an (einschließlich fireActionPerformed), ohne dass Klassen unter Verwendung von Reflexion unterkrass werden. Erstens bekommen Sie die Reflexion Method Objekt einer privaten oder geschützten Methode mit method = clazz.getDeclaredMethod() (clazz muss der sein Class Objekt der Klasse, die die Methode deklariert, nicht eine seiner Unterklassen (dh AbstractButton.class für die Methode fireActionPerformed, nicht JButton.class)). Dann rufst du an method.setAccessible(true) um die zu unterdrücken IllegalAccessExceptionS, das ansonsten auftritt, wenn er versucht, auf private oder geschützte Methoden/Felder zuzugreifen. Schließlich rufst du an method.invoke().

Ich weiß jedoch nicht genug über Reflexion, um die Nachteile der Verwendung von Reflexion auflisten zu können. Sie existieren jedoch nach dem Reflexions -API -Trail (Siehe Abschnitt "Nachteile der Reflexion").

Hier einige Arbeitscode:

// 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);
    }
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top