Java Swing:在按下键时执行某些操作 [英] Java Swing: Do something while the key is being pressed

查看:248
本文介绍了Java Swing:在按下键时执行某些操作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用 KeyAdpater 来获取事件和方法 addKeyListener 并且工作正常。问题是当按下键时,动作只发生一次,而不是按下时, 3-4秒后按住键,动作一直发生,这就是我想要的。

Im using a KeyAdpater to get the events and the method addKeyListener and works fine. The problem is that when a press the key, the action ocurrs only once and not while its being pressed, after 3-4 secs holding down the key the action occurs all the time which is what I want.

我想知道是否有好的方法可以一直按下按键从最开始的,没有按住3-4秒后。

I'd want to know if there is good way to do the action all the time the key is being pressed from the very begining, not after 3-4 seconds holding down.

我想到了下一个解决方案,但也许已经有了实现的方法:

I thought on the next solution, but maybe there is already an implemented way to do it:

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


推荐答案

我取得了很好的成功使用密钥绑定,而不是KeyListener,并启动它按下按下摇摆计时器,然后停止计时器摆动发布。您可以通过将正确的KeyStroke对象传递到绑定组件的 InputMap 使用 KeyStroke.getKeyStroke(int keyCode,int modifiers,boolean onKeyRelease)此处找到的方法: KeyStroke API 。如果布尔参数为假,则输入将响应按键,如果参数为真,则输入相反。

I've had good success with this by using Key Bindings, not a KeyListener, and start a Swing Timer on key press, and then stopping the Timer on Swing release. You can differentiate between the key press and release by passing the correct KeyStroke object into the bound component's InputMap using the KeyStroke.getKeyStroke(int keyCode, int modifiers, boolean onKeyRelease) method found here: KeyStroke API. If the boolean parameter is false, the input will respond to key press, and the converse if the parameter is true.

对于快速且不优雅的示例:

For a quick and inelegant example:

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

这篇关于Java Swing:在按下键时执行某些操作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆