Search code examples
javaawtdelaykeypressawtrobot

Delaying keyPress


I've been searching around ways of being able to have a small delay between keypresses. I've been making this program that reads global hotkeys using the JIntellitype library, and then fires whichever sequence of keypresses you assigned, such as pressing numpad1 will do a sequence of A B C. My issue is, that if I use Thread.sleep it just delays for X amount of time and then keypresses all the assigned keys without any delay in between any of the keypresses. Does anyone have a suggestion on how to fix this problem ?

This is what I'm using to send keypresses with the Robot class

public void onHotKey(int identifier) {
    try {
        Robot bot = new Robot();
        if (output.elementAt(identifier - 1).length() == 1) {
            ch = output.elementAt(identifier - 1).charAt(0);
            bot.keyPress(ch);
        } else {
            int cmdSize = output.elementAt(identifier - 1).length();
            for (int c = 0; c < cmdSize; c++) {
                bot.keyPress((int) output.elementAt(identifier - 1).charAt(c));
                try {
                    Thread.sleep(50);
                } catch (InterruptedException ex) {
                    Logger.getLogger(NewJFrame.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        }
    } catch (AWTException ex) {
        Logger.getLogger(NewJFrame.class.getName()).log(Level.SEVERE, null, ex);
    }
}

Solution

  • These are some possible problems you might have (I also added a "full" example below to do it):

    1. You are only pressing keys, you need to release the key too:

      robot.keyPress(c);
      robot.keyRelease(c);
      
    2. You could be running the robot in the EDT. Use another thread to handle the key-presses...

    3. Use the "built-in" auto delay feature that the Robot class already provides:

      Robot robot = new Robot();
      robot.setAutoDelay(50); // ms
      ...
      

    Example:

    This is an example how you could implement this, every time you press 0, it will print "hello" delaying each typed character using the auto-delay:

    public static void main(String[] args) throws Exception {
    
        final BlockingQueue<Integer> queue = new ArrayBlockingQueue<Integer>(20);
    
        JTextArea area = new JTextArea(10, 40) {{
            addKeyListener(new KeyAdapter() {
                @Override public void keyPressed(KeyEvent e) {
                    if (e.getKeyCode() == KeyEvent.VK_0) {
                        queue.offer(KeyEvent.VK_H);
                        queue.offer(KeyEvent.VK_E);
                        queue.offer(KeyEvent.VK_L);
                        queue.offer(KeyEvent.VK_L);
                        queue.offer(KeyEvent.VK_O);
                    }
                }
            });
        }};
    
        JFrame frame = new JFrame("Test");
        frame.add(area);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setVisible(true);
    
        Robot robot = new Robot();
        robot.setAutoDelay(50);
    
        while (true) {
            final int c = queue.take();
            robot.keyPress(c);
            robot.keyRelease(c);
        }
    }