# KeyListener funktioniert nicht während Timer läuft



## M4_ix (10. Mai 2017)

Hallo,
ich möchte ein Spiel programmieren bei dem es 9 Labels gibt und eines immer rot aufleuchtet und man dann eine entsprechende zahlentaste drücken soll, also eine Art Reaktionsspiel.
Mein Problem ist, dass der KeyListener nicht mehr funktioniert wenn ich den Startbutton klicke.
Ich denke es ist wegen dem Thread vom Timer , ich weis aber nicht wie ich das Problem lösen soll. Hier mein Code:

```
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Timer;
import java.util.TimerTask;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class test {
    static boolean a = true;
    static int i = 0;
    static    JFrame jf1 = new JFrame("Reaktionsspiel");
    static Timer timer = new Timer();
    public static void main(String[] args) {
        // TODO Auto-generated method stub

   
        JLabel jl1 = new JLabel("1");
        JLabel jl2 = new JLabel("2");
        JLabel jl3 = new JLabel("3");
        JLabel jl4 = new JLabel("4");
        JLabel jl5 = new JLabel("5");
        JLabel jl6 = new JLabel("6");
        JLabel jl7 = new JLabel("7");
        JLabel jl8 = new JLabel("8");
        JLabel jl9 = new JLabel("9");
        JPanel jp1 = new JPanel();
        JPanel jp3 = new JPanel();
        JPanel jp2 = new JPanel();
        JButton jb1 = new JButton("Spiel starten");
        JButton jbclose = new JButton("Schließen");
        JLabel jlo = new JLabel();
       
        jf1.setVisible(true);
        jf1.setSize(500, 500);
        jf1.getContentPane().setBackground(Color.GREEN);
        jf1.setLayout(new GridLayout(4,3));
        jf1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        jf1.add(jp1);
        jf1.add(jp2);
        jf1.add(jp3);
        jp1.add(jb1);
        jp2.add(jbclose);
        jp3.add(jlo);
        jf1.add(jl1);
        jf1.add(jl2);
        jf1.add(jl3);
        jf1.add(jl4);
        jf1.add(jl5);
        jf1.add(jl6);
        jf1.add(jl7);
        jf1.add(jl8);
        jf1.add(jl9);
        jl1.setOpaque(true);
        jl2.setOpaque(true);
        jl3.setOpaque(true);
        jl4.setOpaque(true);
        jl5.setOpaque(true);
        jl6.setOpaque(true);
        jl7.setOpaque(true);
        jl8.setOpaque(true);
        jl9.setOpaque(true);
       
       
        jf1.addKeyListener(new KeyListener() {
              public void keyPressed(KeyEvent e) {
                   
                    System.out.println(e.getKeyChar() + " pressed");

                     if(i==1 && e.getKeyChar() ==1 ){
                        
                         System.out.println("Ok");
                                     }else{
                                         timer.cancel();
                
                                     }
                    
   
                }
                public void keyReleased(KeyEvent e) {
                  
                }
                public void keyTyped(KeyEvent e) {
                  
                   
                }
        });       
       
   
        jb1.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent evt){
       
               
                 TimerTask timerTask = new TimerTask() {
                     public void run() {
                        
                       
                         i =(int) (Math.random() * 9) + 1;
                       
                         if(i==1){
                             jl1.setBackground(Color.RED);
                         }else{
                             jl1.setBackground(Color.GREEN);
                         }
                        
                        
                         if(i==2){
                             jl2.setBackground(Color.RED);
                         }else{
                             jl2.setBackground(Color.GREEN);
                         }
                         if(i==3){
                             jl3.setBackground(Color.RED);
                         }else{
                             jl3.setBackground(Color.GREEN);
                         }
                         if(i==4){
                             jl4.setBackground(Color.RED);
                         }else{
                             jl4.setBackground(Color.GREEN);
                         }
                         if(i==5){
                             jl5.setBackground(Color.RED);
                         }else{
                             jl5.setBackground(Color.GREEN);
                         }
                         if(i==6){
                             jl6.setBackground(Color.RED);
                         }else{
                             jl6.setBackground(Color.GREEN);
                         }
                         if(i==7){
                             jl7.setBackground(Color.RED);
                         }else{
                             jl7.setBackground(Color.GREEN);
                         }
                         if(i==8){
                             jl8.setBackground(Color.RED);
                         }else{
                             jl8.setBackground(Color.GREEN);
                         }
                         if(i==9){
                             jl9.setBackground(Color.RED);
                         }else{
                             jl9.setBackground(Color.GREEN);
                         }
                        
                        
                        
                        
                     }
                 };
                  
                   timer.schedule(timerTask,1000, 750);     
               
               
               
               
           
               
               
           
               
            }
           
       
           
           
        });
       
       
        
       
       
        jbclose.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent evt){
        System.exit(1);
       
            }
        });
       
    }

}
```

LG M4_ix


----------



## Robat (10. Mai 2017)

Würde mal vermuten dass dein `jtf1` den Focus verliert, nach dem der Button gedrückt wurde.
Du könntest mit `setFocusable(false)` verhindern, dass der Button den Focus bekommt.

Generell würde ich dir aber eher zu `KeyBindings` raten. Die sind mMn schon allein deshalb besser, weil sie mehr Funktionalität bieten.

Gruß Robert


----------



## M4_ix (10. Mai 2017)

Erstmal danke für deine schnelle Antwort.
ich habe es gerade mit setFocussable(false) probiert, hat aber nicht funktioniert. Also will ich es jetzt mit KeyBindings probieren, ich habe aber keine Ahnung davon und konnte auf die schnelle nichts im Internet finden, kannst du mir eventuell ein Beispiel sagen?


----------



## Robat (10. Mai 2017)

Worauf hast du denn setFocusable(false) angewendet?


M4_ix hat gesagt.:


> konnte auf die schnelle nichts im Internet


https://docs.oracle.com/javase/tutorial/uiswing/misc/keybinding.html


----------



## M4_ix (10. Mai 2017)

Robat hat gesagt.:


> Worauf hast du denn setFocusable(false) angewendet?


Auf jb1 also den Startbutton


----------



## M4_ix (10. Mai 2017)

Ich habe mal ein Code Beispiel, vom Link, ausprobiert und es hat nicht funktioniert.

```
AbstractAction doNothing = new AbstractAction() {
    public void actionPerformed(ActionEvent e) {
        //do nothing
        System.out.println("1 gedrückt");
    }
};
jl1.getInputMap().put(KeyStroke.getKeyStroke("1"),
                            doNothing);
jl1.getActionMap().put("doNothing",
                             doNothing);
```


----------



## Meniskusschaden (10. Mai 2017)

M4_ix hat gesagt.:


> Auf jb1 also den Startbutton


Die anderen Buttons dürfen den Fokus natürlich auch nicht bekommen. Die musst du in dieser Lösungsvariante also ebenfalls so einstellen.
Wenn die Buttons fokussierbar bleiben sollen, kannst du deinen KeyListener natürlich auch einfach den Buttons hinzufügen.


----------



## Robat (10. Mai 2017)

Also ich habs grad noch mal ausprobiert.
Wenn du in dem ActionListener für deinen Startbutton dem jf1 den Focus gibst sollte es funktionieren.

--
Zu den KeyBindings:

```
AbstractAction doNothing = new AbstractAction()
{
    public void actionPerformed(ActionEvent e)
    {
        System.out.println("foo");
    }
};
jl1.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("T"), "FOO");
jl1.getActionMap().put("FOO", doNothing);
```

Du kannst bei einem KeyBinding mitgeben wann das Event ausgelöst werden soll. 
In dem Fall immer dann, wenn die Komponente selbst den Focus hat oder in dem Fenster ist welches den Focus hat.

Gruß Robert


----------



## M4_ix (10. Mai 2017)

Ich habe jetzt den KeyListener  dem Startbutton hinzugefügt, jetzt funktioniert der KeyListener auch wenn der Timer Läuft, aber wenn ich dann ne Taste drücke wird zwar ausgegeben welche, aber der Timer hört dann irgeendwie auf zu laufen


----------



## Robat (10. Mai 2017)

M4_ix hat gesagt.:


> aber wenn ich dann ne Taste drücke wird zwar ausgegeben welche, aber der Timer hört dann irgeendwie auf zu laufen


Weil du es dem Programm doch so gesagt hast 


```
if (i == 1 && e.getKeyChar() == 1)
        System.out.println("Ok");
    else
        timer.cancel();
```

Wenn `i` 1 ist und die gedrückte Taste 1 ist dann soll Ok ausgegeben werden. In jedem anderen Fall soll der timer gestoppt werden.


----------



## M4_ix (10. Mai 2017)

Ohja, danke da wäre ich nie drauf gekommen xD
Funktioniert jetzt, danke an euch alle und n schönen Abend noch.


----------



## mrBrown (10. Mai 2017)

Allerdings meinst du statt `e.getKeyChar() == 1` vermutlich eher `e.getKeyChar() == '1'`


----------



## M4_ix (10. Mai 2017)

Hab dann doch noch n Problem jetzt ist es so, dass wenn i 1 ist und ich 1 drücke der Timer trotzdem anhält.


----------



## mrBrown (10. Mai 2017)

M4_ix hat gesagt.:


> Hab dann doch noch n Problem jetzt ist es so, dass wenn i 1 ist und ich 1 drücke der Timer trotzdem anhält.


Siehe mein Kommentar eins davor


----------



## M4_ix (10. Mai 2017)

Ja schon klar aber ich drücke ja 1 wenn i 1 ist


----------



## mrBrown (10. Mai 2017)

M4_ix hat gesagt.:


> Ja schon klar aber ich drücke ja 1 wenn i 1 ist


Ja, aber die Zahl 1 und das Zeichen '1' sind verschiedene Dinge - du drückst das Zeichen 1, nicht die Zahl 1


----------



## M4_ix (10. Mai 2017)

Habs umgeändert auf e.getKeyChar() == '1' , funktioniert trotzdem nicht


----------



## mrBrown (10. Mai 2017)

Bei mir funktioniert es, wenn der Focus gesetzt wird (was du laut #9 gemacht hast) und ich es auf 'änder', zeig doch mal wie dein Code jetzt aussieht


----------



## M4_ix (10. Mai 2017)

Also ich habe hier keinen Fokus gesetzt


```
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Timer;
import java.util.TimerTask;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class test {
    static boolean a = true;
    static int i = 0;
    static    JFrame jf1 = new JFrame("Reaktionsspiel");
    static Timer timer = new Timer();
    public static void main(String[] args) {
        // TODO Auto-generated method stub

  
        JLabel jl1 = new JLabel("1");
        JLabel jl2 = new JLabel("2");
        JLabel jl3 = new JLabel("3");
        JLabel jl4 = new JLabel("4");
        JLabel jl5 = new JLabel("5");
        JLabel jl6 = new JLabel("6");
        JLabel jl7 = new JLabel("7");
        JLabel jl8 = new JLabel("8");
        JLabel jl9 = new JLabel("9");
        JPanel jp1 = new JPanel();
        JPanel jp3 = new JPanel();
        JPanel jp2 = new JPanel();
        JButton jb1 = new JButton("Spiel starten");
        JButton jbclose = new JButton("Schließen");
        JLabel jlo = new JLabel();
      
        jf1.setVisible(true);
        jf1.setSize(500, 500);
        jf1.getContentPane().setBackground(Color.GREEN);
        jf1.setLayout(new GridLayout(4,3));
        jf1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        jf1.add(jp1);
        jf1.add(jp2);
        jf1.add(jp3);
        jp1.add(jb1);
        jp2.add(jbclose);
        jp3.add(jlo);
        jf1.add(jl1);
        jf1.add(jl2);
        jf1.add(jl3);
        jf1.add(jl4);
        jf1.add(jl5);
        jf1.add(jl6);
        jf1.add(jl7);
        jf1.add(jl8);
        jf1.add(jl9);
        jl1.setOpaque(true);
        jl2.setOpaque(true);
        jl3.setOpaque(true);
        jl4.setOpaque(true);
        jl5.setOpaque(true);
        jl6.setOpaque(true);
        jl7.setOpaque(true);
        jl8.setOpaque(true);
        jl9.setOpaque(true);
        jf1.setFocusable(true);
      
        jb1.addKeyListener(new KeyListener() {
              public void keyPressed(KeyEvent e) {
                  
                  

                     if(i==1 && e.getKeyChar() == '1' ){
                         System.out.println("Ok");
                       
                                     }else{
                                         timer.cancel();
                                       
                                     }
if(i==2 && e.getKeyChar() == '2' ){
                       
                         System.out.println("Ok");
                                     }else{
                                         timer.cancel();
               
                                     }

if(i==3 && e.getKeyChar() ==3 ){
      
        System.out.println("Ok");
                    }else{
                        timer.cancel();

                    }
if(i==4 && e.getKeyChar() ==4 ){
      
        System.out.println("Ok");
                    }else{
                        timer.cancel();

                    }
if(i==5 && e.getKeyChar() ==5){
      
        System.out.println("Ok");
                    }else{
                        timer.cancel();

                    }
if(i==6 && e.getKeyChar() ==6 ){
      
        System.out.println("Ok");
                    }else{
                        timer.cancel();

                    }
if(i==7 && e.getKeyChar() ==7 ){
      
        System.out.println("Ok");
                    }else{
                        timer.cancel();

                    }
if(i==8 && e.getKeyChar() ==8 ){
      
        System.out.println("Ok");
                    }else{
                        timer.cancel();

                    }
if(i==9 && e.getKeyChar() ==9 ){
      
        System.out.println("Ok");
                    }else{
                        timer.cancel();

                    }

                   
  
                }
                public void keyReleased(KeyEvent e) {
                 
                }
                public void keyTyped(KeyEvent e) {
                 
                  
                }
        });      
      
      
        jb1.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent evt){
      
              
                 TimerTask timerTask = new TimerTask() {
                     public void run() {
                         // Was immer du machen willst
                      
                         i =(int) (Math.random() * 9) + 1;
                      
                         if(i==1){
                             jl1.setBackground(Color.RED);
                         }else{
                             jl1.setBackground(Color.GREEN);
                         }
                       
                       
                         if(i==2){
                             jl2.setBackground(Color.RED);
                         }else{
                             jl2.setBackground(Color.GREEN);
                         }
                         if(i==3){
                             jl3.setBackground(Color.RED);
                         }else{
                             jl3.setBackground(Color.GREEN);
                         }
                         if(i==4){
                             jl4.setBackground(Color.RED);
                         }else{
                             jl4.setBackground(Color.GREEN);
                         }
                         if(i==5){
                             jl5.setBackground(Color.RED);
                         }else{
                             jl5.setBackground(Color.GREEN);
                         }
                         if(i==6){
                             jl6.setBackground(Color.RED);
                         }else{
                             jl6.setBackground(Color.GREEN);
                         }
                         if(i==7){
                             jl7.setBackground(Color.RED);
                         }else{
                             jl7.setBackground(Color.GREEN);
                         }
                         if(i==8){
                             jl8.setBackground(Color.RED);
                         }else{
                             jl8.setBackground(Color.GREEN);
                         }
                         if(i==9){
                             jl9.setBackground(Color.RED);
                         }else{
                             jl9.setBackground(Color.GREEN);
                         }
                       
                       
                       
                       
                     }
                 };
                 
                   timer.schedule(timerTask,1000, 1000);    
              
              
              
              
          
              
              
          
              
            }
          
      
          
          
        });
      
      
       
      
      
        jbclose.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent evt){
        System.exit(1);
      
            }
        });
      
    }

}
```


----------



## mrBrown (10. Mai 2017)

M4_ix hat gesagt.:


> Also ich habe hier keinen Fokus gesetzt


Sry - dem Button den Keylistener gegeben hast, hatte mich da grad vertan 

Das Problem ist, dass du in jedem else den Timer cancelst, du solltest da else if nutzen, und nur um letzten else den Timer canceln


----------



## M4_ix (10. Mai 2017)

Wie meinst du das, kannst du bitte n Code Beispiel machen


----------



## mrBrown (10. Mai 2017)

```
if (i == 1 && e.getKeyChar() == '1') {
    System.out.println("Ok");
} else if (i == 2 && e.getKeyChar() == '2') {
    System.out.println("Ok");
} ...
else {
    timer.cancel();
}
```


----------



## M4_ix (10. Mai 2017)

Und wie soll dann das letzte else aussehen?


----------



## Robat (10. Mai 2017)

M4_ix hat gesagt.:


> Und wie soll dann das letzte else aussehen?


Hat er doch geschrieben?


----------



## M4_ix (10. Mai 2017)

Und wie mache ich das wenn der Timer stoppen soll wenn i 1 ist und man nichts drückt oder was anderres drückt


----------



## Robat (10. Mai 2017)

M4_ix hat gesagt.:


> oder was anderres drückt


Du könntest ja abfragen ob die gedrückte Taste *nicht* 1 ist.



M4_ix hat gesagt.:


> und man nichts drückt


Das wirst du so wie du es jetzt hast nicht hinbekommen.
Irgendwo musst du ja sagen dass der User x Sekunden Zeit hat und wenn die Zeit abgelaufen ist musst du den Timer canceln.


----------



## M4_ix (10. Mai 2017)

Naja dann mache ich es einfach so, dass man 60 sek Zeit hat um so oft wie möglich richtig zu drücken, also n score sammeln, das sollte ja nicht so schwer sein.
Danke für eure Antworten 
LG M4_ix


----------

