Search code examples
javamacoskeypressshiftawtrobot

Java robot keypress "shift" on Mac?


I'm creating a automated typer using the built in Java robot class. I'm also building it on Mac and I've come across a fundamental flaw that is stumping me. No matter what,

the "shift" key does not register.

I've tried typerBot.keyPress(KeyEvent.VK_SHIFT); and a few key codes including typerBot.keyPress(60);

Ive looked all over the net and I can't find anything.

Here is a small sample program that replicates the problem I'm having on my machine:

import java.awt.AWTException;
import java.awt.Robot;
import java.awt.event.KeyEvent;

public class RobotClass {

public static void main(String[] args) throws InterruptedException {

        try {   //Gives you 5 seconds to click into a suitable environment for the robot to type
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        String text = "AAAAAAAAAA";
        for(char c : text.toCharArray()) {
            RobotClass.typeChar(c);
            Thread.sleep(200);
        }

    }

    public static void typeChar(char c) {

        try {
            Robot typerBot = new Robot();
            switch(c) {
            case 'A':
                typerBot.keyPress(KeyEvent.VK_SHIFT);
                typerBot.keyPress(KeyEvent.VK_A);
                typerBot.keyRelease(KeyEvent.VK_A);
                typerBot.keyRelease(KeyEvent.VK_SHIFT);
                break;
            }
        } catch (AWTException e) {  e.printStackTrace();    }

    }

}

Input: AAAAAAAAAA

Output: aaaaaaaaaa

My Question: Why is the shift key not being recognized on mac?


Solution

  • You have to be thoughtful in how you apply key strokes, remember, you are "simulating" a physical user.

    This means, in order to be able to type A, you need to press SHIFTA then release ASHIFT (or at least release SHIFT when you're done)

    The following is a really basic test that demonstrates the overall concept. Open a text editor, run the program, you will have 5 seconds to get the editor into keyboard focus

    Robot bot = new Robot();
    bot.setAutoDelay(10);
    Thread.sleep(5000);
    Map<Character, Integer> mapStrokes = new HashMap<>();
    mapStrokes.put('t', KeyEvent.VK_T);
    mapStrokes.put('h', KeyEvent.VK_H);
    mapStrokes.put('i', KeyEvent.VK_I);
    mapStrokes.put('s', KeyEvent.VK_S);
    mapStrokes.put(' ', KeyEvent.VK_SPACE);
    mapStrokes.put('e', KeyEvent.VK_E);
    mapStrokes.put('a', KeyEvent.VK_A);
    String text = "This is A test";
    for (char value : text.toCharArray()) {
        if (Character.isUpperCase(value)) {
            bot.keyPress(KeyEvent.VK_SHIFT);
        }
        int keyStroke = mapStrokes.get(Character.toLowerCase(value));
        System.out.println("Type " + value);
        bot.keyPress(keyStroke);
        bot.keyRelease(keyStroke);
        if (Character.isUpperCase(value)) {
            bot.keyRelease(KeyEvent.VK_SHIFT);
        }
    }