# Gui für Vokabeltrainer (ActionListener)



## Auraya (18. Jun 2015)

Hallo,
ich bin gerade dabei für mein Vokabeltrainer eine GuI zu basteln. Es ist meine erste GuI, aber es funktioniert einfach nicht. Ich habe Button für einzelne Lektionen erstellt und wenn dort drauf geklickt wird, soll z.B. folgendes passieren:


```
if(e.getSource()==lektion1){                liste = new VokabelListe(vokList,1);
                
                int anzahl = Integer.parseInt(feldAnzahlVok.getText());
                    
                if(anzahl>0 && anzahl<500) {
                        anweisung.setText("Bitte die folgende Vokabel übersetzen!");
                        


                   while(anzahl>0) {
                        int zufall = VokabelListe.zufallsZahl();
                        Vokabel aktuelleVokabel=vokList.get(zufall);
                       
                        boolean f = false;
                        while(f==false) {
                            frage.setText(aktuelleVokabel.getDeutsch());
                            
                            if(e.getSource()==bestaetigen) {
                                antwortBenutzer=antwort.getText();
            
                                f=antwortBenutzer.equals(aktuelleVokabel.getFranzoesisch());
                        
                                    if(f==false) {
                                        anweisung.setText("Falsch");
                                    }
                                        else{
                                            anweisung.setText("Richtig!");
                                        } 
                            }
                         } 
                    anzahl--;
                   }
```

Es funktioniert aber nicht. Das Programm macht dann gar nichts mehr, ich kann es auch nicht mehr beenden (endlos-Schleife?).


----------



## camelCase90 (18. Jun 2015)

Wenn der Benutzer eine Falsche Antwort gibt, bleibt f auf false und die while-Schleife, welche die Variable f auf false prüft verläuft in eine Endlosschleife.


----------



## Auraya (18. Jun 2015)

Ok, ich Dusel habe vergessen f auf true zu setzen, wenn es richtig ist. Das soll so sein, das erst die nächste Vokabel angezeigt wird, wenn der Benutzer die richtige Antwort genannt hat. Aber soweit komme ich ja leider gar nicht zu antworten. Sobald ich auf den Button "Lektion 1" klicke, friert das Programm sozusagen ein.


----------



## camelCase90 (18. Jun 2015)

Dafür brauchst du keine While-Schleife. Du musst bloß jedes mal wenn der Benutzer auf den absenden Button klickt, Dir den Inhalt vom Textfeld holen. Wenns falsch war gibst Du eine Fehlermeldung aus und der Benutzer muss die Antwort halt einfach erneut eingeben, solange bis sie richtig ist und wenn das der Fall ist, lässt Du einfach die nächste anzeigen. Das wäre praktisch ein If-Block.

Das Problem, das Du jetzt mit der While-Schleife hast ist, dass der Benutzer eine Eingabe macht, die innerhalb der While-Schleife auf Richtigkeit geprüft wird, ist diese Eingabe einmal falsch (f == false), dann läuft die While-Schleife unendlich durch, weil jedes Mal wieder die selbe Antwort geprüft wird, welche ja nunmal falsch ist.


----------



## Auraya (18. Jun 2015)

Okay, ich habe das jetzt mal geändert, immerhin "friert" es jetzt nicht mehr ein. Die erste Vokabel wird mir dann angezeigt, aber wenn ich auf den Button klicke passiert nichts - also es wird nicht angezeigt richtig oder falsch. Irgendwas kann so ja auch nicht stimmen, oder? Wie komme ich denn dann an die nächste Vokabel so?


```
if(e.getSource()==lektion1){
                liste = new VokabelListe(vokList,1);
                
                int anzahl = Integer.parseInt(feldAnzahlVok.getText());
                    
                if(anzahl>0 && anzahl<500) {
                        feldAnzahlVok.setEditable(false);
                        anweisung.setText("Bitte die folgende Vokabel übersetzen!");
                        


                   while(anzahl>0) {
                        int zufall = VokabelListe.zufallsZahl();
                        Vokabel aktuelleVokabel=vokList.get(zufall);
                        frage.setText(aktuelleVokabel.getDeutsch());
                            
                            if(e.getSource()==bestaetigen) {
                                
                                    if(antwort.getText().equals(aktuelleVokabel.getFranzoesisch())) {
                                        anweisung.setText("Richtig!");
                                        continue;
                                    }
                                        else{
                                            anweisung.setText("Falsch");
                                        } 
                            }
                    anzahl--;
                    } 


                }
```


----------



## camelCase90 (18. Jun 2015)

Das continue kann weg  Kannst Du mal die ganze Klasse posten?


----------



## Auraya (18. Jun 2015)

Ja, okay:


```
private class GuI_Listener implements ActionListener {        
        @Override
         public void actionPerformed(ActionEvent e) {
             
            if(e.getSource()==einblenden){
             Vokabel vokabel;
                for(int i = 0; i<vokList.size();i++) {
                        vokabel=vokList.get(i);
                        vokabeln.append(vokabel.toString()+"\n");
                     } 
                einblenden.setEnabled(false);
                ausblenden.setEnabled(true);
            } 
            
            if(e.getSource()==ausblenden){
                vokabeln.setText("");
                einblenden.setEnabled(true);
                ausblenden.setEnabled(false);
            }
             
            if(e.getSource()==lektion1){
                
                liste = new VokabelListe(vokList,1);
                
                int anzahl = Integer.parseInt(feldAnzahlVok.getText());
                    
                if(anzahl>0 && anzahl<500) {
                        feldAnzahlVok.setEditable(false);
                        anweisung.setText("Bitte die folgende Vokabel übersetzen!");
                        


                   while(anzahl>0) {
                        int zufall = VokabelListe.zufallsZahl();
                        Vokabel aktuelleVokabel=vokList.get(zufall);
                        frage.setText(aktuelleVokabel.getDeutsch());
                            
                            if(e.getSource()==bestaetigen) {
                                
                                    if(antwort.getText().equals(aktuelleVokabel.getFranzoesisch())) {
                                        anweisung.setText("Richtig!");
                                    }
                                        else{
                                            anweisung.setText("Falsch");
                                        } 
                            }
                    anzahl--;
                    } 


                } else {
                            anweisung.setText("Die Zahl ist zu klein oder zu groß! Bitte neue Zahl eingeben und Lektion wählen!"); 
                            lektion1.setEnabled(true);}
                }
          }   
    }
```


----------



## camelCase90 (19. Jun 2015)

Ich gehe mal davon aus, dass lektion1 ein Button-Objekt ist oder?  

Sollte dies der Fall sein, dann steckt die Abfrage ob der Eingabe Button geklickt wurde innerhalb der Abfrage ob der lektion1 Button geklickt wurde und ist somit in dem Moment unerreichbar.

Du musst die Abfragen trennen. Dann wäre da das Problem, dass Du die aktuelle Vokabel nicht mehr abfragen kannst, da du diese innerhalb der Abfrage ob der lektion1 Button geklickt wurde als lokale Variable deklarierst.


----------



## Auraya (19. Jun 2015)

Ja Lektion 1 ist ein Button-Objekt. Also kann man niemals so eine Verschachtelung von Button-Abfragen machen? 

Habe nun die Abfrage der Eingabe außerhalb von der Abfrage von Lektion 1 eingefügt und die aktuelle Vokabel ganz am Anfang deklariert. Nun funktioniert es soweit, das die erste Vokabel abgefragt wird und auch angezeigt wird richtig oder falsch. 
Allerdings bleibt weiter das Problem wie ich an die nächste Vokabel dran komme? Gibt es da irgendeine Funktion die ich in die while Schleife setzen kann die sozusagen "wartet" und dann dazu ein "mach weiter" der dann in die Abfrage des anderen Buttons kommt?


----------



## camelCase90 (19. Jun 2015)

Ne, was Du nun machen musst ist, wieder eine neue Vokabel per Zufall zu erstellen, innerhalb des Blocks, der den Eingabe Button überprüft.

Deshalb wäre es am einfachsten und auch sauberer, wenn Du Dir eine Methode erstellst, die genau das macht , was inner des "if(e.getSource() == lektion1)" Blocks passiert.

Ich würde mir für sowas einen Singleton, also eine Helferklasse erstellen, die dann die Methoden für solche Geschichten enthält.


Lektion 1 soll ja auch nicht ewig gehen oder?

D.h. Du brauchst noch ein Attribut, welches die Anzahl der Vokabeln innerhalb einer Lektion enthält (evtl eine Klasse "Lektion", du könntest dann dort die Logik für die Vokabeln rein machen. Die Methoden um neue Vokabeln zu bekommen, eine Liste, welche die Vokabeln für die aktuelle Lektion enthält etc.)


----------



## Auraya (21. Jun 2015)

Nein, die Lektion soll nicht ewig gehen. Der Benutzer gibt in ein Textfeld ein wie viele Vokabeln abgefragt werden sollen. Ich verstehe leider immer noch nicht, wie ich das jetzt machen kann, das solange wie eben die eingebende Anzahl ist neue Vokabeln in das Textfeld gefügt werden. Immer wenn ich eine while Schleife einfüge, friert das Programm ein. 

Mit den Singleton verstehe ich leider auch nicht so ganz. Damit lässt sich nur ein Objekt einer Klasse erstellen?

Also ich habe bisher eine Klasse "Franzoesisch" in der nur die main-Methode drin ist. 
Dann eine Klasse "Vokabel", die halt die Vokabel "beschreibt". Also Wert für deutsch, Wert für französisch und die getter und setter Methoden. 
Dann eine Klasse "VokabelListe" wo je nachdem welche Lektion eine Datei eingelesen wird für die einzelnen Lektionen und dann in einer ArrayList von Vokabeln gespeichert werden. Heißt das, diese Klasse müsste ich als Singleton machen, damit nur ein Objekt davon erstellt wird? 
Dann habe ich noch eine Klasse "Vokabeltrainer" wo ich für die Konsole dann eine Methode habe, der die Vokabeln halt abfragt. Aber diese Methode kann ich ja nicht so einfach für die GuI übernehmen. 

Also noch eine Klasse GuI wo ich halt die Gui erstellt habe und die Klasse für ActionListener... Ich kriege irgendwie nicht so ganz auf die Reihe wie ich das alles jetzt sozusagen zusammen füge für die GuI. :/


----------



## camelCase90 (21. Jun 2015)

Den Singleton kannst als Helferklasse nutzen (Ja, bei einem Singleton wird nur ein Objekt einer Klasse erstellt). Dem Singleton könntest Du Methoden geben, welche Dir die Vokabeln etc übergeben. 

Ich schreib Dir mal morgen Abend einen Beispiel-Code der genau das macht, was Du vor hast. Den kannst Du dann mit deinem abgleichen und schauen was ich anders gemacht habe. Ich werde den dann auch kommentieren, damit du dann genau weißt was wo passiert.

Ich werde allerdings kein aufwendiges GUI erstellen, nur grob. Die Logik ist ja das, was Du benötigst


----------



## Auraya (25. Jun 2015)

Hallo camelCase90,

da ich es leider immer noch nicht hinbekommen habe, würde ich mich über ein Beispiel wirklich sehr freuen. Es muss natürlich kein aufwendiges/schönes Gui sein. Also ich würde mich darüber freuen, wenn du diese Beispiel noch zur Verfügung stellen würdest. 

Gruß,
Auraya


----------



## camelCase90 (25. Jun 2015)

Hallo, 

Beispiel kommt noch, sry. 
War die letzten Tage auf der Arbeit komplett eingespannt, hatte auch versucht es auf der Arbeit zwischen zu quetschen, hatte allerdings zu viel zu tun 

Vielleicht schaff ich das heute noch ansonsten morgen, da hab ich mehr auf der Arbeit


----------



## Auraya (29. Jun 2015)

Ähm, ich will ja nicht nerven und so... Arbeit geht natürlich vor. Ich wollte hiermit nur nochmal bekunden, das ich an den Beispiel immer noch Interesse hätte.


----------

