Java Swing:在按下键时执行某些操作

我使用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); } 

我通过使用Key Bindings而不是KeyListener获得了很好的成功,并在按下键时启动Swing Timer ,然后在Swing释放时停止Timer。 您可以使用KeyStroke.getKeyStroke(int keyCode, int modifiers, boolean onKeyRelease)方法将正确的KeyStroke对象传递到绑定组件的InputMap中来区分按键和释放: KeyStroke API 。 如果布尔参数为false,则输入将响应按键,如果参数为true,则反转。

一个快速而不雅的例子:

 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(); } }); } }