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();
}
}
这应该将鼠标光标移动到我/你的屏幕上的1000x1000位置(即距我屏幕的绝对0x0坐标1000px ...并且应该在总是相同的位置)。 ......它没有......这取决于按钮的位置。为什么呢?
造成这种情况的原因是什么?
...这曾经在旧笔记本电脑上工作。即windows 10,1 intel图形卡,1 nvidia显卡,1920x1080显示器。
目前我使用的是Windows 10,24显卡,分辨率为3840x2160,分辨率为175%。
调整缩放系数似乎无能为力。
...我也使用jdk8。
使用-Dsun.java2d.dpiaware = true或-Dsun.java2d.dpiaware = false vm选项似乎没有做任何事情。
[edit] ...对于问题重复问题......它不是重复的问题。这个问题的解决方案毫无用处。
这不起作用!
for(int count = 0;(MouseInfo.getPointerInfo().getLocation().getX() != x ||
MouseInfo.getPointerInfo().getLocation().getY() != y) &&
count < 100; count++) {
new Robot().mouseMove(x, y);
}
答案 0 :(得分: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以防止无限循环,因此在循环之后立即执行另一次检查以确定它是否在正确的位置是值得的。
答案 1 :(得分: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)定义的光标位置......没有时间也没有耐心去弄清楚它。 ......解决方案有效。故事的结尾。
答案 2 :(得分:-1)
我写了一个“调整”功能,它完成了肮脏的工作。 注意:如果必须调整超过30像素,则终止。 您可以致电:
如果您和我有相同的错误,则代码修复如下:
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]