Robot.mouseMove(1000,1000)将鼠标移动到屏幕上的随机位置......为什么?

问题描述 投票:0回答:3
public class MoveCursor extends Application {
    public static void main(String[] args) {
        launch(args);
    }
    @Override
    public void start(Stage stage) throws Exception {
        Button b = new Button("X");
        b.setOnAction((event) -> {
            try {
                new Robot().mouseMove(1000, 1000);
            } catch (AWTException ex) {
                Logger.getLogger(MoveCursor.class.getName()).log(Level.SEVERE, null, ex);
            }
        });
        stage.setScene(new Scene(b));
        stage.show();
    }
}
  1. 这应该将鼠标光标移动到我/你的屏幕上的1000x1000位置(即距我的屏幕的绝对0x0坐标1000px ...并且应该总是在同一位置结束)。 ......它不...它取决于按钮的位置。为什么?
  2. 是什么导致了这个?

...这曾经在旧笔记本电脑上工作。即windows 10,1 intel显卡,1 nvidia显卡,1920x1080显示屏。

我目前在SLI上使用Windows 10,2显卡,分辨率为3840x2160,分辨率为175%。

调整比例因子似乎没有做任何事情。

...我也在使用jdk8。

使用-Dsun.java2d.dpiaware = true或-Dsun.java2d.dpiaware = false vm选项似乎没有做任何事情。

[编辑] ...对于问题重复问题......这不是重复的问题。这个问题的解决方案毫无用处。

这不起作用!

 for(int count = 0;(MouseInfo.getPointerInfo().getLocation().getX() != x || 
        MouseInfo.getPointerInfo().getLocation().getY() != y) &&
        count < 100; count++) {
    new Robot().mouseMove(x, y);
  }
java javafx robot
3个回答
0
投票

是的,这是高分辨率屏幕的已知错误。有关详细信息,请参阅https://bugs.openjdk.java.net/browse/JDK-8186063

最好的解决方案是在循环中运行命令,直到它到达正确的坐标。

这样的事情的代码如下:

 for(int count = 0;(MouseInfo.getPointerInfo().getLocation().getX() != x || 
        MouseInfo.getPointerInfo().getLocation().getY() != y) &&
        count < 100; count++) {
    new Robot().mouseMove(x, y);
  }

请注意,此代码将最大迭代次数设置为100以防止无限循环,因此在循环之后立即执行另一次检查以确定它是否在正确的位置是值得的。


0
投票

次优,可怜的解决方案......但是它起作用......而且我在这个问题上浪费了太多时间而不是我应该拥有的。

import com.sun.jna.platform.win32.BaseTSD.ULONG_PTR;
import com.sun.jna.platform.win32.User32;
import com.sun.jna.platform.win32.WinDef.DWORD;
import com.sun.jna.platform.win32.WinDef.LONG;
import com.sun.jna.platform.win32.WinUser.INPUT;
import java.awt.MouseInfo;
import java.awt.Point;

public class Mouse {

    public static final int MOUSEEVENTF_MOVE = 1;

    public static void _winEvent_mi_move(int x, int y) {
        mouseAction(x, y, MOUSEEVENTF_MOVE);
    }

    public static void mouseAction(int x, int y, int flags) {
        INPUT input = new INPUT();
        input.type = new DWORD(INPUT.INPUT_MOUSE);
        input.input.setType("mi");
        if (x != -1) {
            input.input.mi.dx = new LONG(x);
        }
        if (y != -1) {
            input.input.mi.dy = new LONG(y);
        }
        input.input.mi.time = new DWORD(0);
        input.input.mi.dwExtraInfo = new ULONG_PTR(0);
        input.input.mi.dwFlags = new DWORD(flags);
        User32.INSTANCE.SendInput(new DWORD(1), new INPUT[]{input}, input.size());
    }

    public static void forceMove(int x, int y) {
        init_abs_move_0_0:
        {
            Point ip = MouseInfo.getPointerInfo().getLocation();
            _winEvent_mi_move(-ip.x, -ip.y);
        }
        moveX:
        {
            while (MouseInfo.getPointerInfo().getLocation().x < x - 1) {
                _winEvent_mi_move(1, 0);
            }
        }
        moveY:
        {
            while (MouseInfo.getPointerInfo().getLocation().y < y - 1) {
                _winEvent_mi_move(0, 1);
            }
        }
        System.out.println(MouseInfo.getPointerInfo().getLocation().toString());
    }

    public static void main(String[] args) {
        forceMove(1000, 1000);
        forceMove(2000, 1500);
    }

}

通过使用awt.Robot实例逐个像素地移动某些东西,可以获得相同的结果......这看起来效果更好。

是的...我确实尝试根据鼠标光标的当前位置和所有内容来计算指针目标的相对目标位置......但它仍然基于模糊地难以获取有关DPI缩放等的信息废话MS决定在WPI和GDI输入事件处理例程中实现。

...将其直接移动到0x0然后1000x1000使得它导致由(2000x1400)定义的光标位置...没有时间也没有耐心去弄清楚它。 ......解决方案有效。故事结局。


-1
投票

我写了一个“调整”功能,它做了肮脏的工作。注意:如果必须调整超过30 px,则终止。你可以打电话:

如果您遇到与我相同的错误,代码修复如下:

Adjust:638:598>507:537
Adjust:638:598>670:613
Adjust:638:598>630:595
Adjust:638:598>640:598
Move: 638 598 Click:true

moveAndClick(1000,1000,TRUE);

private void moveAndClick(int x, int y, boolean click) throws AWTException {

    robot.mouseMove(x, y);

    adjustMouse(x, y);

    if (click) {
        robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
        robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
    }
    System.out.println("Move: " + x + " " + y + " Click:" + click);

}

private void adjustMouse(int x, int y) {

    int realX = MouseInfo.getPointerInfo().getLocation().x;
    int realY = MouseInfo.getPointerInfo().getLocation().y;

    int aX = x;
    int aY = y;

    int count = 0;

    while (realX != x || realY != y) {
        System.out.println("Adjust:" + x + ":" + y + ">" + realX + ":" + realY + "");

        aX = realX > x ? aX-- : aX++;
        aY = realY > y ? aY-- : aY++;

        robot.mouseMove(x, y);
        try {  // you can remove this part 
            Thread.sleep(30);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        count++;

        realX = MouseInfo.getPointerInfo().getLocation().x;
        realY = MouseInfo.getPointerInfo().getLocation().y;
        if (count > 30) {  // you can remove or increase this part
            System.exit(0);
        }
    }


}

收益率:

@ system.start - mouse position : java.awt.Point[x=1540,y=1462]
Adjust:1000:1000>191:307
Adjust:1000:1000>2212:2039
Adjust:1000:1000>0:0
Adjust:1000:1000>2500:2159
Adjust:1000:1000>0:0
Adjust:1000:1000>2500:2159
Adjust:1000:1000>0:0
Adjust:1000:1000>2500:2159
Adjust:1000:1000>0:0
Adjust:1000:1000>2500:2159
Adjust:1000:1000>0:0
Adjust:1000:1000>2500:2159
Adjust:1000:1000>0:0
Adjust:1000:1000>2500:2159
Adjust:1000:1000>0:0
Adjust:1000:1000>2500:2159
Adjust:1000:1000>0:0
Adjust:1000:1000>2500:2159
Adjust:1000:1000>0:0
Adjust:1000:1000>2500:2159
Adjust:1000:1000>0:0
Adjust:1000:1000>2500:2159
Adjust:1000:1000>0:0
Adjust:1000:1000>2500:2159
Adjust:1000:1000>0:0
Adjust:1000:1000>2500:2159
Adjust:1000:1000>0:0
Adjust:1000:1000>2500:2159
Adjust:1000:1000>0:0
Adjust:1000:1000>2500:2159
Adjust:1000:1000>0:0
@ system.exit - mouse position : java.awt.Point[x=2500,y=2159]
© www.soinside.com 2019 - 2024. All rights reserved.