Java KeyListener是延迟注册

时间:2012-08-24 02:55:51

标签: java swing timer delay keylistener

正如大多数人现在用密钥监听器实现的那样,在keyPressed方法中,java注册一次按键,然后暂停大约半秒钟,然后按下密钥记录稳定的流。 我的问题是,我希望java在按下一个键后立即注册一个稳定的流keyDown事件。 我已经阅读过很多关于这个问题的文章,其中很多都谈到了摇摆计时器,其中我也处于黑暗中。 为了使下面的代码更好更容易看,我只是修剪掉了胖子并把关键的监听器放到了一个单独的类中! 对此的任何意见将不胜感激!

public class Keyer implements KeyListener
{

    Keyer(){}
    @Override
    public void keyPressed(KeyEvent ovent)
    {
        int keyCode = ovent.getKeyCode();
        System.out.println("You pressed: "+keyCode);
    }
    @Override
    public void keyReleased(KeyEvent ovent)
    {

    }
    @Override
    public void keyTyped(KeyEvent ovent)
    {

    }
}

2 个答案:

答案 0 :(得分:6)

我认为这不是Java问题,而是操作系统问题 - 操作系统在发送一键击键之前在一段时间内发送键击延迟。解决方案是在按键时启动Swing Timer。我还建议您使用Key Bindings而不是KeyListener。

另外你说你在摇摆计时器“黑暗中”,如果是这样,我敦促你做我们其他人在这种情况下所做的事情:查看相关教程。 Google会帮助您快速找到它。此外,搜索此站点将帮助您查找使用Swing Timer进行键绑定的示例,例如,看看here

修改
KeyListener是一个低级构造,通常您更喜欢使用更高级别的构造,因为它们更安全,更容易使用而不会产生副作用或出现问题。例如,如果使用KeyListener,则很容易遇到焦点问题,因为只有在侦听的组件具有焦点时它才有效。如果您使用键绑定,则很容易避免这种情况。

答案 1 :(得分:6)

如果按下的按键是更新GUI的触发器,那就是当你需要使用SwingTimers时。如果它没有触发对GUI的更新,则可以使用普通线程。

我认为文章所指的是

  1. 使用KeyListener
  2. 保存按下的键
  3. 使用Swing Timer检查按给定间隔(例如每100ms)按下哪些键
  4. 以下是您如何将其纳入KeyListener

    的示例
        public class Keyer implements KeyListener{
    
            /** Stores currently pressed keys */
            HashSet<Integer> pressedKeys = new HashSet<Integer>();
    
            public Keyer(){
    
                //Check every 100ms if there's keys pressed
                //(This is the Swing Timer they talk about)
                new Timer(100, new ActionListener(){
                    @Override
                    public void actionPerformed(ActionEvent arg0) {
                        String keysString = "";
                        if(!pressedKeys.isEmpty()){
                            Iterator<Integer> i = pressedKeys.iterator();
                            while(i.hasNext()){
                                keysString += i.next() + ",";
                            }
                        } 
                        System.out.println(keysString);
                    }
                }).start();
            }
    
            @Override
            public void keyPressed(KeyEvent ovent){
                //Add key to hashSet when pressed
                int keyCode = ovent.getKeyCode();
                pressedKeys.add(keyCode);
            }
            @Override
            public void keyReleased(KeyEvent ovent){
                //Remove key from hashset when released
                int keyCode = ovent.getKeyCode();
                pressedKeys.remove(keyCode);
            }
            @Override
            public void keyTyped(KeyEvent ovent){}
        }
    

    这是一个将所有内容放在一起的示例 - 更新标签,告诉您确切按下了哪些键(按键码)。

    import java.awt.*;
    import java.awt.event.*;
    import java.util.*;
    import javax.swing.*;
    import javax.swing.Timer;
    
    public class TempProject extends JPanel{
        /** Label to update with currently pressed keys */
        JLabel output = new JLabel();
    
        public TempProject(){
            super();
            setFocusable(true);
            add(output, BorderLayout.CENTER);
            requestFocus();
            addKeyListener(new Keyer());
        }
    
        public static void main(String args[])
        {
            EventQueue.invokeLater(new Runnable()
            {
                public void run()
                {
                    JFrame frame = new JFrame();
                    frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
                    frame.setContentPane(new TempProject());    
                    frame.pack();
                    frame.setVisible(true);
                    new TempProject();
                }
            });
        }
    
        public class Keyer implements KeyListener{
    
            /** Stores currently pressed keys */
            HashSet<Integer> pressedKeys = new HashSet<Integer>();
    
            public Keyer(){
    
                //Check every 100ms if there's keys pressed
                //(This is the Swing Timer they talk about)
                new Timer(100, new ActionListener(){
                    @Override
                    public void actionPerformed(ActionEvent arg0) {
                        String keysString = "";
                        if(!pressedKeys.isEmpty()){
                            Iterator<Integer> i = pressedKeys.iterator();
                            while(i.hasNext()){
                                keysString += i.next() + ",";
                            }
                        } 
                        output.setText(keysString);
                    }
                }).start();
            }
    
            @Override
            public void keyPressed(KeyEvent ovent){
                //Add key to hashSet when pressed
                int keyCode = ovent.getKeyCode();
                pressedKeys.add(keyCode);
            }
            @Override
            public void keyReleased(KeyEvent ovent){
                //Remove key from hashset when released
                int keyCode = ovent.getKeyCode();
                pressedKeys.remove(keyCode);
            }
            @Override
            public void keyTyped(KeyEvent ovent){}
        }
    
    
    
    }
    

    修改

    另外,请参阅@HovercraftFullOfEels发布的关于KeyListener的警告。根据您要完成的任务,您可能需要考虑使用Key Bindings(与此帖适用的原理相同)。如果你想看一下,这里有一个关于键绑定的有用的tutorial