15 Stimmen

Wie kann ich programmatisch ActionEvent an JButton senden?

Wie sende ich programmatisch eine ActionEvent (z.B. Taste gedrückt/ACTION_PERFORMED) zu einem JButton ?

Ich weiß davon:

button.doClick(0);

y

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

Aber ist es nicht möglich, ihm direkt eine ActionEvent ?

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

17voto

jjnguy Punkte 132790

Sie können eine Schaltfläche ActionListener s, und rufen dann die 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);
}

14voto

Mark Peters Punkte 78448

Selbst wenn Sie es könnten, warum sollten Sie es wollen? Wenn Menschen so etwas tun wollen, bedeutet das in der Regel, dass sie sich nicht richtig informiert haben. trennte die Bedenken der Benutzeroberfläche von der Geschäftslogik. Normalerweise wollen 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!
}

Die eigentliche Lösung besteht jedoch darin, diese Logik aus dem ActionListener zu extrahieren und sie sowohl vom ActionListener als auch von der zweiten Stelle aus aufzurufen:

public void someLogic() {
    //SomeLogic
}

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

//...

public void someOtherPlace() {
    someLogic();
}

3voto

OscarRyz Punkte 189898

Nur wenn Sie die fireActionPerformed 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 das tun, aber natürlich müssen Sie eine Referenz wie diese verwenden:

MockButton b = .... 

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

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

1voto

Wenn Sie doClick() nicht auf der Schaltfläche aufrufen möchten, können Sie einfach den Code aufrufen, der durch die Aktion der Schaltfläche aufgerufen wird. Vielleicht möchten Sie, dass die Klasse, die die actionPerformed-Methode enthält, eine öffentliche Methode aufruft, die von anderen Klassen aufgerufen werden kann, und rufen einfach diese Methode auf.

0voto

mkdrive2 Punkte 227

Das praktische Problem wurde anscheinend gelöst (siehe Mark Peters' y von jjnguy Antworten). Und die fireActionPerformed Methode wurde ebenfalls bereits erwähnt (siehe OscarRyz' Antwort ), um mögliche Gleichzeitigkeitsprobleme zu vermeiden.

Was ich noch hinzufügen wollte, ist, dass Sie puede alle privaten und geschützten Methoden aufrufen (einschließlich fireActionPerformed ), ohne dass eine Unterklasse gebildet werden muss, unter Verwendung von Reflection. Zunächst erhalten Sie die Reflexion Method Objekt einer privaten oder geschützten Methode mit method = clazz.getDeclaredMethod() ( clazz muss die Class Objekt der Klasse, die die Methode deklariert, und nicht eine ihrer Unterklassen (d. h. AbstractButton.class für die Methode fireActionPerformed , no JButton.class )). Dann rufen Sie method.setAccessible(true) zur Unterdrückung der IllegalAccessException s, die sonst beim Versuch, auf private oder geschützte Methoden/Felder zuzugreifen, auftreten würden. Schließlich rufen Sie method.invoke() .

Ich weiß jedoch nicht genug über Reflexion, um die Nachteile der Verwendung von Reflexion aufzählen zu können. Es gibt sie jedoch, und zwar laut der Reflection-API-Pfad (siehe Abschnitt "Nachteile der Reflexion").

Hier ein funktionierender 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);
    }
}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X