GUI automation using a Robot

I would like to welcome guest writer Takeshi (Kesh) Ikuma. Kesh has posted several interesting utilities on the Matlab File Exchange, including the award-winning Enhanced Input Dialog Box. Today, Kesh will describe how we can automate GUI actions programmatically.

Automating GUI actions, including controlling a mouse and keyboard programmatically, is often useful. This can be used, for example, to demonstrate GUI usage or to perform a recorded macro.

Matlab’s Handle Graphics interface provides a simple way to manipulate the mouse cursor position, but not to emulate mouse or keyboard clicks. However, we can utilize Java’s java.awt.Robot class.

This article provides an overview of the Robot class and how it can be used to program mouse movement, button clicks and keyboard strikes.

java.awt.Robot class

The online Java documentation describes the purpose of the Robot class as follows:
This class is used to generate native system input events for the purposes of test automation, self-running demos, and other applications where control of the mouse and keyboard is needed.

This class has three main functionalities: mouse control, keyboard control, and screen capture. Here are some of the important member functions:

Mouse control functions

void mouseMove(int x, int y)

This function moves the cursor to the coordinate (x, y) which is defined with respect to the top-left screen corner (in contrast to Matlab’s coordinate origin at the bottom-left corner).

void mousePress(int buttons)
void mouseRelease(int buttons)

This pair of functions performs the button click. Their input argument is an OR’ed combination of java.awt.event.InputEvents:

java.awt.event.InputEvent.BUTTON1_MASK   // left mouse button 
java.awt.event.InputEvent.BUTTON2_MASK   // middle mouse button
java.awt.event.InputEvent.BUTTON3_MASK   // right mouse button

Keyboard control functions

Keyboard action is emulated by the following pair of functions. Their keycodes are defined in java.awt.event.KeyEvent:

void keyPress(int keycode)
void keyRelease(int keycode)

NOTE: Although java.awt.event.KeyEvent constants defines most of the US QWERTY keys, not all can actually be used with java.awt.Robot. Specifically, it appears that only the KeyEvent constants for unmodified keys can be used. See the following section for an example.

Utility functions

The robot can be put to sleep for a desired duration (in milliseconds). Also, the calling routine can be blocked until the robot exhausts its command queue.

void delay(int ms)
void waitForIdle()

Readers interested in Robot’s screen-capture capability are invited to take a look at Yair’s ScreenCapture utility on the File Exchange.

Using java.awt.Robot in Matlab

To create the Robot object in Matlab, simply run

robot = java.awt.Robot;

Moving the mouse cursor

With Matlab’s root (0) handle, the mouse cursor can be repositioned by

set(0,'PointerLocation',[x y]);

The mouse cursor is placed on the x-th pixel from left edge and the y-th pixel from the bottom edge of the screen.

Alternately, we could use the semi-documented moveptr function, which was described here last year.

The same operation can also be done using Robot as follows:

scrSize = get(0,'ScreenSize');
robot.mouseMove(x,scrSize(2)-y);

The extra step must be taken to convert from Matlab to Java screen coordinates.

Depending on the specific case (for example, whether or not we know the absolute or only relative screen coordinates), we may prefer using any of these equivalent mouse-movement alternatives.

Clicking mouse buttons

Unfortunately, we have few alternatives for automating mouse-clicks – Robot is basically our only option. Matlab recognizes 4 different mouse click types as specified in the Figure’s SelectionType property:

  • Normal: Click left mouse button
  • Extend: SHIFT-click left mouse button
  • Alternate: CTRL-click left mouse button
  • Open: Double click left mouse button

To observe the mouse click, open a figure and set its WindowButtonDownFcn callback:

myCallback = @(hObj,event) disp(get(hObj,'SelectionType'));
set(gcf,'WindowButtonDownFcn', myCallback);

To trigger the callback, the figure must have the focus and the mouse cursor must be on the figure. To ensure the callback invocation, “figure(gcf); drawnow;” commands are included in the code examples below. Make sure to place the mouse cursor on the figure before running these codes.

Here’s how the Robot can be used to perform each type of clicking. First, normal click:

figure(gcf); drawnow;
robot.mousePress  (java.awt.event.InputEvent.BUTTON1_MASK);
robot.mouseRelease(java.awt.event.InputEvent.BUTTON1_MASK);

For “open” or double click, repeat it twice:

figure(gcf); drawnow;
robot.mousePress  (java.awt.event.InputEvent.BUTTON1_MASK);
robot.mouseRelease(java.awt.event.InputEvent.BUTTON1_MASK);
robot.mousePress  (java.awt.event.InputEvent.BUTTON1_MASK);
robot.mouseRelease(java.awt.event.InputEvent.BUTTON1_MASK);

For the other two click types, we need to use the keyboard functions. First, “extend” or SHIFT-click:

figure(gcf); drawnow;
robot.keyPress    (java.awt.event.KeyEvent.VK_SHIFT);
robot.mousePress  (java.awt.event.InputEvent.BUTTON1_MASK);
robot.mouseRelease(java.awt.event.InputEvent.BUTTON1_MASK);
robot.keyRelease  (java.awt.event.KeyEvent.VK_SHIFT);

Lastly, “alternate” or CTRL-click:

figure(gcf); drawnow;
robot.keyPress    (java.awt.event.KeyEvent.VK_CONTROL);
robot.mousePress  (java.awt.event.InputEvent.BUTTON1_MASK);
robot.mouseRelease(java.awt.event.InputEvent.BUTTON1_MASK);
robot.keyRelease  (java.awt.event.KeyEvent.VK_CONTROL);

Clicking keyboard keys

Just as we have shown above how to press a modifier key (Ctrl or Alt key) to set the figure’s SelectionType property, keyPress and keyRelease functions can be used with character keys to type text. For example, with the focus on Matlab’s Command Prompt, running the following code executes the ver command:

robot.keyPress    (java.awt.event.KeyEvent.VK_V);
robot.keyRelease  (java.awt.event.KeyEvent.VK_V);
robot.keyPress    (java.awt.event.KeyEvent.VK_E);
robot.keyRelease  (java.awt.event.KeyEvent.VK_E);
robot.keyPress    (java.awt.event.KeyEvent.VK_R);
robot.keyRelease  (java.awt.event.KeyEvent.VK_R);
robot.keyPress    (java.awt.event.KeyEvent.VK_ENTER);
robot.keyRelease  (java.awt.event.KeyEvent.VK_ENTER);

In the previous section, I mentioned that not all KeyEvent constants are supported by java.awt.Robot, and keys must be defined with their unmodified characters. For example, a semicolon (‘;’) can be typed by:

robot.keyPress    (java.awt.event.KeyEvent.VK_SEMICOLON);
robot.keyRelease  (java.awt.event.KeyEvent.VK_SEMICOLON);

However, doing the same for a colon (‘:’ or SHIFT-’;') causes an error:

robot.keyPress    (java.awt.event.KeyEvent.VK_COLON);
robot.keyRelease  (java.awt.event.KeyEvent.VK_COLON);
??? Java exception occurred:
java.lang.IllegalArgumentException: Invalid key code
    at sun.awt.windows.WRobotPeer.keyPress(Native Method)
    at java.awt.Robot.keyPress(Unknown Source)

Instead of using the VK_COLON constant, VK_SEMICOLON constant must be used while SHIFT modifier key is pressed:

robot.keyPress    (java.awt.event.KeyEvent.VK_SHIFT);
robot.keyPress    (java.awt.event.KeyEvent.VK_SEMICOLON);
robot.keyRelease  (java.awt.event.KeyEvent.VK_SEMICOLON);
robot.keyRelease  (java.awt.event.KeyEvent.VK_SHIFT);

Although unconfirmed, I suspect VK_SEMICOLON constant would not work with keyboards in which semicolon is mapped to SHIFT-’,’ (e.g., Spanish or Italian keyboard layouts), while the VK_COLON constant would work with a French keyboard.

Putting it all together: jMouseEmu and inputEmu

To simplify the execution of the mouse and keyboard actions outlined above, I (Kesh Ikuma) have created the jMouseEmu and inputEmu utilities, which are available on the Matlab File Exchange. These interface/wrapper functions will be described in next week’s article.

Do you have any favorite use for Java Robots in your workflow? If so, please tell us all about it in a comment below.

Related posts:

  1. GUI automation utilities This article explains a couple of Matlab utilities that use Java's Robot class to programmatically control mouse and keyboard actions...
  2. ScreenCapture utility The ScreenCapture utility uses purely-documented Matlab for capturing a screen region as an image from within Matlab. ...
  3. Uicontrol callbacks This post details undocumented callbacks exposed by the underlying Java object of Matlab uicontrols, that can be used to modify the control's behavior in a multitude of different events...
  4. Detecting window focus events Matlab does not have any documented method to detect window focus events (gain/loss). This article describes an undocumented way to detect such events....
  5. Matlab-Java interface using a static control The switchyard function design pattern can be very useful when setting Matlab callbacks to Java GUI controls. This article explains why and how....
  6. Inactive Control Tooltips & Event Chaining Inactive Matlab uicontrols cannot normally display their tooltips. This article shows how to do this with a combination of undocumented Matlab and Java hacks....

Categories: Figure window, Guest bloggers, GUI, Java, Low risk of breaking in future versions

Tags: , ,

Bookmark and SharePrint Print

21 Responses to GUI automation using a Robot

  1. Martin Richard says:

    Very interesting. I used this java.awt.Robot class recently to perform GUI testing in MATLAB and, with little effort, it became a very interesting and simple feature to use.
    Thanks for posting

  2. Sabrina Wendt says:

    Response to:
    “Although unconfirmed, I suspect VK_SEMICOLON constant would not work with keyboards in which semicolon is mapped to SHIFT-’,’ ”

    I can confirm that this is true (writting from a danish laptop). At my computer ‘;’ is mapped to ‘,’ and so to generate a semicolon it works to write the following in MATLAB:

    robot.keyPress (java.awt.event.KeyEvent.VK_SHIFT);
    robot.keyPress (java.awt.event.KeyEvent.VK_COMMA);
    robot.keyRelease (java.awt.event.KeyEvent.VK_COMMA);
    robot.keyRelease (java.awt.event.KeyEvent.VK_SHIFT);

    Great article! Thanks for posting :-)

  3. Héctor says:

    I try this example some time ago from another source. Now I´m reading all your posts to learn new things (great job). When I reach newer posts I will ask you some things I want to do and don´t know how.

  4. Ankit says:

    Hi,
    Just like you have given the commands for keyboard and mouse interface is there any command for joystick interface in java. Please help.

  5. appy says:

    Hi this is very interesting i used it in matlab figure instead of overobj but i have problem i used mouse press
    and mouse release in windowmotionFcn in mat lab i.e when i move the mouse at that point mouse button will be pressed programmatically if i move mouse over the toolbar it is pressing the button automatically zoom save are working even to resize or close window will be activated if i just move the mouse over them but i donot want this to happen how to stop.

    Thank you.

  6. timmy says:

    Has anyone experienced double clicking using Press/Release/Press/Release not working? Say for opening an image icon on desktop. The icon is correctly selected but the correct double-clicking results (application opening) is not performed. Everything else works, even dragging icons around, just not opening icons via double click. Thanks for the help.

  7. Pingback: ScreenCapture utility | Undocumented Matlab

  8. MEENAKSHI.S says:

    I want to use the executable file in Matlab for optimisation methods. How can I use the run button of that exe file in matlab command window as a command and not by clicking the run button of exe file so that repeated process of clicking can be avoid in optimisation methods (exe file is visual c++ program-MFC Application).

    • @Meenakshi – you would need to write an automation script for this, either using the Java Robot class (as described in the article), or using an external application (e.g., AutoIt) that you would call from Matlab using the system command. If you would like my help writing such an application for you as a consultant, please send me an email (altmany at gmail).

  9. MEENAKSHI.S says:

    thank you sir…i have tried Java Robot class in matlab…it works well..i.e.to press F1 KEY of matlab suddenly help window opened…so really happy to see the response without clicking F1 KEY…it works well…but i want to press F5 KEY of EXECUTABLE FILE IN MATLAB COMMAND WINDOW…What can i do sir.. PLEASE SHARE YOUR IDEAS…Thank you Sir…

  10. George says:

    thanks a lot for your post,and i have a question

    i want to type 1 to 3 with matlab
    of course i can write

    import java.awt.Robot;
    import java.awt.event.*;
    robot=Robot();
    robot.keyPress(KeyEvent.VK_1);
    robot.keyRelease(KeyEvent.VK_1);
    robot.keyPress(KeyEvent.VK_2);
    robot.keyRelease(KeyEvent.VK_2);
    robot.keyPress(KeyEvent.VK_3);
    robot.keyRelease(KeyEvent.VK_3);

    i wanna ask how to do these with while or for loop

    thank you

    • Yair Altman says:

      @George – in your specific case you can simply use the numeric equivalents of KeyEvent.VK_*: VK_0=48, VK_1=49 and so on until VK_9=57. You can see the full list using my checkClass utility. Turning these numbers into a loop is trivial. Note that using numbers is far less maintainable than using the enumerations, so add ample documentation to your code.

  11. Muthu Vicky says:

    Thanks a lot for this post.. This is really awesome!!

    Can you please tell me how to press function keys (i.e.) f6 or f7 or some other function key?

  12. hema says:

    how to right click on a window??

    • @hema -

      jRobot = java.awt.Robot;
      jRobot.mouseMove(400,300); % move to absolute x,y pixel position
      jEvent = java.awt.event.InputEvent.BUTTON3_MASK;
      jRobot.mousePress(jEvent); jRobot.mouseRelease(jEvent);  %=right-click
  13. puja says:

    i am working on dynamic typing project.i want to capture the time when key is pressed and released.can anyone please help me

Leave a Reply

Your email address will not be published. Required fields are marked *

*

<pre lang="matlab">
a = magic(3);
sum(a)
</pre>