Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Robot.mouseMove not moving to specified location properly

Whenever I run a mouseMove command for a robot, the mouse doesn't always go to the same location. For example, I have the following code:

import java.awt.Robot;
import java.util.concurrent.TimeUnit;

public class MainBot {
    public static void main(String[] args){
        try {
            Robot screenWin = new Robot();
            TimeUnit.SECONDS.sleep(2);
            screenWin.mouseMove(100, 300);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

The code usually makes the mouse end up at the X:

Mouse Location after running First, I hit run (I am using eclipse) and move my mouse to a location (before the 2 second timer is up). Then the 2 second delay finishes and the mouse moves and then the script ends. The problem is, the mouse never seems to go to the same exact place twice. For example, the mouse should go to (100, 300) but it goes to something that looks like (0, 300) most of the time. Other times, however, if I move the mouse at the beginning to where it should roughly be, then it goes to the right spot.

I am getting where the mouse should be using Paint to get the pixel location of a screenshot but I don't think it is that because the location keeps changing.

Is there anything I'm missing how the coordinates for mouseMove work?

Edit: Basically, I hit start with that program, then I move the mouse to a new position (so there is a different initial position before the mouseMove function) and then mouseMove executes. Each time I do this, the mouse goes to a different location.

like image 878
DarkHorse Avatar asked Feb 15 '18 03:02

DarkHorse


3 Answers

There's an open bug on OpenJDK, so this could be related:

https://bugs.openjdk.java.net/browse/JDK-8196030?jql=project%20in%20(JDK)%20AND%20component%20in%20(client-libs)%20AND%20Subcomponent%20in%20(java.awt)

The bug details that a problem may have been introduced in Windows 10 Fall Creators update, related to screen scaling and a mouse_move function.

In the meantime, you could try to set your screen scale to 100% instead of 125% and see if it helps.

like image 124
Syl Avatar answered Oct 19 '22 18:10

Syl


I found a solution, you just have to move the mouse to the coordinate (0,0) then you can move it to the place you want.

like image 36
martin eduardo mtz Avatar answered Oct 19 '22 19:10

martin eduardo mtz


I wrote a class to do proper cursor positioning. This works under windows 10 scalings too.

Use the MoveMouseControlled(double, double) function to move the cursor to a specified position. It uses a [0,1] coordinate system. The (0,0) Point is the upper left corner of the screen.

import java.awt.AWTException;
import java.awt.Dimension;
import java.awt.MouseInfo;
import java.awt.Point;
import java.awt.Robot;
import java.awt.Toolkit;

public class MouseCorrectRobot extends Robot
{
    final Dimension ScreenSize;// Primary Screen Size

    public MouseCorrectRobot() throws AWTException
    {
        super();
        ScreenSize = Toolkit.getDefaultToolkit().getScreenSize();
    }

    private static double getTav(Point a, Point b)
    {
        return Math.sqrt((double) ((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y)));
    }

    public void MoveMouseControlled(double xbe, double ybe)// Position of the cursor in [0,1] ranges. (0,0) is the upper left corner
    {

        int xbepix = (int) (ScreenSize.width * xbe);
        int ybepix = (int) (ScreenSize.height * ybe);

        int x = xbepix;
        int y = ybepix;

        Point mert = MouseInfo.getPointerInfo().getLocation();
        Point ElozoInitPont = new Point(0, 0);

        int UgyanAztMeri = 0;
        final int UgyanAZtMeriLimit = 30;

        int i = 0;
        final int LepesLimit = 20000;
        while ((mert.x != xbepix || mert.y != ybepix) && i < LepesLimit && UgyanAztMeri < UgyanAZtMeriLimit)
        {
            ++i;
            if (mert.x < xbepix)
                ++x;
            else
                --x;
            if (mert.y < ybepix)
                ++y;
            else
                --y;
            mouseMove(x, y);

            mert = MouseInfo.getPointerInfo().getLocation();

            if (getTav(ElozoInitPont, mert) < 5)
                ++UgyanAztMeri;
            else
            {
                UgyanAztMeri = 0;
                ElozoInitPont.x = mert.x;
                ElozoInitPont.y = mert.y;
            }

        }
    }

}
like image 1
Gats János Avatar answered Oct 19 '22 19:10

Gats János