2013-05-05 107 views
1

我一直在嘗試解決這個問題約5個小時,但我無法弄清楚爲什麼我的KeyListener根本沒有反應。它甚至看起來並沒有達到它尋找keyInput的地步? 這是它被稱爲在類:KeyListener根本沒有反應

package summonit; 

import java.awt.event.KeyEvent; 
import java.awt.event.KeyListener; 
import java.io.IOException; 

public class Player extends KleinerScreen implements KeyListener { 

    public Player() throws IOException{ 
     addKeyListener(this); 
    } 
    public static int playerX=20; 
    public static int playerY; 

    @Override 
    public void keyTyped(KeyEvent e) { 
     if (e.getKeyCode() == KeyEvent.VK_K) { 
      playerX += 100; 
     } 
     System.out.println(playerX); 
     repaint(); 
    } 

    @Override 
    public void keyPressed(KeyEvent e) { 
     if (e.getKeyCode() == KeyEvent.VK_K) { 
      playerX += 100; 
     } 
     System.out.println(playerX); 
     repaint(); 

    } 

    @Override 
    public void keyReleased(KeyEvent e) { 
    } 

}

和主類:

package summonit; 
import java.awt.*; 
import java.io.IOException; 
import javax.swing.JFrame; 

public class Summonit extends JFrame{ 

    public static void main(String[] args) throws IOException { 

     Summonit game = new Summonit(); 
     Screen window = new Screen(); 
     TileMap tilemap = new TileMap(); 
     Player player = new Player(); 

    } 
} 

面板類

/* 
* To change this template, choose Tools | Templates 
* and open the template in the editor. 
*/ 
package summonit; 

import java.awt.Dimension; 
import java.awt.Graphics; 
import java.awt.Image; 
import java.awt.image.BufferedImage; 
import java.io.BufferedReader; 
import java.io.File; 
import java.io.FileReader; 
import java.io.IOException; 
import javax.imageio.ImageIO; 
import javax.swing.ImageIcon; 
import javax.swing.JPanel; 

/** 
* 
* @author Boyen 
*/ 
public class KleinerScreen extends JPanel { 

    String i = "457528_3569247037775_1427420686_o.jpg"; 
    String s = "City.txt"; 
    public static Dimension windowsize = new Dimension(1000, 1000); 
    private int mapWidth; 
    private int mapHeight; 
    public int map[][]; 
    final int playerRows = 4; 
    final int playerCols = 4; 
    //images of tiles 
    private Image tileYellowPath; 
    private Image tileGround; 
    BufferedImage bigPlayerImg; 
    BufferedImage[] sprites; 
    //images 

    public KleinerScreen() throws IOException { 
     setPreferredSize(windowsize); 

     tileYellowPath = new ImageIcon(getClass().getResource("/CorrodedTechnoTiles.png")).getImage(); 
     tileGround = new ImageIcon(getClass().getResource("/images.jpg")).getImage(); 
     bigPlayerImg = ImageIO.read(new File("res/sprites_player_3.png")); 
     sprites = new BufferedImage[playerRows * playerCols]; 
     for (int i = 0; i < playerRows; i++) { 
      for (int j = 0; j < playerCols; j++) { 
       sprites[(i * playerCols) + j] = bigPlayerImg.getSubimage(
         j * 150, 
         i * 150, 
         150, 
         150); 
      } 
     } 

    } 

    public void readTiles() { 
    } 

    public void paint(Graphics g) { 
     for (int i = 0; i < TileMap.map.length; i++) { 
      for (int j = 0; j < TileMap.map[i].length; j++) { 

       switch (TileMap.map[i][j]) { 
        case 0: 
         g.drawImage(tileGround, windowsize.width/10 * j, windowsize.height/10 * i, windowsize.height/10, windowsize.width/10, null); 
         break; 
        case 1: 
         g.drawImage(tileYellowPath, windowsize.width/10 * j, windowsize.height/10 * i, windowsize.height/10, windowsize.width/10, null); 
         break; 

       } 
      } 
     } 
     g.drawImage(sprites[5], Player.playerX, 0 ,100,100,null); 
    } 
} 
+1

您是否在搜索論壇?有很多「爲什麼我的關鍵聽衆沒有工作」的問題,都有相同的答案。 – camickr 2013-05-05 21:27:47

回答

4

使用Key Bindings。這裏是一個簡短的例子來說明如何使用它們:

public class Test 
{ 
    JFrame frame = new JFrame(); 

    public Test() 
    { 
     ActionMap actionMap = frame.getRootPane().getActionMap(); 
     InputMap inputMap = frame.getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW); 

     for (Keys direction : Keys.values()) 
     { 
      actionMap.put(direction.getText(), new KeyBinding(direction.getText())); 
      inputMap.put(direction.getKeyStroke(), direction.getText()); 
     } 
     frame.getRootPane().setActionMap(actionMap); 
     frame.getRootPane().setInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW, inputMap); 
     frame.setVisible(true); 
    } 

    private class KeyBinding extends AbstractAction 
    { 

     private static final long serialVersionUID = 1L; 

     public KeyBinding(String text) 
     { 
      super(text); 
      putValue(ACTION_COMMAND_KEY, text); 
     } 

     @Override 
     public void actionPerformed(ActionEvent e) 
     { 
      String action = e.getActionCommand(); 
      System.out.println("Key Binding: " + action); 
     } 
    } 

    public static void main(String... args) 
    { 
     new Test(); 
    } 
} 

enum Keys 
{ 
    ESCAPE("Escape", KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0)), 
    CTRLC("Control-C", KeyStroke.getKeyStroke(KeyEvent.VK_C, KeyEvent.CTRL_DOWN_MASK)), 
    CTRLP("Control-P", KeyStroke.getKeyStroke(KeyEvent.VK_P, KeyEvent.CTRL_DOWN_MASK)), 
    UP("Up", KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0)), 
    DOWN("Down", KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0)), 
    LEFT("Left", KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0)), 
    RIGHT("Right", KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0)); 

    private String text; 
    private KeyStroke keyStroke; 

    Keys(String text, KeyStroke keyStroke) 
    { 
     this.text = text; 
     this.keyStroke = keyStroke; 
    } 

    public String getText() 
    { 
     return text; 
    } 

    public KeyStroke getKeyStroke() 
    { 
     return keyStroke; 
    } 

    @Override 
    public String toString() 
    { 
     return text; 
    } 
} 
+0

感謝您的快速回答,我不完全理解所有的代碼,以及如何將其應用到我的項目中,但我會嘗試我最好的tommorow,謝謝! – Boyen 2013-05-05 20:51:26

+0

@Boyen當然可以。如果你不明白,請閱讀我完全鏈接到答案中的教程。如果您在關鍵綁定之後還有問題,請提問另一個關於SO的問題。 – syb0rg 2013-05-05 20:53:13

+0

但是,再次,你有任何解釋爲什麼這不適用於KeyListener? – Boyen 2013-05-05 20:59:43

0

如果其中有聽衆的組件沒有焦點的KeyListener的不火。當我查看代碼時,似乎並未實際將Player實例添加到JFrame,因此它無法獲得焦點。

我建議你將它添加到JFrame,並使用顯示幀this.setVisible(true); 這應該做的伎倆

+0

我很抱歉混淆,我會用我的面板類更新代碼 – Boyen 2013-05-05 20:47:04

1

KeyListeners會才反應過來,如果他們註冊的組件是可聚焦並具有焦點。大多數Swing頂級容器永遠不可能直接接收鍵盤焦點,因爲它們有一個JRootPane,其中包含一個contentPane(其他內容)ontop(防止它從未能夠接收鍵盤焦點),ontop其中,另外增加了一個組件。

這是KeyListeners的常見已知問題,也是我們推薦使用Key Bindings代替的主要原因。

一邊不是,你的自定義繪畫是令人擔憂的。你應該無效覆蓋油漆,而是使用paintComponent。您還應該致電super.paintXxx以確保Graphics上下文已正確地進行繪畫準備?

查看Performing Custom Painting瞭解更多詳情