【问题标题】:Java Swing: Do something while the key is being pressedJava Swing:在按键被按下时做一些事情
【发布时间】:2012-05-19 16:08:03
【问题描述】:

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

【问题讨论】:

    标签: java swing keyboard key-bindings onkeypress


    【解决方案1】:

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

    举个简单粗暴的例子:

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

    【讨论】:

    • @Pete 我从下往上尝试了这段代码,反之亦然,我在比较中找不到单词......,直到你的胡同,aaaach
    猜你喜欢
    • 1970-01-01
    • 2019-03-23
    • 1970-01-01
    • 2011-12-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-04
    相关资源
    最近更新 更多