# KeyListern funktioniert nicht. :S ?



## roontafloor (29. Sep 2006)

Also ich habe folgendes Problem:
ich bin ein ziemlicher Anfänger was Java betrifft und bei diesem kleinen simplen Spiel stosse ich auf Probleme mit dem KeyListener.
Es ist eine Art MarioKart, die Oberfläche und alles zeigt es mir alles schön und gut an, doch die Sache mit dem KeyListener geht nicht, wenn ich die bestimmte Taste drücke sollte (vorerst ein Fahrer(mario)) um eine gewisse x-achsen Zahl (die ja bestimmt werden kann) nach rechts vorrücken, doch bei meinem jetztigen stand komme ich nicht mehr weiter. 

Hier der Code: Hoffe ihr könnt mir tipps geben:



```
import java.awt.BorderLayout;

import java.awt.Container;
import java.awt.FlowLayout;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;


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


public class MarioKart  extends JFrame implements KeyListener, ActionListener {

	int a = 32;
	
	
	
	
	JPanel buttonPanel = new JPanel();
	JPanel racePanel = new JPanel();
	
	//private JButton reset = new JButton("Restart Race");
	private JButton quit = new JButton("Exit Game");

	//ImageIcon mario = new ImageIcon(getIconImage(), "Mario.gif");
	JLabel mario = new JLabel(new ImageIcon("Mario.gif"));
	JLabel luigi = new JLabel(new ImageIcon("Luigi.gif"));
	JLabel peach = new JLabel(new ImageIcon("Peach.gif"));
	JLabel yoshi = new JLabel(new ImageIcon("Yoshi.gif"));
	JLabel dk = new JLabel(new ImageIcon("DK.gif"));
	JLabel bowser = new JLabel(new ImageIcon("Bowser.gif"));
	JLabel koppa = new JLabel(new ImageIcon("Koppa.gif"));
	JLabel toad = new JLabel(new ImageIcon("Toad.gif"));
	
	private Container contentPane = new Container();
	
	
	
	public MarioKart() {
		
		setSize(600, 400);
		setTitle("Mario Grand-Prix");
		setDefaultCloseOperation(EXIT_ON_CLOSE);
		
	
		// dem Container wird das Layout und die Panels übergeben
		contentPane = this.getContentPane();
		contentPane.setLayout(new BorderLayout());
		contentPane.add(BorderLayout.NORTH, buttonPanel);
		contentPane.add(BorderLayout.CENTER, racePanel);
		
		// dem buttonPanel wird ein Layout übergeben und der Knopf "reset"
		buttonPanel.setLayout(new FlowLayout());
		//buttonPanel.add(reset);
		buttonPanel.add(quit);
		
		quit.addActionListener(this);
	
		// dem racePanel wird Layout(null) übergeben und alle JLabels mit den Bildern der Fahrer
		racePanel.setLayout(null);
		//racePanel.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
		racePanel.add(mario);
		racePanel.add(luigi);
		racePanel.add(peach);
		racePanel.add(yoshi);
		racePanel.add(dk);
		racePanel.add(bowser);
		racePanel.add(koppa);
		racePanel.add(toad);
	
		// den JLables(Bilder) muss jetzt Standort (x-achse und y-achse) und die effektive Grösse des JLabels (Hier habe ich die genau
		// die Grösse der Bilder genommen (32px, 32px)) übergeben werden
		mario.setBounds(10,50, a, a);
		luigi.setBounds(10,82, a, a);
		peach.setBounds(10,114, a, a);
		yoshi.setBounds(10,146, a, a);
		dk.setBounds(10,178, 32, a);
		bowser.setBounds(10,210, a, a);
		koppa.setBounds(10,242, a, a);
		toad.setBounds(10,274, a, a);

		addKeyListener(this);
	
		show();
		
	}
	
	
	public static void main(String args[]) {		
		
		MarioKart mk = new MarioKart();
	}
	
	
	public void movemario(int b1){
		
		if (b1 == 1){

			mario.getLocation().getX();
			mario.setLocation((10+50), 10);

		}
	}
	
	public  void keyPressed(KeyEvent e) {
	
		if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
		
			System.out.println("hallo");
			movemario(1);
			
			
			//mx = mx+=100;
			
			/*mario.setBounds(200,50,a,a);
			mario.setLocation(200,50);
			mario.setVisible(true);*/
		
		}
	}

	public void keyReleased(KeyEvent event) {
		
		System.out.println("hallo");
		/*if (event.getKeyCode() == KeyEvent.VK_F10) {
			
			//mario.setBounds(200,50,a,a);
			mario.setLocation(200,50);
			//mario.setVisible(false);
		
		}*/
	}


	public void keyTyped(KeyEvent arg0) {
		
		System.out.println("hallo");
		
		/*if (arg0.getKeyCode() == KeyEvent.VK_F10) {
			
			mario.setBounds(200,50,a,a);
			mario.setLocation(200,50);
			mario.setVisible(true);
		
		}*/
	}


	public void actionPerformed(ActionEvent arg0) {
		
		if (arg0.getSource() == quit) {
			System.exit(0);
			}
		
	}


	

}
```


----------



## Leroy42 (29. Sep 2006)

```
mario.getLocation().getX(); 
mario.setLocation((10+50), 10);
```

Die erste Anweisung dürfte sinnlos sein, da sie ja nur
einen Wert ins Nirwana liefert (Es, sei denn, daß deine getX-Methode
etwas verändert)

Die zweite Anweisung setzt die Koordinaten immer auf denselben Wert.


Und schließlich vermisse ich in der Routine einen Aufruf von repaint()


----------



## Gast (2. Okt 2006)

ja was würde es denn für eine Lösung geben? habe x sachen ausprobiert und der Fahrer sollte um eine gewisse x-zahl bei click von der f10 taste nach rechts gehen, doch zum test des KeyListener habe ich noch ein System.out.println("");
und diesen inhalt gibt es mir auch nicht aus, was ja heisst das der KeyListener gar nicht funktioniert.


----------



## LoN_Nemesis (2. Okt 2006)

```
mario.setLocation(mario.getLocation().getX()+10, mario.getLocation().getY());
```

Wie wärs damit?


----------



## Gast (3. Okt 2006)

habs jetzt mal ausprobiert, was noch nicht geht ist nach wie vor der KeyListener hab das mit dem Focusable ein paar mal ausprobiert aber es ist weiter nicht gegangen, und es gibt mir ein Fehler im Eclipse aus bei mario.setLocation...
hier nochmal der code, verzwefle langsam aber sicher wirklich....


```
import java.awt.BorderLayout;

import java.awt.Container;
import java.awt.FlowLayout;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;


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


public class MarioKart extends JFrame implements KeyListener, ActionListener {

   int a = 32;

   
   
   
   JPanel buttonPanel = new JPanel();
   JPanel racePanel = new JPanel();
   
   //private JButton reset = new JButton("Restart Race");
   private JButton quit = new JButton("Exit Game");

   //ImageIcon mario = new ImageIcon(getIconImage(), "Mario.gif");
   JLabel mario = new JLabel(new ImageIcon("Mario.gif"));
   JLabel luigi = new JLabel(new ImageIcon("Luigi.gif"));
   JLabel peach = new JLabel(new ImageIcon("Peach.gif"));
   JLabel yoshi = new JLabel(new ImageIcon("Yoshi.gif"));
   JLabel dk = new JLabel(new ImageIcon("DK.gif"));
   JLabel bowser = new JLabel(new ImageIcon("Bowser.gif"));
   JLabel koppa = new JLabel(new ImageIcon("Koppa.gif"));
   JLabel toad = new JLabel(new ImageIcon("Toad.gif"));
   
   private Container contentPane = new Container();
   
   
   
   public MarioKart() {
      
      setSize(600, 400);
      setTitle("Mario Grand-Prix");
      setDefaultCloseOperation(EXIT_ON_CLOSE);
      
      
   
      // dem Container wird das Layout und die Panels übergeben
      contentPane = this.getContentPane();
      contentPane.setLayout(new BorderLayout());
      contentPane.add(BorderLayout.NORTH, buttonPanel);
      contentPane.add(BorderLayout.CENTER, racePanel);
      
      // dem buttonPanel wird ein Layout übergeben und der Knopf "reset"
      buttonPanel.setLayout(new FlowLayout());
      
      //buttonPanel.add(reset);
      buttonPanel.add(quit);
      setFocusable(false);
      quit.addActionListener(this);
   
      
      // dem racePanel wird Layout(null) übergeben und alle JLabels mit den Bildern der Fahrer
      racePanel.setLayout(null);
      
      //racePanel.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
      racePanel.add(mario);
      racePanel.add(luigi);
      racePanel.add(peach);
      racePanel.add(yoshi);
      racePanel.add(dk);
      racePanel.add(bowser);
      racePanel.add(koppa);
      racePanel.add(toad);
      
   
      // den JLables(Bilder) muss jetzt Standort (x-achse und y-achse) und die effektive Grösse des JLabels (Hier habe ich die genau
      // die Grösse der Bilder genommen (32px, 32px)) übergeben werden
      mario.setBounds(10,50,a,a);
      luigi.setBounds(10,82, a, a);
      peach.setBounds(10,114, a, a);
      yoshi.setBounds(10,146, a, a);
      dk.setBounds(10,178, 32, a);
      bowser.setBounds(10,210, a, a);
      koppa.setBounds(10,242, a, a);
      toad.setBounds(10,274, a, a);

      setVisible(true);
      addKeyListener(this);
      setFocusable(true);
      
      
   }
   
   
   /*public void movemario(int b1){
   
      if (b1 == 1){

         //mario.getLocation().getX();
         mario.setBounds(mx+100,50,a,a);
         //mx = mx+100;
         
      }
   }*/
   
      public void keyPressed(KeyEvent e) {
   
         if (e.getKeyCode() == KeyEvent.VK_N) {
             
       
            System.out.println("hallo");
            mario.setLocation(mario.getLocation().getX()+10, mario.getLocation().getY());
            
      
         }
      
      }

      public void keyReleased(KeyEvent e) {}


      public void keyTyped(KeyEvent e) {}
   


   public void actionPerformed(ActionEvent arg0) {
      
      if (arg0.getSource() == quit) {
         System.exit(0);
         }
      
   }
   public static void main(String args[]) {      
      
      MarioKart mk = new MarioKart();
   }
}
```


----------



## SlaterB (3. Okt 2006)

der Aufruf muss
mario.setLocation((int) (mario.getLocation().getX() + 10),(int) mario.getLocation().getY());
heißen,

bei mir funktioniert der KeyListener wenn nicht der quit-Button sondern das JPanel/ JFrame den Focus hat,
einfach am Anfang einmal Tab drücken, dann gehts

alternativ mit 
quit.addKeyListener(this);
auch dem quit-Button den KeyListener zuweisen,
oder den Anfangsfoucs auf ein anderes Element legen 
oder einen globalen KeyListener benutzen, der überall mithört,

zu den letzten beiden Möglichkeiten einen Thread im Allgemein- oder Anfängerfragen-Forum eröffnen, falls nicht klar
(vorher die Forumsuche bemühen!)

-----------

KeyEvent.VK_N ist übrigens die N-Taste, nicht F10?
ich würde dir auch eine dieser statt der F-Tasten empfehlen,
zumindest bei mir reagiert der KeyListener da etwas merkwürdig,

dein System.out.println("hallo");  ist falsch plaziert,
denn es reagiert nur wenn auch die richtige Taste gedrückt wurde,
zum Testen lieber außerhalb der if-Abfrage schreiben, 
dann siehst wann überhaupt (und welche) Tasten gedrückt wurden,

noch besser:

```
public void keyPressed(KeyEvent e) {
		System.out.println("keyPressed "+e.getKeyCode()+" - "+KeyEvent.VK_N);
		if (e.getKeyCode() == KeyEvent.VK_N) {

			mario.setLocation(
				(int) (mario.getLocation().getX() + 10),
				(int) mario.getLocation().getY());

		}

	}

	public void keyReleased(KeyEvent e) {
		System.out.println("keyReleased "+e.getKeyCode());
	}

	public void keyTyped(KeyEvent e) {
		System.out.println("keyTyped "+e.getKeyCode());
	}
```


----------



## Gast (3. Okt 2006)

also wenn ich, wie du gesagt hast, den "quit Button" dem KeyListener hinzufüge und den Fokus auf dem Button lasse, dann funktioniert das ganze, es kommt die Ausgabe "hallo" und die Bilder bewegen sich, doch wenn ich den Fokus so wie eigentlich gewollt auf mein racePanel setze geht es nicht komisch und das mit dem Tab geht auch nicht. Jedenfall geht es jetzt =)

Danke


----------



## marthi (24. Okt 2006)

Hallo,
füge deiner klasse doch mal folgende Methode hinzu:

private void addKeyAndContainerListener(Component c)
    {
        c.removeKeyListener(this);
        c.addKeyListener(this);
        if(c instanceof Container)
        {
            Container cont = (Container) c;
            cont.removeContainerListener(this);
            cont.addContainerListener(this);
            Component[] children = cont.getComponents();
            for(int i=0; i<children.length; i++)
            {
                addKeyAndContainerListener(children_);
            }       
        }
    }

und in Zeile 96 Kommentierst du deine Zeile aus und gibst folgendes ein:

addKeyAndContainerListener(this);

Dann sollte das Focus Problem behoben sein. ;-)_


----------

