Problem: Unterscheidung Buttons getSource() - ActionListener

Julius

Mitglied
Hi,

ich erzeuge in meiner View Klasse mehrere private Buttons.
Sagen wir 1,2,3,4,5, etc. und füge jedem Button einen Listener hinzu.

Java:
button1.addActionListener(new ViewButtonListener());

In der Klasse ViewButtonListener wird der ActionListener implementiert und die Methode actionPerformed aufgerufen.

Wie kann ich allerdings unterscheiden, welcher Button in der View gedrückt wurde?
 

Der Wolf

Erfahrenes Mitglied
Hallo Julius,

in deinem Fall müsstest du theoretisch keine Unterscheidung treffen, da dein ViewButtonListener nur von einem Button benachrichtigt werden kann. Dem "button1". Das liegt daran, dass jedesmal wenn ein Button gedrückt wird, ein Event generiert wird, welches an ALLE Listener geschickt wird, die mit der "addActionListener" Methode zu einem Button hinzugefügt werden. Würdest du nun 5 Buttons generieren und jedem mit deiner Methode einen Listener hinzufügen, dann hättest du 5 verschiedene Listener-Instanzen die jeweils nur von einem Button benachrichtigt werden.

Willst du nur mit einem Action-Listener arbeiten, der dann unterscheidet welcher Button gedrückt wurde, kannst du das zum Beispiel folgendermaßen machen (Achtung: Ungetester Code).

Java:
public class MyFrame extends JFrame implements ActionListener {

    private JButton button1 = new JButton("Button 1");

    private JButton button2 = new JButton("Button 2");

    public MyFrame() {
        button1.addActionListener(this);
        button2.addActionListener(this);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        Object source = e.getSource();
        if (button1 == source) {
              // Reagiere auf Click auf button1.
        } else if (button2 == source) {
              // Reagiere auf Click auf button2.
        }
    }

}

Ich hoffe das funktioniert so, natürlich musst du noch die Import-Anweisungen hinzufügen und die Reaktionen auf die Events implementieren. Ich habe den Code gerade aus dem Kopf geschrieben und auch selbst gerade keine Möglichkeit ihn direkt zu testen.

Gruß,
Der Wolf
 

Julius

Mitglied
Bezieht sich das so nicht nur auf die Buttons, die in MyFrame angelegt wurden?
Bei mir lese ich die Buttons aus einer anderen Klasse aus.

Ich müsste sie dann praktisch irgendwie an die actionPerformed übergeben können.

Edit:
Habe der "anderen" Klasse eine Methode bereit gestellt und rufe sie über MyFrame Konstruktor auf. MyFrame hat für jeden actionPerformed eine innere Klasse.
Funktioniert jetzt soweit.
 
Zuletzt bearbeitet:

Der Wolf

Erfahrenes Mitglied
In dem ActionEvent das an die actionPerformed Klasse übergeben wird ist eine Referenz bzw ein Pointer zu der Instanz beinhaltet, die das Event ausgelöst hat. In deinem Fall der Button. Diese Referenz kannst du mit

Java:
Object source = e.getSource();

erhalten. Dann musst du nur eine Möglichkeit finden, eindeutig zu identifizieren, welcher Button das ist. In meinem Beispiel war das relativ simple, da die Buttons in der selben Klasse lag. Da konnte ich einfach mit dem "==" Operator gucken ob die Referenzen gleich sind. Gibt aber auch jede Menge andere Möglichkeiten.

Gruß,
Wolf
 

Akeshihiro

Erfahrenes Mitglied
actionPerformed ist eine Methode, und keine Klasse ;)
In Java gibt es keine Pointer, das sind nur Referenzen. Wie das intern in der VM umgesetzt wird, ist an dieser Stelle egal, da man in diese Abstraktionstiefe im Normalfall eh nicht hingelangt.

In so einem Fall ließe sich das meiner Meinung nach besser durch das Setzen des actionCommand in den Buttons besser realisieren. In dem Listener würde man dann einfach nach den actionCommands entsprechend filtern, das ist leichter als über Objektreferenzen, da diese ja bekannt sein müssten und das sorgt ja für unnötigen Overhead und ist ohnehin nicht so die beste Variante, da es das Entkoppeln der Logik von der GUI nur unnötig verkompliziert.