我使用KeyAdpater
来获取事件和方法addKeyListener
并且正常工作。问题是当按下键时,动作只会出现一次,而不是在被按下时, 3-4秒后按住键,动作始终发生,这就是我想要的。
我想知道是否有好的方法可以一直按下从最开始的按键,而不是在按住3-4秒之后。
我想到了下一个解决方案,但也许已经有了实现的方法:
public abstract class MyKeyAdapter extends KeyAdapter{
private boolean isPressed = false;
private int pressedKey = 0;
Thread t = new Thread(new Runnable() {
@Override
public void run() {
while(isPressed)
keyPressedAction(pressedKey);
}
});
@Override
public void keyPressed(KeyEvent e) {
if(!isPressed){
pressedKey = e.getKeyCode();
t.start();
}
}
@Override
public void keyReleased(KeyEvent e) {
if(isPressed && e.getKeyCode()==pressedKey)}
isPressed = false;
}
public abstract void keyPressedAction(int key);
}
答案 0 :(得分:4)
我通过使用Key Bindings而不是KeyListener获得了很好的成功,并在按键时启动Swing Timer,然后在Swing版本上停止Timer。您可以使用此处的KeyStroke.getKeyStroke(int keyCode, int modifiers, boolean onKeyRelease)
方法将正确的KeyStroke对象传递到绑定组件的InputMap中来区分按键和释放:KeyStroke API。如果布尔参数为false,则输入将响应按键,如果参数为真则反转。
快速而不雅的例子:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import javax.swing.*;
@SuppressWarnings("serial")
public class KeyBindingEg extends JPanel {
private static final String UP_KEY_PRESSED = "up key pressed";
private static final String UP_KEY_RELEASED = "up key released";
private static final int UP_TIMER_DELAY = 200;
private static final Color FLASH_COLOR = Color.red;
private Timer upTimer;
private JLabel label = new JLabel();
public KeyBindingEg() {
label.setFont(label.getFont().deriveFont(Font.BOLD, 32));
label.setOpaque(true);
add(label);
setPreferredSize(new Dimension(400, 300));
int condition = WHEN_IN_FOCUSED_WINDOW;
InputMap inputMap = getInputMap(condition);
ActionMap actionMap = getActionMap();
KeyStroke upKeyPressed = KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0, false);
KeyStroke upKeyReleased = KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0, true);
inputMap.put(upKeyPressed, UP_KEY_PRESSED);
inputMap.put(upKeyReleased, UP_KEY_RELEASED);
actionMap.put(UP_KEY_PRESSED, new UpAction(false));
actionMap.put(UP_KEY_RELEASED, new UpAction(true));
}
private class UpAction extends AbstractAction {
private boolean onKeyRelease;
public UpAction(boolean onKeyRelease) {
this.onKeyRelease = onKeyRelease;
}
@Override
public void actionPerformed(ActionEvent evt) {
if (!onKeyRelease) {
if (upTimer != null && upTimer.isRunning()) {
return;
}
System.out.println("key pressed");
label.setText(UP_KEY_PRESSED);
upTimer = new Timer(UP_TIMER_DELAY, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
Color c = label.getBackground();
if (FLASH_COLOR.equals(c)) {
label.setBackground(null);
label.setForeground(Color.black);
} else {
label.setBackground(FLASH_COLOR);
label.setForeground(Color.white);
}
}
});
upTimer.start();
} else {
System.out.println("Key released");
if (upTimer != null && upTimer.isRunning()) {
upTimer.stop();
upTimer = null;
}
label.setText("");
}
}
}
private static void createAndShowGui() {
KeyBindingEg mainPanel = new KeyBindingEg();
JFrame frame = new JFrame("KeyBindingEg");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}