2011-12-14 14 views
13

Estoy tratando de hacer un motor de juego. He hecho la clase Game pero el error reside en la clase Keyboard. Aquí dejo un código.addKeyListener() no funciona para JPanel

Clase :: Juego

package transfer2pc.co.cc.game.tileengine; 

import java.awt.Graphics; 
import java.util.HashMap; 

import javax.swing.JPanel; 

import transfer2pc.co.cc.game.tileengine.input.KeyBoard; 

public abstract class Game extends JPanel implements Runnable { 

    /** 
    * 
    */ 
    private static final long serialVersionUID = 640206679500196209L; 

    HashMap<String, ?> maps = null; 

    KeyBoard keyBoard = null; 

    public Game(){ 
     super(); 
     keyBoard = new KeyBoard(this); 
     setKeyBoard(keyBoard); 
     Thread th = new Thread(this); 
     th.start(); 
    } 

    public void run(){ 
     while(true){ 
      repaint(); 
      try { 
       Thread.sleep(30); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
     } 
    } 

    @Override 
    public void paint(Graphics g){ 

    } 

    public void addMap(){ 

    } 

    public void setMap(){ 

    } 

    public abstract void keyPressed(int code); 

    public abstract void keyReleased(int code); 

    public abstract void keyTyped(int code); 

    public void setKeyBoard(KeyBoard key){ 
     addKeyListener(key); 
    } 

} 

Clase :: teclado de Clase

package transfer2pc.co.cc.game.tileengine.input; 

import java.awt.event.KeyAdapter; 
import java.awt.event.KeyEvent; 
import java.awt.event.KeyListener; 

import transfer2pc.co.cc.game.tileengine.Game; 

public class KeyBoard extends KeyAdapter implements KeyListener { 

    Game game = null; 

    public KeyBoard(Game gm){ 
     this.game = gm; 
    } 

    @Override 
    public void keyPressed(KeyEvent e) { 
     System.out.println("KeyPressed"); 
     game.keyPressed(e.getKeyCode()); 
    } 

    @Override 
    public void keyReleased(KeyEvent e) { 
     game.keyReleased(e.getKeyCode()); 
    } 

    @Override 
    public void keyTyped(KeyEvent e) { 
     game.keyTyped(e.getKeyCode()); 
    } 

    public static char getChar(int key){ 
     return (char)key; 
    } 

} 

:: Keytest

package transfer2pc.co.cc.game.tileengine.test; 

import java.awt.Graphics; 

import javax.swing.JFrame; 

import transfer2pc.co.cc.game.tileengine.Game; 
import transfer2pc.co.cc.game.tileengine.input.KeyBoard; 

public class KeyTest extends Game { 

    /** 
    * 
    */ 
    private static final long serialVersionUID = 8557676950779023327L; 

    char pressed; 

    public KeyTest(){ 
     super(); 
     addKeyListener(new KeyBoard(this)); 
    } 

    @Override 
    public void keyPressed(int code) { 
     pressed = KeyBoard.getChar(code); 
    } 


    @Override 
    public void keyReleased(int code) { 

    } 


    @Override 
    public void keyTyped(int code) { 

    } 

    @Override 
    public void paint(Graphics g){ 
     g.drawString("You pressed: "+pressed, 20, 20); 
    } 

    public static void main(String[] args){ 
     JFrame frame = new JFrame("KeyTest"); 
     frame.setSize(640, 480); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.setLocationRelativeTo(null); 
     frame.add(new KeyTest()); 
     frame.setVisible(true); 
    } 

} 

Pero el error era que no había excepción lanzada y la entrada de ISN no se lee ¿Alguien podría decirme la forma correcta de hacerlo ...

+1

1) Para una mejor ayuda antes, publique un [SSCCE] (http://sscce.org/). 2) Un componente debe ser enfocable antes de que pueda escuchar eventos clave. 3) Si un panel contiene cosas como árboles o tablas, esos componentes consumirán los eventos clave. 4) En general, se recomienda utilizar enlaces de teclas sobre un 'KeyListener'. 5) 'Thread.sleep (30);' No hagas eso. Debo haber discutido esto 3 veces en los últimos 2 días. Busque mis publicaciones y comentarios para saber por qué. –

Respuesta

38

Simplemente, su panel debe ser enfocable. Agrega en donde se crea el panel:

panel.setFocusable(true); 
panel.requestFocusInWindow(); 

He aquí una SSCCE (Sugiero que hacen preguntas con uno de ellos en el futuro):

import java.awt.Dimension; 
import java.awt.event.KeyEvent; 
import java.awt.event.KeyListener; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.SwingUtilities; 

public class SimpleKeyTest { 

    public static void main(String[] args) { 

     Runnable r = new Runnable() { 

      @Override 
      public void run() { 
       JFrame frame = new JFrame(); 
       JPanel panel = new JPanel(); 

       frame.getContentPane().add(panel); 

       panel.addKeyListener(new KeyListener() { 

        @Override 
        public void keyTyped(KeyEvent e) {} 

        @Override 
        public void keyReleased(KeyEvent e) {} 

        @Override 
        public void keyPressed(KeyEvent e) { 
         System.out.println("Pressed " + e.getKeyChar()); 
        } 
       }); 

       panel.setFocusable(true); 
       panel.requestFocusInWindow(); 

       frame.setSize(new Dimension(300, 300)); 
       frame.setVisible(true); 
      } 

     }; 

     SwingUtilities.invokeLater(r); 

    } 
} 

Además, https://www.google.com/search?q=jpanel+keylistener

+1

* "podrías decir lo que es una sscce" * Podría, pero lo he dicho tantas veces que al final lo puse en una página web. La misma página web vinculada * dos veces * ya está en este hilo. Sigue el enlace al documento. Léelo todo. Pregunte si algo no está claro. –

2

Puedes añadir el oyente clave del JFrame, eso es algo que he hecho en el pasado. Sin embargo, probablemente no sea una buena idea si tiene otros componentes en el JFrame.

+1

No tengo ningún componente en el marco, pero los jpanels se adaptan a mí ya que se pueden usar en applets. –

+1

Creo que también puedes agregarlo al Applet/JApplet, pero entiendo por qué querrías conservar el código en JPanel – MadcoreTom