Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java robot.mouseMove(x, y) not producing correct results

I have recently been trying to automate a program I made and I have run into a problem, robot.mouseMove(100, 100) doesn't send the mouse to 100, 100.

I made this simple program to show this off:

new Robot().mouseMove(100, 100);
System.out.println(MouseInfo.getPointerInfo().getLocation().getX() + " , "
        + MouseInfo.getPointerInfo().getLocation().getY());

This code produces different results every time I run it:

54.0 , 54.0
0.0 , 0.0
58.0 , 58.0

When you put this in a loop the mouse approaches the correct position. Code :

Robot b = new Robot();  
for (int i = 1; i < 10; i++) {
        b.mouseMove(100, 100);
        System.out.println("Attempt "+i+" : "+MouseInfo.getPointerInfo().getLocation().getX() + " , "
                + MouseInfo.getPointerInfo().getLocation().getY());
    }

Results:

Attempt 1 : 12.0 , 21.0
Attempt 2 : 143.0 , 139.0
Attempt 3 : 79.0 , 81.0
Attempt 4 : 110.0 , 109.0
Attempt 5 : 96.0 , 96.0
Attempt 6 : 101.0 , 102.0
Attempt 7 : 100.0 , 99.0
Attempt 8 : 100.0 , 100.0
Attempt 9 : 100.0 , 100.0
Attempt 10 : 100.0 , 100.0

I don't understand what's going on but any help would be appreciated. Thanks. And just to clarify I am running Windows 10 and Java version 1.8.0_161. My ThinkPad E460 screen is 1920x1080 with 150% scale. Changing the scale does not affect the problem, however, it appears that lowering my screen resolution to the lowest possible (800x600) the mouse pointer is put a lot closer to the spot it is told. This may just be because there are fewer pixels and less room for error.

Results on 800x600 screen:

Attempt 1 : 101.0 , 101.0
Attempt 2 : 99.0 , 100.0
Attempt 3 : 101.0 , 99.0
Attempt 4 : 100.0 , 101.0
Attempt 5 : 99.0 , 99.0
Attempt 6 : 101.0 , 101.0
Attempt 7 : 100.0 , 99.0
Attempt 8 : 99.0 , 101.0
Attempt 9 : 101.0 , 99.0
Attempt 10 : 99.0 , 101.0

EDIT: Unfortunately creating a new robot each loop isn't the problem. I have updated the code (and the results just to be thorough).

EDIT 2: Just updated Java from 1.8.0_151 to 1.8.0_161, the same problem continues.

EDIT 3: I found some questions which might be linked to this problem here and here, they seem to be having a similar problem to me (their robot class isn't moving the mouse to where they want it).

like image 655
Tacodude7729 Avatar asked Feb 17 '18 03:02

Tacodude7729


People also ask

What is correct for robot class mouseMove?

mouseMove(int x, int y) : move the mouse to a specified location of screen. keyPress(int k) : presses a given key with a specified keycode. keyRelease(int k) : releases a given key with a specified keycode. mousePress(int b) : presses one or more mouse buttons.

How does Java robot work?

The primary purpose of Robot is to facilitate automated testing of Java platform implementations. Using the class to generate input events differs from posting events to the AWT event queue or AWT components in that the events are generated in the platform's native input queue.


2 Answers

The JDK Bug website says a current workaround is to call the function in a loop until the mouse moved to the right space. You could use a function like this:

public static void moveMouse(int x, int y, int maxTimes, Robot screenWin) {
    for(int count = 0;(MouseInfo.getPointerInfo().getLocation().getX() != x || 
            MouseInfo.getPointerInfo().getLocation().getY() != y) &&
            count < maxTimes; count++) {
        screenWin.mouseMove(x, y);
    }
}

Max times is there to stop an infinite loop in case something happens. Usually 4-5 times is good enough for me.

like image 141
DarkHorse Avatar answered Oct 14 '22 10:10

DarkHorse


Probably you do not need to point at exact pixel, and you may allow a bit difference. So, allow it and it will take much less tries. I have two 1080 monitors 100% scale and use a loop to check position with a limit of 100 tries. Some time it reaches the limit without right positioning, in my case. So I modified a loop to allow a difference in 3 points (I do not need really exact positioning) and now it moves mouse near the right spot in less than 10 attempts.

        for (int ntry = 0; ntry < moveTryMax; ntry++) {
            bot.mouseMove(paramVO.getX(), paramVO.getY());
            Point testPoint = MouseInfo.getPointerInfo().getLocation();

            if (Math.abs(testPoint.x - paramVO.getX()) <= pointsDeltaMax && Math.abs(testPoint.y - paramVO.getY()) <= pointsDeltaMax) {
                if (showMessages) {
                    System.out.println("N try: " + ntry);
                }
                break;
            }
        }
like image 43
CrazyBear Avatar answered Oct 14 '22 10:10

CrazyBear