8

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).

Tacodiva
  • 391
  • 2
  • 17
  • 3
    Wow, behavior confirmed, `1.8.0_151` this is certainly strange. `57, 111, 97, 100, 100, ...` – Matt Clark Feb 17 '18 at 04:05
  • 1
    Cannot confirm on Windows 10, `1.8.0_40`, always getting `100.0 , 100.0`. – Max Vollmer Feb 17 '18 at 04:10
  • 1
    `Windows 10`, `1.8.0_152`, still getting `100.0, 100.0` for 10000+ Attempts (It's actually 106383 Attempts), maybe bug in `1.8.0_151`? –  Feb 17 '18 at 04:39
  • 3
    [There is an open bug report against the JDK](https://bugs.openjdk.java.net/browse/JDK-8186063), the behavior mentioned in the ticket seems very similar; may be an issue with display scaling. – Matt Clark Feb 17 '18 at 07:30
  • Interesting. I still can't reproduce it. Tested it on `1920x1080` and `3440x1440` with `100%`, `125%`, `150%`, `175%`, `200%` and `225%` scaling. (The last 2 only on `3440x1440`, because they are not available on `1920x1080`.) In each case I got the correct `100.0 , 100.0` result. Still `Windows 10`, but I updated my Java to `1.8.0_161` yesterday. – Max Vollmer Feb 17 '18 at 11:12
  • @Matt Clark I would be interested to see your scaling/screen size as you appear to be the only one who can re-create this behavior (if your willing). – Tacodiva Feb 17 '18 at 21:19
  • Oddly, the one machine I tested, I was running 1080p @ 100% text scale, nothing out of the ordinary. (Touch screen?) – Matt Clark Feb 17 '18 at 21:22

2 Answers2

3

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.

DarkHorse
  • 963
  • 1
  • 10
  • 28
1

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;
            }
        }
CrazyBear
  • 11
  • 3