# ActionListener Methoden Buttons zuweisen!



## xYurisha (28. Feb 2018)

Hallo Leute 

Ich habe eine Klasse mit zwei verschiedenen ActionListener Methoden, wie kann ich den Buttons der Methode zuweisen die ich brauche?
Normalerweise habe ich immer:

```
hauptmubutton[1].addActionListener(this);
```
benutzt. Nun habe ich aber eine zweite ActionListener Methode und möchte die dem nächsten Button zuordnen. 
Wie mache ich das?
Und wieso nimmt eclipse bei dem genannten Beispiel die erste ActionListener Methode, bzw. wie weiß er welche er mit dem Befehl this ausführen muss?
So weise ich bisher immer die zweite Methode zu..

```
hauptmubutton[0].addActionListener(new ActionListener() {
               public void actionPerformed(ActionEvent ae) {
                   actionPerformed1(ae);
                  }});
```


----------



## Robat (28. Feb 2018)

Was meinst du mit 2 verschiedene "Actionlistener Methoden".
Hast du 2 mal in deinem Code ?

```
@Override
public void actionPerformed(ActionEvent e) {..}
```


----------



## xYurisha (28. Feb 2018)

Robat hat gesagt.:


> Was meinst du mit 2 verschiedene "Actionlistener Methoden".
> Hast du 2 mal in deinem Code ?
> 
> ```
> ...


Ich habe einmal 

```
public void actionPerformed(ActionEvent mouse) {
        if(mouse.getSource() == antworten[0]) {
            if(loesung == 1) {
                message("Richtig","Schlauer Dude");
                //prozent();
                frage_klasse = new Fragen();
            }else {
                message("falsch","LEIDER");
               
            }}
           
            if(mouse.getSource() == antworten[1]) {
                if(loesung == 2) {
                    message("Richtig","Schlauer Dude");
                    //prozent();
                    frage_klasse = new Fragen();
                }else {
                    message("falsch","LEIDER");
                    //lebenAbziehen("Sie haben noch "+getHealth()+ "leben", "Verlierer");
                    //lebenAbziehen();
                }}
               
                if(mouse.getSource() == antworten[2]) {
                    if(loesung == 3) {
                        message("Richtig","Schlauer Dude");
                        //prozent();
                        frage_klasse = new Fragen();
                    }else {
                        message("falsch","LEIDER");
                        //lebenAbziehen("Sie haben noch "+getHealth()+ "leben", "Verlierer");
                        //lebenAbziehen();
                    }}
       
                if(mouse.getSource() == antworten[3]) {
                    if(loesung == 4) {
                        message("Richtig","Schluer Dude");
                        //prozent();
                        frage_klasse = new Fragen();
                    }else {
                        message("falsch","LEIDER");
                        //lebenAbziehen("Sie haben noch "+getHealth()+ "leben", "Verlierer");
                        //lebenAbziehen();
                    }}
                }
```
und dann eine Methode mit einem anderem Namen für das Hauptmenü die darauf achten soll was gedrückt wird:

```
public void actionPerformed1(ActionEvent ae) {
        if(ae.getSource()==this.hauptmubutton[0])
        {
            System.out.println("1");
            content.removeAll();
            content.validate();
            antworten[0] = new JButton(" - ");
             antworten[0].setBounds(52, 90, 120, 40);
             antworten[0].addActionListener(this);
             content.add(antworten[0]);
             antworten[1] = new JButton(" - ");
             antworten[1].setBounds(52, 160, 120, 40);
             antworten[1].addActionListener(this);
             content.add(antworten[1]);
             antworten[2] = new JButton(" - ");
             antworten[2].setBounds(220, 90, 120, 40);
             antworten[2].addActionListener(this);
             content.add(antworten[2]);
             antworten[3] = new JButton(" - ");
             antworten[3].setBounds(220, 160, 120, 40);
             antworten[3].addActionListener(this);
             content.add(antworten[3]);
             frage = new JLabel("Frage:");
             frage.setBounds(52,15,250,40);
             content.add(frage);
            fenster.setContentPane(content);   
            new Fragen();
        }
    }
```

Und ich will das nicht so gerne mischen sondern das ich diese beiden Methoden habe und den Buttons aus den hauptmenü die zweite methode zuweise und den anderen, für das Quiz die erste Methode.
Wie gesagt habe ich die zweite Methode bisher immer so versucht zu benutzen:

```
hauptmubutton[0].addActionListener(new ActionListener() {
               public void actionPerformed(ActionEvent ae) {
                   actionPerformed1(ae);
                  }});
```


----------



## Robat (28. Feb 2018)

Warum fügst du nicht beiden den selben Listener hinzu und fragst dann im Listener einfach nur ab welcher JButton gedrückt wurde.
Deine Logik lagerst du in 2 Methoden aus und rufst sie einfach nur auf.

```
@Override
public void actionPerformed(ActionEvent e) {
    if(e.getSource() == btnA) {
         btnALogic();
    } else if(e.getSource() == btnB) {
         btnBLogic();
    }
}

private void btnALogic() { ... }
private void btnBLogic() { ... }
```


----------



## xYurisha (28. Feb 2018)

Robat hat gesagt.:


> Warum fügst du nicht beiden den selben Listener hinzu und fragst dann im Listener einfach nur ab welcher JButton gedrückt wurde.
> Deine Logik lagerst du in 2 Methoden aus und rufst sie einfach nur auf.
> 
> ```
> ...


Das macht Sinn! Dankeschön 
Eine Frage noch, geht das auch wenn ich die eine Funktion in einer anderen Klasse aufbewahre?


----------



## Robat (28. Feb 2018)

Klar. Dann musst du nur eine Instanz dieser Klasse haben um darüber die Methode aufrufen zu können.


----------



## xYurisha (28. Feb 2018)

Robat hat gesagt.:


> Klar. Dann musst du nur eine Instanz dieser Klasse haben um darüber die Methode aufrufen zu können.





Robat hat gesagt.:


> Klar. Dann musst du nur eine Instanz dieser Klasse haben um darüber die Methode aufrufen zu können.


Also wie sehe das aus wenn ich eine Instanz dieser Klasse habe, bzw. wie würde ich das in die action Methode einsetzen?
Du siehst ja was ich vor habe, ich will ein Menü mit Auswahl Möglichkeiten machen und je nach dem werden die Buttons und Labels erzeugt (die einen haben eine Prozentbar die anderen nicht). Muss ich dann für jeden Button einzeln eine Methode schreiben?
Und dann nochmal extra für die Sache mit dem Quiz wo jeder Button nach der Lösung abgefragt wird?
Weil ich muss ja in meinem Array den jeweils angeklicken button ansprechen und gucken ob das Ergebnis richtig ist.
(Tut mir leid ich stehe gerade aufn Schlauch ich sitze hier schon ein paar Stunden dran ^^')


----------



## Robat (1. Mrz 2018)

xYurisha hat gesagt.:


> Also wie sehe das aus wenn ich eine Instanz dieser Klasse habe, bzw. wie würde ich das in die action Methode einsetzen?


Kleines Minimalbeispiel:

```
public class Test implements ActionListener{
       private Klasse cls;
       public Test() {
            this.cls = new Klasse();
            ....
       }
       @Override
       public void actionPerformed(ActionEvent e) {
             cls.someMethod();
       }
}
```



xYurisha hat gesagt.:


> Muss ich dann für jeden Button einzeln eine Methode schreiben?
> Und dann nochmal extra für die Sache mit dem Quiz wo jeder Button nach der Lösung abgefragt wird?


Sicherlich nicht. Man kann mit den Informationen aber schwer sagen was du verbessern könntest.


----------



## MoxxiManagarm (1. Mrz 2018)

> > Muss ich dann für jeden Button einzeln eine Methode schreiben?
> > Und dann nochmal extra für die Sache mit dem Quiz wo jeder Button nach der Lösung abgefragt wird?
> 
> 
> Sicherlich nicht. Man kann mit den Informationen aber schwer sagen was du verbessern könntest.



Ich bin der Meinung in diesem Fall macht der ActionCommand Sinn. Dieser kann nach id ausgelesen und mit der korrekten Lösung verglichen werden.

Das könnte ungefähr so aussehen:


```
// irgendein Initialisierungsvorgang
for(int i=0; i<antworten.length; i++) {
  antworten[i] = new JButton();
  antworten[i].setActionCommand("antwort" + (i + 1));
  antworten[i].addActionListener(this);
}

//der ActionListener
@Override
public void actionPerformed(ActionEvent e) {
    if(e.getActionCommand().startsWith("antwort")) {
         // TODO: zahl aus dem ActionCommand herauslösen und mit der Lösung vergleichen.
    } else {
         // TODO: other stuff
    }
}
```


----------



## xYurisha (3. Mrz 2018)

Hmmh ich habe jetzt das Problem das ich 2 Klassen habe und jede besitzt eine ActionListener Methode.
Nun benötigt die eine Klasse aber den Zugriff auf die andere genauer gesagt nur auf einen Button. Um das ganze Übersichtlich zuhalten und Oberflächliche Aufgaben von den anderen zu trennen kann ich die beiden auch nicht zusammenführen.
Wie kann ich jetzt einen JButton den anderen Listener aus der anderen Klasse zuweisen?
Sonst habe ich ja immer 
	
	
	
	





```
bspButton.addActionListener(this);
```
 benutzt aber nun möchte ich ja nicht den ActionListener aus der Klasse sondern aus einer anderen.
Wie mache ich das ?


----------



## Robat (3. Mrz 2018)

Warum willst du denn auf den ActionListener zugreifen? Mit welchem Zweck?


----------



## xYurisha (3. Mrz 2018)

Robat hat gesagt.:


> Warum willst du denn auf den ActionListener zugreifen? Mit welchem Zweck?


Ich habe einen Hauptmenü wo die Buttons geprüft werden und je nach dem welcher angeklickt wird werden verschiedene Buttons/Labels/Bars hinzugefügt.
Der andere wiederum überprüft zB in dem erstellten Spielmodi die Buttons. Also es wird eine Frage gestellt und es gibt 4 Buttons den Antworten zugeteilt worden sind und der Listener prüft ebendt ob man den richtigen angeklickt hat(Ob der Inhalt des angeklickten Buttons der Lösung entspricht).
Wenn ja gibt es eine Fensterausgabe und eine neue Frage wird erstellt und eine Prozentbar wird hochgesetzt.
Oder wenn man Beenden will gibt es ein Button den man klick und das Spiel schließt sich und weitere Funktion.
Das eine ist in einer Klassi Gui und die andere Methode in einer Klasse Quiz_Funktion.
Ich will halt die Oberflächlichen Dinge bzw. die Dinge die nichts miteinander zutun haben getrennt voneinander aufbewahren um es überschaubar zu halten.Wüsstest du wie das geht, das ich zB sage: 

```
bspButton.addActionListener(ActionPermed2(Action event));
//und es die andere Methode anspricht
```
Geht das irgend wie ?


Zusätzlich Ich kenne mich halt mit den Listenern noch nicht so gut aus.

```
if(ae.getSource()==hauptmubutton[0]){..}
```
Deswegen benutze ich für jeden Button eine if Abfrage..

```
public void actionPerformed(ActionEvent mouse) {
            if(mouse.getSource() == quiz.antworten[0]) {
                if(quiz.lösung == 1) {
                    quiz.message("Richtig","Gut gemacht");
                    fragen_klasse= new Frag();
                    zaehlen();
                }else {
                    quiz.message("falsch","Schade");
                }}
               
                if(mouse.getSource() == quiz.antworten[1]) {
                    if(quiz.lösung == 2) {
                        quiz.message("Richtig","Gut gemacht");
                        fragen_klasse = new Frag();
                        zaehlen();
                    }
                    else {
                        quiz.message("Falsch","Schade");
                    }}
                   
                    if(mouse.getSource() ==quiz. antworten[2]) {
                        if(quiz.lösung == 3) {
                            quiz.message("Richtig","Gut gemacht");
                            fragen_klasse = new Frag();
                            zaehlen();
                        }
                        else {
                            quiz.message("Falsch","Schade"); 
                        }}
           
                    if(mouse.getSource() == quiz.antworten[3]) {
                        if(quiz.lösung == 4) {
                            quiz.message("Richtig","Gut gemacht");
                            fragen_klasse = new Frag();
                            zaehlen();
                        }
                        else {
                            quiz.message("Falsch","Schade");
                        }}}
```
so sieht zB eine Abfrage für die Buttons nach der richtigen Antwort aus, das ist eine unnötige Code Duplizierung, wo ich noch nicht weiß wie es anders geht :-/


----------



## Xyz1 (3. Mrz 2018)

xYurisha hat gesagt.:


> Code Duplizierung, wo ich noch nicht weiß wie es anders geht


Mit einem Array/Feld und wahlweise ner Schleife....


----------



## MoxxiManagarm (3. Mrz 2018)

> Code Duplizierung, wo ich noch nicht weiß wie es anders geht


Ich  habe dafür schon ein Beispiel gemacht! Nutze den ActionCommand und die ausgelöste Zahl kann einfach in den Code verarbeitet werden.


```
public void actionPerformed(ActionEvent mouse) {
  int i = getIndexFromActionCommand(mouse.getActionCommand()); // ActionCommand wurde dem Button zuvor zugewiesen
if (i == quiz.lösung) // richtig
else // falsch
}
```

Du brauchst übrigens nicht immer für den ActionListener irgendeine Klasse erstellen. Du kannst auch sowas machen:

```
anyButton.addActionListener(ae -> {
 // do anything
});
```

Das nennt man dan anonyme Klasse


----------



## xYurisha (4. Mrz 2018)

MoxxiManagarm hat gesagt.:


> Ich  habe dafür schon ein Beispiel gemacht! Nutze den ActionCommand und die ausgelöste Zahl kann einfach in den Code verarbeitet werden.
> 
> 
> ```
> ...





DerWissende hat gesagt.:


> Mit einem Array/Feld und wahlweise ner Schleife....



Danke an euch beiden! Funktioniert super


----------



## xYurisha (4. Mrz 2018)

MoxxiManagarm hat gesagt.:


> ```
> public void actionPerformed(ActionEvent mouse) {
> int i = getIndexFromActionCommand(mouse.getActionCommand()); // ActionCommand wurde dem Button zuvor zugewiesen
> if (i == quiz.lösung) // richtig
> ...


Ich habe jetzt so eine Klasse erstellt und zur Probe sollte es richtig oder falsch ausgeben, leider gibt es jetzt nur falsch aus wenn ich falsch liege aber nicht richtig wenn ich auf den richtigen button gedrückt habe.

```
@SuppressWarnings("unlikely-arg-type")
    public int lele(String ding) {
        int b = 0;
        if(ding.equals(Gui.antworten[0])) {
            b=1;
        }
        if(ding.equals(Gui.antworten[1])) {
            b=2;
        }
        if(ding.equals(Gui.antworten[2])) {
            b=3;
        }
        if(ding.equals(Gui.antworten[3])) {
            b=4;
        }
        return b;
    }
 
    public void actionPerformed(ActionEvent mouse) {
        int i = lele(mouse.getActionCommand());
        if (i == Gui.loesung) {System.out.println("richtig");} //richtig
        else {System.out.println("falsch");} // falsch
}
```
Habe ich was falsch gemacht?
//EDIT
So nach dem einigen versuchen geht es jetzt:

```
@SuppressWarnings("unlikely-arg-type")
    public int lele(ActionEvent ding) {
        int b = 0;
        if(ding.getSource()== Gui.antworten[0]) {
            b=1;
        }
        if(ding.getSource()== Gui.antworten[1]) {
            b=2;
        }
        if(ding.getSource()== Gui.antworten[2]) {
            b=3;
        }
        if(ding.getSource()== Gui.antworten[3]) {
            b=4;
        }
        return b;
    }
  
    public void actionPerformed(ActionEvent mouse) {
        int i = lele(mouse);
        if (i == Gui.loesung) {System.out.println("richtig ");} //richtig
        else {System.out.println("falsch ");} // falsch}
```

Hoffe das passt so


----------



## MoxxiManagarm (4. Mrz 2018)

Das ist überhaupt nicht was ich meinte. Aber egal, denn so sieht der Ansatz auch besser aus. So wie du es aufgebaut hast solltest du es es aber noch mit einer Schleife machen, damit du nicht die duplizierten if's hast.


```
public int lele(ActionEvent ding) {
  for(b = 0; b < Gui.antworten.length; b++) {
    if(ding.getSource().equals(Gui.antworten[b])) return b;
  }
}
```


----------

