2011-12-14 21 views
13

Próbuję stworzyć silnik gry. Zrobiłem klasę gry, ale błąd znajduje się w klasie KeyBoard. Tutaj zostawiam kod.addKeyListener() nie działa dla JPanel

Class :: Gra

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); 
    } 

} 

Class :: KeyBoard

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; 
    } 

} 

Class :: 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); 
    } 

} 

Ale błąd był nie było rzucony wyjątek i ISN wejście Czytałem. Czy ktokolwiek mógłby mi powiedzieć, jak to zrobić prawidłowo?

+1

1) Aby uzyskać lepszą pomoc wcześniej, opublikuj [SSCCE] (http://sscce.org/). 2) Komponent musi być w stanie aktywować, zanim będzie mógł słuchać kluczowych zdarzeń. 3) Jeśli panel zawiera elementy takie jak drzewa lub tabele, składniki te będą wykorzystywać kluczowe zdarzenia. 4) Generalnie zaleca się stosowanie powiązań klawiszy w 'KeyListener'. 5) 'Thread.sleep (30);' Nie rób tego. Musiałem omówić to 3 razy w ciągu ostatnich 2 dni. Przeszukuj moje posty i komentarze, dlaczego. –

Odpowiedz

38

Po prostu panel musi być możliwy do ustawienia. Dodać w dowolnym miejscu utworzyć panel:

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

Oto SSCCE (Proponuję pytaniami z jednym z nich w przyszłości):

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); 

    } 
} 

również https://www.google.com/search?q=jpanel+keylistener

+1

* "Czy mógłbyś powiedzieć, co to jest sscce" * Mógłbym, ale powiedziałem to tyle razy, że w końcu umieściłem to na stronie internetowej. Ta sama strona internetowa została dwukrotnie * połączona * w tym wątku. Skorzystaj z linku do dokumentu. Przeczytaj to wszystko. Zapytaj, czy coś nie jest jasne. –

2

Możesz dodać kluczowy słuchacz JFrame, to jest coś, co robiłem w przeszłości. To prawdopodobnie nie jest dobry pomysł, jeśli masz inne elementy w ramce JFrame.

+1

Nie mam żadnych elementów w ramce, ale jpanele pasują do mnie, ponieważ mogą być używane w apletach. –

+1

Wierzę, że możesz dodać to również do Applet/JApplet, ale rozumiem, dlaczego chcesz zachować kod w JPanel – MadcoreTom