Робот AWT не может перетаскивать окно

Я пытаюсь переместить окно проводника Windows с помощью робота AWT. Робот работает на 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);

Мышь начинается в правильном месте и перемещается в правильное место назначения, но, похоже, не нажимает кнопку.


person Nathaniel Waisbrot    schedule 09.05.2013    source источник


Ответы (4)


В сикули используйте 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);
person kalharbi    schedule 11.06.2013

У меня была похожая проблема. Попробуйте добавить Thread.sleep(100); (или более 100) между каждой операцией робота.

person Andrzej Kasp    schedule 04.07.2013

У меня была точно такая же проблема. Даже попробовал то, что сказал @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) после каждого шага, вместо этого вам нужно добавить thread.sleep(100) только между шагами 2 и 3. Я протестировал эти коды, и они работали. Коды, как показано ниже:

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

Дайте мне знать, если у вас есть дополнительные вопросы.

person Ivan Ouyang    schedule 12.07.2017
comment
Я обнаружил, что это зависит от небольших корректировок; например, я начал с ваших последних четырех шагов, но для того, чтобы его можно было распознать как жест dnd, мне пришлось добавить еще одно крошечное промежуточное движение. Тем не менее, пока мне не удалось, чтобы после mouseRelease DnD действительно была завершена. (в моем случае DnD был объектом в графическом интерфейсе, а не окном) - person 0__; 04.01.2020

Почему у вас не получилось с Сикули? Что было проблемой? Я попробовал это сам, и это сработало. Моя среда: 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)
person Marcin Kowalczyk    schedule 16.05.2013
comment
Я использую Sikuli-API, библиотеку Java, а не Sikuli, оболочку/библиотеку Jython. Проблема, как я сказал в своем вопросе, заключается в том, что мышь начинается в правильном месте и перемещается в правильное место назначения, но, похоже, не нажимает кнопку. - person Nathaniel Waisbrot; 16.05.2013
comment
@ Натаниэль Вайсброт: Понятно. Мы работаем в разных средах сикули, поэтому поведение тоже разное. - person Marcin Kowalczyk; 16.05.2013