2013-05-05 109 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了解更多详情