0

I have been messing around with the Robot class recently, and wanted to try to remotely type a search in the search bar, but I can't seem to get the entire string to type out. Only the last letter ends up being typed in the search bar. The rest of the text ends up being printed in the terminal where I run the code.

I start by moving the mouse above the selection box.

I click the mouse twice (once to make safari the active window and once to activate the bar)

Then I let the type function type for me. It uses the keypress and keyrelease methods.

Does anybody know how to make the entire string type in the search bar?

Also I give credit to Sensei_Shoh on his stackoverflow post at Convert String to KeyEvents for his code from lines 38 to the end. Thanks.

import java.awt.*;
import java.awt.event.*;
import static java.awt.event.KeyEvent.*;
import java.util.*;
import java.awt.datatransfer.*; 
import static java.awt.AWTKeyStroke.getAWTKeyStroke;
import static java.awt.event.InputEvent.SHIFT_DOWN_MASK;

public class myBot
{
    public static Robot robot;
    public static void main(String[] args) throws AWTException
    {
        Scanner in = new Scanner(System.in);

        robot = new Robot();

        //Move to search bar
        robot.delay(500);
        robot.mouseMove(600,140);

        //Activate search bar
        robot.mousePress( InputEvent.BUTTON1_MASK );
        robot.mouseRelease( InputEvent.BUTTON1_MASK );
        robot.delay(100);
        robot.mousePress( InputEvent.BUTTON1_MASK );
        robot.mouseRelease( InputEvent.BUTTON1_MASK );
        robot.delay(1000);

        //Type in search bar;
        //YOUR STRING  \/
        String input = "ipad pro";
        for(int i=0; i<input.length(); i++)
        {
            type(input.substring(i, i+1));
        }
    }
    private static AWTKeyStroke getKeyStroke(char c) {
        String upper = "`~'\"!@#$%^&*()_+{}|:<>?";
        String lower = "`~'\"1234567890-=[]\\;,./";

        int index = upper.indexOf(c);
        if (index != -1) {
            int keyCode;
            boolean shift = false;
            switch (c) {
                case '~':
                    shift = true;
                case '`':
                    keyCode = KeyEvent.VK_BACK_QUOTE;
                    break;
                case '\"':
                    shift = true;
                case '\'':
                    keyCode = KeyEvent.VK_QUOTE;
                    break;
                default:
                    keyCode = (int) Character.toUpperCase(lower.charAt(index));
                    shift = true;
            }
            return getAWTKeyStroke(keyCode, shift ? SHIFT_DOWN_MASK : 0);
        }
        return getAWTKeyStroke((int) Character.toUpperCase(c), 0);
    }

    public static void type(CharSequence chars) {
        type(chars, 0);
    }

    public static void type(CharSequence chars, int ms) {
        ms = ms > 0 ? ms : 0;
        for (int i = 0, len = chars.length(); i < len; i++) {
            char c = chars.charAt(i);
            AWTKeyStroke keyStroke = getKeyStroke(c);
            int keyCode = keyStroke.getKeyCode();
            boolean shift = Character.isUpperCase(c) || keyStroke.getModifiers() == (SHIFT_DOWN_MASK + 1);
            if (shift) {
                robot.keyPress(KeyEvent.VK_SHIFT);
            }

            robot.keyPress(keyCode);
            robot.keyRelease(keyCode);

            if (shift) {
                robot.keyRelease(KeyEvent.VK_SHIFT);
            }
            if (ms > 0) {
                robot.delay(ms);
            }
        }
    }
}
Community
  • 1
  • 1
Henri
  • 145
  • 13
  • Consider setting [`Robot#setAutoDelay`](https://docs.oracle.com/javase/8/docs/api/java/awt/Robot.html#setAutoDelay-int-) to help insert a delay between the key pressed and key released events – MadProgrammer Apr 13 '17 at 00:37
  • I tried using robot.delay(100) between all the computations already, but that had no effect besides slowing the program down. – Henri Apr 13 '17 at 00:50
  • No, you didn't, not the way I suggested. `Robot` can, automatically, place a delay between EVERY event it triggers (that includes `mousePress` and `mouseRelease` and `keyPress` and `keyRelease`), not just between a batch of events as you are doing – MadProgrammer Apr 13 '17 at 00:54
  • Ok. I typed robot.setAutoDelay(1000) right after I initialize robot at the beginning of main. I got a different result, but still not the full result. I got the same "o" but this time, there was a space before it. Btw I really appreciate your help. :) – Henri Apr 13 '17 at 01:01

0 Answers0