Frage

Ich habe gerade angefangen zu lernen, wie man Action -Hörer benutzt. Mein Verständnis funktioniert auf folgende Weise:

  1. Es gibt einige Klassen, die standardmäßig "AddActionListener" -Methode enthalten (z. B. Klassen für Schaltflächen).

  2. Mit dieser Methode fügen wir einem Objekt einen Aktionshörer hinzu. Zum Beispiel: listenedObject.addActionListener(listeningObject).

  3. Wenn eine Aktion mit dem "HeenedObject" ausgeführt wird, wird die "Action -Performed" -Methode des "HörensObject" aufgerufen. Es bedeutet also, dass wir, wenn wir eine Klasse für das Hörgerät programmieren, dort "actionperformierte" Methode einstellen müssen.

Was mir nicht klar ist, sollten wir eine neue Klasse für jedes Objekt erstellen, das wir zuhören möchten. Es scheint mir nicht als elegante Lösung zu sein. Wenn wir andererseits eine Action -Hörerklasse für alle (oder zumindest viele) Objekte haben, haben wir ein Problem Wisse, dass seit der Ausführung von Aktionen, die von den Actionperformed ausgeführt wurden, je nachdem, wer für diese Methode gefordert wird).

Meiner Meinung nach müssen wir für jedes angehörte Objekt, das wir erstellen müssen, "persönlicher" Aktionshörer und wir können dies tun, indem wir einen bestimmten Wert für das entsprechende Feld des Aktionshörers festlegen. Aber ich bin mir nicht sicher, ob es ein Standard -Weg ist? Wie machen es normalerweise die Leute?

War es hilfreich?

Lösung

Die häufigste Art, dies zu bewältigen - nach meiner persönlichen Erfahrung zu urteilen - besteht darin, einfach eine anonyme Inline -Klasse zu erstellen. So was:

listenedObject.addActionListener(new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent evt) {
        // Your action handling code in here
    }
});

Und oft habe ich gesehen, wie Leute einen Aufruf an eine Methode des Objekts gestellt haben, das das HeeendObject enthält. Zum Beispiel in einem Dialogfeld mit einer Schaltfläche:

myOkayButton.addActionListener(new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent evt) {
        okayButtonPressed();
    }
});

Später später in der Dialogklasse:

private void okayButtonPressed() {
    // Do what we need to do
}

Andere Tipps

Personnaly, wenn möglich, bevorzuge ich eine Aktion Klasse (als Beispiel eine Unterklasse von AbstractAction) Anstatt sich einfach auf einen Action -Hörer zu verlassen. Auf diese Weise kann ich dem Ursprungs -Widget einen Namen, ein Symbol, ein Tooltip usw. angeben ...

Die Art, wie ich immer nützlich gefunden habe (für Navigation Zwecke) besteht darin, eine anonyme innere Klasse zu erstellen, die dann in die äußere Klasse delegiert:

listenedObject.addActionListener(new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent evt) {
        listenedObject_actionPerformed(evt);
    }
});


private void listenedObject_actionPerformed(ActionEvent evt) {
    //Your handling goes here
}

Es ist dann viel einfacher, in einer IDE mit einer strukturellen Lookup (Strg+F12 in IDEA, STRG+O in Eclipse) zu Ihrem Handhabungscode zu gelangen.

Das Problem der Verwendung einer einzigen Klasse (wie eine GUI MyCoolPanel) Als gemeinsamer Zuhörer eines Haufens seiner Komponenten (Schaltflächen usw.) ist das, dass die actionPerformed Methode hat dann viel hässlich if-else Vergleiche herauszufinden welcher Taste Wurde tatsächlich gedrückt - überhaupt nicht sehr oo!

Sie sollten sich sicherlich nicht übermäßig Sorgen machen über die Leistung Aspekte dieser Art von Dingen - sie sind wahrscheinlich im Extrem vernachlässigbar! Frühgeborene Optimierung ist berühmt Eine schlechte Sache

Ich habe immer nützlich gefunden, eine separate Klasse zu erstellen, die die ActionListener -Schnittstelle und alle anderen Methoden implementiert, die zur Durchführung der Aktion erforderlich sind. Auf diese Weise ist eine Aktion nicht an ein bestimmtes Objekt gebunden und kann aus einer Taste, einem Menü usw. ausgelöst werden Befehlsmuster Ich vermute. Es hält den Code einfach.

Anonyme Klassen sind nicht wiederverwendbar.

Die Umleitung zum Objekt, das das HeeendObject enthält, führt zu gigantischen Klassen, die schwer zu warten sind.

Achten Sie darauf, dass Methoden removeActionListener aus einem bestimmten Grund vorhanden sind. Sie können Hörer überspringen, wenn Objekte, die Sie hören, mit Objekt sterben, das Ereignisse verarbeitet. Wenn Ihre Komponente jedoch das von der externe Quelle gelieferte Modell hört, sollten Sie Ihre Hörer in Addnotify hinzufügen und in Removenotify -Methoden entfernen. Andernfalls können Sie ein Memore -Leck haben.

Vielleicht ist es im Moment nicht wirklich, aber ich glaube, dass in naher Zukunft (nach Java 7 -Veröffentlichung) so etwas der gemeinsame Weg wäre:

listenedObject.addActionListener ( #{doSmth();} );
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top