问题
I need to know if it is possible to have an action only happen once when a key is pressed, even if that key is held down for some time, and if it is possible, how? This is the code I have for that now:
if(e.getKeyCode() == KeyEvent.VK_A)
{
attack = true;
moveX = -5;
draw(moveX, moveY);
players.get(username).setImageIcon("attack-left");
}
This is within the keyPressed method, and in the keyReleased I set moveX to 0. So if A is pressed the image is supposed to 5 units to the left and stop, regardless of whether or not A is still being held down or it has been released. But this is not working, it just keeps on moving to the left. I tried using keyTyped but it didn't work.
Thanks in advance, and if needed I can provide more code.
回答1:
One way to do this is to save the last key pressed into a field. Then, if the current key pressed is the same as the last key pressed, don't do anything. On a key up, clear the field.
Here's some example code:
package com.sandbox;
import javax.swing.JFrame;
import javax.swing.WindowConstants;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.IOException;
public class SwingSandbox {
private static Character lastKey = null;
public static void main(String[] args) throws IOException {
JFrame frame = buildFrame();
frame.addKeyListener(new KeyListener() {
@Override
public void keyTyped(KeyEvent e) {
if (lastKey == null || lastKey != e.getKeyChar()) {
lastKey = e.getKeyChar();
System.out.println("keyTyped: " + lastKey);
}
}
@Override
public void keyPressed(KeyEvent e) {
if (lastKey == null || lastKey != e.getKeyChar()) {
lastKey = e.getKeyChar();
System.out.println("keyPressed: " + lastKey);
}
}
@Override
public void keyReleased(KeyEvent e) {
lastKey = null;
System.out.println("keyReleased");
}
});
}
private static JFrame buildFrame() {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setSize(200, 200);
frame.setVisible(true);
return frame;
}
}
Despite what @schmop's comment says, I'm not experiencing that. With this code:
package com.sandbox;
import javax.swing.JFrame;
import javax.swing.WindowConstants;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.IOException;
public class SwingSandbox {
public static void main(String[] args) throws IOException {
JFrame frame = buildFrame();
frame.addKeyListener(new KeyListener() {
@Override
public void keyTyped(KeyEvent e) {
System.out.println("keyTyped");
}
@Override
public void keyPressed(KeyEvent e) {
System.out.println("keyPressed");
}
@Override
public void keyReleased(KeyEvent e) {
System.out.println("keyReleased");
}
});
}
private static JFrame buildFrame() {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setSize(200, 200);
frame.setVisible(true);
return frame;
}
}
This holding down a key prints this:
keyPressed keyTyped keyPressed keyTyped keyPressed keyTyped keyPressed keyTyped keyPressed keyTyped keyPressed keyTyped keyPressed keyTyped keyPressed keyTyped keyPressed keyTyped keyPressed keyTyped keyPressed keyTyped keyPressed keyTyped keyPressed keyTyped keyPressed keyTyped keyPressed keyTyped keyPressed keyTyped keyPressed keyTyped keyPressed keyTyped keyPressed keyTyped keyPressed keyTyped
回答2:
One way to fix your problem is to stop your moveX from moving when key is released.
public void keyReleased(KeyEvent e) {
moveX = 0;
moveY = 0; //If you have a moveY
}
来源:https://stackoverflow.com/questions/23642854/make-a-keyevent-in-java-only-happen-once-even-when-key-is-held