keylistener 没有响应任何键?
keylistener is not responding to any keys?
我正在尝试为响应 "w" 键的玩家移动脚本编写一个简单的按键事件。我希望最终让它做一些像移动角色这样的事情,但现在我只是想让它做出回应。我对 java 比较陌生,所以请详细说明。另请注意,当我真正开始工作时,播放器不会成为文本区域我只是还不想显示图像和动画。我已经包含了很多评论来解释我在每一行上试图做的事情。希望有帮助!到目前为止,这是我的代码:
import javax.swing.*; //importing swing for gui stuff
import java.awt.*; //importing awt for gui stuff
import java.awt.event.*; //importing awt event so i can add listeners
public class game { //creates the class
static String player = "Player"; //initializes the variable for text i will put in the text area
public static void main(String args[]) { //making a function (main) to run automatically and initialize the game
JFrame f = new JFrame("Javax Swing UI"); //create frame for GUI
GridLayout l = new GridLayout(2,4);
f.setSize(300,300); //set the size of the frame in pixels x,y
JTextArea t = new JTextArea(5,10); //create a text area to act as the player for the game (until i get an image working)
t.append(player);
t.setEditable(false); //make it so you cant edit the text area
f.add(t);
f.setLayout(l);
f.setVisible(true); //load the frame and all objects inside it
}
public static void movement(JTextArea t) { //creating a method for moving my "character"
t.addKeyListener(new KeyAdapter() { //adding key listener to my text area
public void keyPressed(KeyEvent e) { //creating the method to respond to my key listener
int key = e.getKeyCode(); //getting the key the user types
if (key == KeyEvent.VK_W) { //checking if the key is "w"
System.out.println("if key == w !!! working"); //prints that the if statement is working
}
}
});
}
}
没有错误,编译正常,运行正常,但键盘监听器没有响应 "w" 键。我认为它与关键代码或我的逻辑语句有关。我稍后会担心格式化,但正如我所说,我只是想让 keyevent 起作用。如果在 java 方面更有经验的人可以提供帮助,那就太好了! (我正在使用 java 8)。
编辑 [已解决]:我已经开始使用 KeyStrokes
编写出@DontKnowMuchButGetting Better 的答案,并且我 运行 解决了这个问题:
java:9: error: ';' expected
public void actionPerformed(ActionEvent e) {
java:9: error: ';' expected
public void actionPerformed(ActionEvent e) {
^
2 errors
抛出错误的代码看起来有点像这样:
public class move extends AbstractAction {
public static void main(int right, int down) {
int right = right;
int down = down;
@Override
public void actionPerformed(ActionEvent e) {
x += right * 4;
y += down * 4;
repaint();
}
}
}
编辑:
解决了上次编辑,做了一些工作,我现在收到这些错误:
game.java:39: error: cannot find symbol
String whenfocused = WHEN_IN_FOCUSED_WINDOW;
^
symbol: variable WHEN_IN_FOCUSED_WINDOW
location: class game
game.java:40: error: cannot find symbol
InputMap inputs = InputMap(whenfocused);
^
symbol: method InputMap(String)
location: class game
game.java:41: error: cannot find symbol
ActionMap actions = ActionMap();
^
symbol: method ActionMap()
location: class game
game.java:44: error: Action is abstract; cannot be instantiated
m = new Action();
^
game.java:46: error: incompatible types: game.move cannot be converted to Action
actions.put(key.toString(), m);
^
game.java:62: error: cannot find symbol
g.repaint();
^
symbol: method repaint()
location: variable g of type Graphics
Note: Some messages have been simplified; recompile with -Xdiags:verbose to get full output
6 errors
这是我的新代码:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.*;
import java.applet.Applet;
public class game { //creates the class
public static final int ph = 300;
public static final int pw = 300;
public final int w = 20;
public final int h = 20;
public int x = (pw - w) / 2;
public int y = (ph - h) / 2;
public void main(String args[]) { //making a function (main) to run automatically and initialize the game
JFrame f = new JFrame("Javax Swing UI"); //create frame for GUI
f.setSize(ph, pw); //set the size of the frame in pixels x,y
f.setBackground(Color.WHITE);
f.setVisible(true); //load the frame and all objects inside it
KeyStroke left = KeyStroke.getKeyStroke(KeyEvent.VK_A, 0);
KeyStroke down = KeyStroke.getKeyStroke(KeyEvent.VK_S, 0);
KeyStroke right = KeyStroke.getKeyStroke(KeyEvent.VK_D, 0);
KeyStroke up = KeyStroke.getKeyStroke(KeyEvent.VK_W, 0);
keyAdd(up, -1, 0);
keyAdd(down, 0, 1);
keyAdd(right, 1, 0);
keyAdd(left, -1, 0);
}
public void keyAdd(KeyStroke key, int right, int down) {
String whenfocused = WHEN_IN_FOCUSED_WINDOW;
InputMap inputs = InputMap(whenfocused);
ActionMap actions = ActionMap();
move m = new move(right, down);
m = new Action();
inputs.put(key, key.toString());
actions.put(key.toString(), m);
}
private class move {
private int down;
private int right;
public move(int right, int down) {
this.right = right;
this.down = down;
}
public void actionPerformed(ActionEvent e, int down, int right, Graphics g) {
x += right * 4;
y += down * 4;
g.repaint();
}
}
protected void paintComponent(Graphics g,int x,int y,int w,int h, Color color) {
g.setColor(color);
g.fillRect(x, y, w, h);
}
}
如果您想根据已按下的击键移动 "player",请根据我对您的原始 post 的评论,使用键绑定,而不是 KeyListener。一方面,即使绑定的组件没有焦点,Key Bindings 也可以工作,这可以通过传递给 JComponent#getInputMap(...)
方法的条件 int 来控制。在下面的示例中,我传入了 JComponent.WHEN_IN_FOCUSED_WINDOW
,这意味着如果组件位于具有焦点的 window 中,即使实际键盘焦点位于该 [= 持有的另一个组件上,绑定也会响应28=].
键绑定教程可以在这里找到:How to Use Key Bindings
这是一个移动红色小矩形的演示程序,我的 "sprite" 基于用户按下箭头键:
请查看代码注释以了解有关此代码的作用的更多信息
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.*;
@SuppressWarnings("serial")
public class MoveSomething extends JPanel {
private static final int PANEL_WIDTH = 800;
private static final int PANEL_HEIGHT = 600;
private static final Color SPRITE_COLOR = Color.RED;
private static final int SPRITE_W = 20;
public static final int DELTA = 4;
private int spriteX = (PANEL_WIDTH - SPRITE_W) / 2;
private int spriteY = (PANEL_HEIGHT - SPRITE_W) / 2;
public MoveSomething() {
setPreferredSize(new Dimension(PANEL_WIDTH, PANEL_HEIGHT));
setBackground(Color.WHITE);
// keystrokes that the program will respond to
// you can use the "w" key as well, simply via KeyEvent.VK_W
KeyStroke upStroke = KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0);
KeyStroke downStroke = KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0);
KeyStroke leftStroke = KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0);
KeyStroke rightStroke = KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0);
// submit the key stroke for binding along with two int parameters
// the right parameter that tells us if the key stroke should move things right (+1) or left (-1)
// and the down parameter for moving sprite down (+1) or up (-1)
submitKeyBinding(upStroke, 0, -1);
submitKeyBinding(downStroke, 0, 1);
submitKeyBinding(leftStroke, -1, 0);
submitKeyBinding(rightStroke, 1, 0);
}
private void submitKeyBinding(KeyStroke keyStroke, int right, int down) {
// set key bindings:
int condition = WHEN_IN_FOCUSED_WINDOW;
InputMap inputMap = getInputMap(condition);
ActionMap actionMap = getActionMap();
inputMap.put(keyStroke, keyStroke.toString());
actionMap.put(keyStroke.toString(), new MoveAction(right, down));
}
// action used by the bindings to do the actual movement
private class MoveAction extends AbstractAction {
private int right;
private int down;
public MoveAction(int right, int down) {
this.right = right;
this.down = down;
}
@Override
public void actionPerformed(ActionEvent e) {
spriteX += right * DELTA;
spriteY += down * DELTA;
repaint(); // redraw the GUI
}
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(SPRITE_COLOR);
g.fillRect(spriteX, spriteY, SPRITE_W, SPRITE_W);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
private static void createAndShowGui() {
MoveSomething mainPanel = new MoveSomething();
JFrame frame = new JFrame("MoveSomething");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
我正在尝试为响应 "w" 键的玩家移动脚本编写一个简单的按键事件。我希望最终让它做一些像移动角色这样的事情,但现在我只是想让它做出回应。我对 java 比较陌生,所以请详细说明。另请注意,当我真正开始工作时,播放器不会成为文本区域我只是还不想显示图像和动画。我已经包含了很多评论来解释我在每一行上试图做的事情。希望有帮助!到目前为止,这是我的代码:
import javax.swing.*; //importing swing for gui stuff
import java.awt.*; //importing awt for gui stuff
import java.awt.event.*; //importing awt event so i can add listeners
public class game { //creates the class
static String player = "Player"; //initializes the variable for text i will put in the text area
public static void main(String args[]) { //making a function (main) to run automatically and initialize the game
JFrame f = new JFrame("Javax Swing UI"); //create frame for GUI
GridLayout l = new GridLayout(2,4);
f.setSize(300,300); //set the size of the frame in pixels x,y
JTextArea t = new JTextArea(5,10); //create a text area to act as the player for the game (until i get an image working)
t.append(player);
t.setEditable(false); //make it so you cant edit the text area
f.add(t);
f.setLayout(l);
f.setVisible(true); //load the frame and all objects inside it
}
public static void movement(JTextArea t) { //creating a method for moving my "character"
t.addKeyListener(new KeyAdapter() { //adding key listener to my text area
public void keyPressed(KeyEvent e) { //creating the method to respond to my key listener
int key = e.getKeyCode(); //getting the key the user types
if (key == KeyEvent.VK_W) { //checking if the key is "w"
System.out.println("if key == w !!! working"); //prints that the if statement is working
}
}
});
}
}
没有错误,编译正常,运行正常,但键盘监听器没有响应 "w" 键。我认为它与关键代码或我的逻辑语句有关。我稍后会担心格式化,但正如我所说,我只是想让 keyevent 起作用。如果在 java 方面更有经验的人可以提供帮助,那就太好了! (我正在使用 java 8)。
编辑 [已解决]:我已经开始使用 KeyStrokes
编写出@DontKnowMuchButGetting Better 的答案,并且我 运行 解决了这个问题:
java:9: error: ';' expected
public void actionPerformed(ActionEvent e) {
java:9: error: ';' expected
public void actionPerformed(ActionEvent e) {
^
2 errors
抛出错误的代码看起来有点像这样:
public class move extends AbstractAction {
public static void main(int right, int down) {
int right = right;
int down = down;
@Override
public void actionPerformed(ActionEvent e) {
x += right * 4;
y += down * 4;
repaint();
}
}
}
编辑: 解决了上次编辑,做了一些工作,我现在收到这些错误:
game.java:39: error: cannot find symbol
String whenfocused = WHEN_IN_FOCUSED_WINDOW;
^
symbol: variable WHEN_IN_FOCUSED_WINDOW
location: class game
game.java:40: error: cannot find symbol
InputMap inputs = InputMap(whenfocused);
^
symbol: method InputMap(String)
location: class game
game.java:41: error: cannot find symbol
ActionMap actions = ActionMap();
^
symbol: method ActionMap()
location: class game
game.java:44: error: Action is abstract; cannot be instantiated
m = new Action();
^
game.java:46: error: incompatible types: game.move cannot be converted to Action
actions.put(key.toString(), m);
^
game.java:62: error: cannot find symbol
g.repaint();
^
symbol: method repaint()
location: variable g of type Graphics
Note: Some messages have been simplified; recompile with -Xdiags:verbose to get full output
6 errors
这是我的新代码:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.*;
import java.applet.Applet;
public class game { //creates the class
public static final int ph = 300;
public static final int pw = 300;
public final int w = 20;
public final int h = 20;
public int x = (pw - w) / 2;
public int y = (ph - h) / 2;
public void main(String args[]) { //making a function (main) to run automatically and initialize the game
JFrame f = new JFrame("Javax Swing UI"); //create frame for GUI
f.setSize(ph, pw); //set the size of the frame in pixels x,y
f.setBackground(Color.WHITE);
f.setVisible(true); //load the frame and all objects inside it
KeyStroke left = KeyStroke.getKeyStroke(KeyEvent.VK_A, 0);
KeyStroke down = KeyStroke.getKeyStroke(KeyEvent.VK_S, 0);
KeyStroke right = KeyStroke.getKeyStroke(KeyEvent.VK_D, 0);
KeyStroke up = KeyStroke.getKeyStroke(KeyEvent.VK_W, 0);
keyAdd(up, -1, 0);
keyAdd(down, 0, 1);
keyAdd(right, 1, 0);
keyAdd(left, -1, 0);
}
public void keyAdd(KeyStroke key, int right, int down) {
String whenfocused = WHEN_IN_FOCUSED_WINDOW;
InputMap inputs = InputMap(whenfocused);
ActionMap actions = ActionMap();
move m = new move(right, down);
m = new Action();
inputs.put(key, key.toString());
actions.put(key.toString(), m);
}
private class move {
private int down;
private int right;
public move(int right, int down) {
this.right = right;
this.down = down;
}
public void actionPerformed(ActionEvent e, int down, int right, Graphics g) {
x += right * 4;
y += down * 4;
g.repaint();
}
}
protected void paintComponent(Graphics g,int x,int y,int w,int h, Color color) {
g.setColor(color);
g.fillRect(x, y, w, h);
}
}
如果您想根据已按下的击键移动 "player",请根据我对您的原始 post 的评论,使用键绑定,而不是 KeyListener。一方面,即使绑定的组件没有焦点,Key Bindings 也可以工作,这可以通过传递给 JComponent#getInputMap(...)
方法的条件 int 来控制。在下面的示例中,我传入了 JComponent.WHEN_IN_FOCUSED_WINDOW
,这意味着如果组件位于具有焦点的 window 中,即使实际键盘焦点位于该 [= 持有的另一个组件上,绑定也会响应28=].
键绑定教程可以在这里找到:How to Use Key Bindings
这是一个移动红色小矩形的演示程序,我的 "sprite" 基于用户按下箭头键:
请查看代码注释以了解有关此代码的作用的更多信息
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.*;
@SuppressWarnings("serial")
public class MoveSomething extends JPanel {
private static final int PANEL_WIDTH = 800;
private static final int PANEL_HEIGHT = 600;
private static final Color SPRITE_COLOR = Color.RED;
private static final int SPRITE_W = 20;
public static final int DELTA = 4;
private int spriteX = (PANEL_WIDTH - SPRITE_W) / 2;
private int spriteY = (PANEL_HEIGHT - SPRITE_W) / 2;
public MoveSomething() {
setPreferredSize(new Dimension(PANEL_WIDTH, PANEL_HEIGHT));
setBackground(Color.WHITE);
// keystrokes that the program will respond to
// you can use the "w" key as well, simply via KeyEvent.VK_W
KeyStroke upStroke = KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0);
KeyStroke downStroke = KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0);
KeyStroke leftStroke = KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0);
KeyStroke rightStroke = KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0);
// submit the key stroke for binding along with two int parameters
// the right parameter that tells us if the key stroke should move things right (+1) or left (-1)
// and the down parameter for moving sprite down (+1) or up (-1)
submitKeyBinding(upStroke, 0, -1);
submitKeyBinding(downStroke, 0, 1);
submitKeyBinding(leftStroke, -1, 0);
submitKeyBinding(rightStroke, 1, 0);
}
private void submitKeyBinding(KeyStroke keyStroke, int right, int down) {
// set key bindings:
int condition = WHEN_IN_FOCUSED_WINDOW;
InputMap inputMap = getInputMap(condition);
ActionMap actionMap = getActionMap();
inputMap.put(keyStroke, keyStroke.toString());
actionMap.put(keyStroke.toString(), new MoveAction(right, down));
}
// action used by the bindings to do the actual movement
private class MoveAction extends AbstractAction {
private int right;
private int down;
public MoveAction(int right, int down) {
this.right = right;
this.down = down;
}
@Override
public void actionPerformed(ActionEvent e) {
spriteX += right * DELTA;
spriteY += down * DELTA;
repaint(); // redraw the GUI
}
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(SPRITE_COLOR);
g.fillRect(spriteX, spriteY, SPRITE_W, SPRITE_W);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
private static void createAndShowGui() {
MoveSomething mainPanel = new MoveSomething();
JFrame frame = new JFrame("MoveSomething");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}