AWT机器人无法拖动窗口。

4

我正在尝试使用AWT机器人移动Windows资源管理器窗口。这个机器人是在Java 7下运行的,操作系统是Windows 7。

我可以移动鼠标并单击某些内容,但是在尝试点击和拖动时,似乎没有按下按钮。我无法确定发生了什么问题,也不知道如何找出发生了什么。

我最初使用Sikuli:

mouse.mouseDown(InputEvent.BUTTON1_MASK);
mouse.drop(targetLocation);

当那种方法不起作用时,我尝试了一种更低层次的实现,直接与机器人合作:
Robot robot = new Robot();
robot.mousePress(InputEvent.BUTTON1_MASK);
robot.mouseMove(targetLocation.getX(), targetLocation.getY());
robot.mouseRelease(InputEvent.BUTTON1_MASK);

鼠标位置正确,并移动到正确的目标位置,但似乎无法按下按钮。

4个回答

4

在Sikuli中,使用mouse.drag()然后使用mouse.drop()。

示例:

ScreenRegion fullScreenRegion=new ScreenRegion();
ImageTarget dragImageTarget=new ImageTarget("dragTargetFile");
ScreenRegion dragTargetRegion=fullScreenRegion.find(dragImageTarget);
ImageTarget dropImageTarget=new ImageTarget("dropTargetFile");
ScreenRegion dropTargetRegion=fullScreenRegion.find(dropImageTarget);

Mouse mouse = new DesktopMouse();
mouse.drag(dragTargetRegion.getCenter());
mouse.drop(dropTargetRegion.getCenter());

对于Java Robot API: 你应该按照这个顺序调用mouseMove()、 mousePress()、 mouseMove()和mouseRelease()。 例如:

Robot robot=new Robot();
// drag
robot.mouseMove(x1, y1);
robot.mousePress(InputEvent.BUTTON1_MASK);
// drop
robot.mouseMove(x2, y2);
robot.mouseRelease(InputEvent.BUTTON1_MASK);

2

我曾经也遇到过完全相同的问题。甚至尝试了@Andrzej Kasp所说的,添加线程睡眠一段时间。但是它不起作用,直到我根据@Andrzej Kasp的评论进行了一些修改。感谢Andrzej Kasp。

整个原因是因为线程是按顺序执行的。我试图在每个操作之间添加thread.sleep(100);但不起作用。代码如下:

robot.mouseMove(x1,y1);                      //step 1
thread.sleep(100);
robot.mousePress(InputEvent.BUTTON1_MASK);   //step 2
thread.sleep(100);
robot.mouseMove(x2, y2);                     //step 3
thread.sleep(100);
robot.mouseRelease(InputEvent.BUTTON1_MASK); //step 4

对我来说它不起作用,但可能对你有效,这取决于电脑。整个理论背后的基本原则是:如果您想确保它有效,必须在光标移动时按下鼠标。也就是说,步骤2和步骤3必须同时执行。在正常情况下,计算机在运行此程序时不会创建新线程,除非您使用thread.sleep(),它将暂停当前线程,处理器时间将分配给其他线程。因此,您不必在每个步骤之后添加thread.sleep(100),而只需要在步骤2和步骤3之间添加thread.sleep(100)。我已经测试过这些代码,并且它们有效。代码如下:

robot.mouseMove(x1,y1);                      //step 1
robot.mousePress(InputEvent.BUTTON1_MASK);   //step 2
thread.sleep(100);
robot.mouseMove(x2, y2);                     //step 3
robot.mouseRelease(InputEvent.BUTTON1_MASK); //step 4

如果您有更多问题,请让我知道。


1
我发现它依赖于小的调整;例如,我开始使用你的最后四个步骤,但为了使它被识别为DnD手势,我必须添加一个额外的微小的中间动作。然而,到目前为止,我还没有成功地让mouseRelease之后DnD实际完成。(在我的情况下,DnD是跨GUI的对象,而不是窗口) - 0__

1
我遇到了类似的问题。尝试在每个机器人操作之间添加Thread.sleep(100);(或更多)来解决问题。

0
为什么你在使用Sikuli时遇到了问题?具体是什么问题呢? 我自己试过,它可以正常工作。我的环境是:Win7系统,窗口透明度已禁用,使用的是Sikuli r930版本。为了简化测试,一些窗口在开始测试前已经打开。以下是我的可行示例:
winExpl_topRightCornerImg = Pattern("1368690528515.png").targetOffset(-2,-13) 
"""winExpl_topRightCornerImg is a part of a window containing top bar.
I captured huge rectangle containing navigation arrows and I changed target offset,
so that Sikuli clicks only on a bar"""
anyRectangleAtDesktop = "1368690615156.png" #any particular part of a desktop
drag(winExpl_topRightCornerImg)
dropAt(anyRectangleAtDesktop)

我正在使用Sikuli-API,这是Java库,而不是Sikuli Jython包装器/库。正如我在问题中所说的那样,问题是“鼠标从正确的位置开始移动到正确的目的地,但似乎没有按下按钮。” - Nathaniel Waisbrot
@ Nathaniel Waisbrot:我明白了。我们在不同的Sikuli环境中工作,所以行为也不同。 - Marcin Kowalczyk

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接