Robot.mouseMove вообще не работает в Mac OS X

Я создал файл java в IntelliJ IDE с этим кодом

import java.awt.AWTException;
import java.awt.MouseInfo;
import java.awt.Robot;

public class JavaRobotExample {
    public static void main(String[] args) {
        int x = 12,
                y = 300;
        try {
            Robot robot = new Robot();
            robot.mouseMove(x, y);

            int xAct = (int)    MouseInfo.getPointerInfo().getLocation().getX(),
                    yAct = (int) MouseInfo.getPointerInfo().getLocation().getY();

            String sPred = String.format("Predicted mouse location : %, d, %, d", x, y),
                    sAct = String.format("Actual mouse location : %, d, %, d", xAct, yAct);

            System.out.println(sPred);
            System.out.println(sAct);
        } catch (AWTException e) {
            e.printStackTrace();
        }
    }
}

Этот пример отлично работает в среде Windows 7, но тот же код в Mac OS 10.14 не перемещает мышь с помощью метода mouseMove (но считывает позицию с помощью класса MouseInfo).

Также я не получаю никаких исключений, например.

У кого-то раньше была подобная проблема? Есть идеи, как заставить этот код работать в Mac OS?

С уважением,

Вам нужно будет более конкретно сказать «это не работает». Что говорит консоль, когда вы ее запускаете? / Что она должна сказать? Также более важно, как вы его запускаете?

scigs 01.11.2018 16:13

Привет, поэтому в консоли я получаю только эти две строки (пример с Mac): «Прогнозируемое местоположение мыши: 12, 300» и «Фактическое местоположение мыши: 730, 428» - что правильно, потому что вторая строка показывает положение мыши (потому что мышь почему-то не меняет положение). В Windows 7 я могу видеть одни и те же значения в обеих строках (поскольку прогнозируемое положение мыши равно фактическому положению после перемещения мыши). Мне нужно предоставить что-то еще? Спасибо за ответ

R.edd 01.11.2018 18:20

Я запустил ваш код с JDK 1.8, и фактическое и прогнозируемое не совпадают, но курсор мыши был перемещен в правильное место. Тот же код с JDK 11 работает.

Jason 04.04.2020 19:54

Пример кода не всегда будет работать. Чтобы он работал надежно, для получения SwingUtilities.invokeAndWait должен использоваться MouseInfo.

Jason 06.04.2020 17:49
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
11
4
3 258
2

Ответы 2

У меня такая же проблема. У меня есть инструкция «robot.mouseMove (100, 100);» и мышь вообще не двигается. У меня есть идея для исследования. Я заметил предупреждение или информационное сообщение от MacOS, когда выполнял свой код. Меня спрашивали о разрешении моей программе управлять экраном, системой или чем-то еще. Я попытался установить флажок «Разрешить», но мне это не удалось. Я исследую это еще немного. Думаю, дело в MacOS. Вы (и я) должны сказать MacOS, что наша программа Java может управлять мышью.

Я думаю, это решение. . .

В Системных настройках (значок «шестеренка») в разделе «Безопасность и конфиденциальность» щелкните вкладку «Конфиденциальность» вверху, а затем выберите «Доступность» слева. Здесь перечислены все программы, которые могут «управлять вашим компьютером». Я использую STS, а не IntelliJ. Я вижу STS в списке вместе с BetterSnapTool и KeyCastr. Проверяются как BetterSnapTool, так и KeyCastr. СТС не проверял. И все они неактивны, поэтому я не могу изменить ни одну из проверок. В левом нижнем углу окна есть значок замка. Я щелкнул значок, и появилось окно с запросом моего пароля (у меня есть некоторый уровень привилегий системного администратора). Я ввел свой пароль, и теперь мне разрешено «проверять» STS. Я "проверил" STS (вы будете "проверять" IntelliJ). После "проверки" STS я снова щелкнул значок замка в левом нижнем углу. Это «закрыл» замок. Теперь, когда я запускаю свою программу, команда робота перемещает мою мышь.

У меня уже был IntelliJ в списке разрешенных приложений для "Доступности". И у меня также проблема, когда мое приложение Java, запущенное в IntelliJ, не может перемещать мышь. Интересно, должна ли JVM быть одинаковой для моего приложения и IntelliJ. В настоящее время это не так.

Jason 04.04.2020 19:43

Итак, действительно, каждой JVM, которая должна запускать приведенный выше код, должно быть предоставлено разрешение с использованием метода, описанного здесь. IntelliJ встраивает JVM, но я не использую эту JVM для компиляции и запуска кода. Я использую Gradle, который запускает еще одну JVM. Кроме того, в Gradle есть рабочий демон, который необходимо перезапустить после предоставления разрешения JVM. Примечание: когда я говорю «JVM», я имею в виду команду java.

Jason 04.04.2020 20:43

Хорошо, это хуже, чем мой предыдущий комментарий. У меня был java для JDK 11.0.6 в списке разрешенных приложений, и все по-прежнему не работало. Чтобы решить эту проблему, мне пришлось удалить IntelliJ и все команды java из списка разрешенных приложений (удалить, а не снимать флажок). Затем мне пришлось запустить мою программу, используя gradle в командной строке (не в IntelliJ). Это привело к появлению окна macOS с запросом разрешений безопасности. Я щелкнул «Открыть системные настройки», и java был там. Я проверил это. Теперь это работает. Этот java такой же, как я добавил ранее вручную, и не работал. Я проверил это с помощью «Открыть в Finder».

Jason 06.04.2020 17:31

Вышеупомянутый метод также заставил работать при запуске из IntelliJ.

Jason 06.04.2020 17:31

У меня все еще возникают трудности с этим. Время от времени мне приходится удалять IntelliJ и все записи «java» из «Доступность» в разделе «Конфиденциальность» в системных настройках, а затем запускать gradle из командной строки, чтобы заставить macOS запросить разрешение. Потом еще какое-то время все работает. Очень странный.

Jason 28.04.2020 02:55

Большое спасибо за ваш комментарий! Я запустил свой автокликер java из iTerm2, поэтому мне пришлось включить iTerm в разделе Безопасность и конфиденциальность / Конфиденциальность / Доступность, чтобы он работал.

psmith 04.05.2020 02:27

Мне это было полезно. Пришлось снять в безопасности и поставить заново

Alejandro Gonzalez 04.10.2021 18:05

Ответ - «можно» и «нельзя». Начнем с «не могу».

Не могу:

Кажется, macOS неправильно определяет попытку переместить мышь как исходящую от IntelliJ, хотя на самом деле она исходит от java. Вы можете предоставить IntelliJ все необходимые разрешения, но java никогда не сможет перемещать курсор, когда разрешения предоставлены IntelliJ.

IntelliJ (который является приложением Java) запускает дочерний процесс для запуска вашей программы. Дочерний процесс - это командная строка java, а не тот же java, который поставляется с IntelliJ. Этому дочернему процессу требуются разрешения.

Жестяная банка:

Это немного по кругу.

  1. Используйте Gradle для создания своего проекта, IntelliJ распознает проекты Gradle и прекрасно с ними взаимодействует.
  2. Удалите все вхождения IntelliJ и Java из разрешений доступности в системных настройках macOS -> Безопасность и конфиденциальность.
  3. Убедитесь, что все демоны Gradle остановлены (или, если вы еще не запустили Gradle, убедитесь, что следующим шагом будет первый запуск Gradle с момента последней перезагрузки компьютера)
  4. Запустите приложение из командной строки с помощью Gradle
  5. macOS предложит предоставить разрешения, открыть системные настройки и предоставить разрешение java.
  6. Запустите IntelliJ и запустите свое приложение как проект Gradle через IntelliJ, и вуаля!

Что происходит: IntelliJ на шаге 6 использует уже запущенный процесс демона gradle для выполнения вашего приложения. В этом процессе используется java, и java имеет разрешение на перемещение курсора мыши в системных настройках macOS.

Это некрасиво, но работает. Если вы похожи на меня, вы все равно используете gradle для Java-проектов в IntelliJ, и все, что вам нужно сделать, это не забыть запустить свой проект из командной строки, прежде чем запускать его из IntelliJ. Таким образом, демон gradle (процесс java) будет отвечать за запуск приложения, а соответствующие разрешения будут обнаружены macOS.

Я проверил это с помощью следующего кода (обратите внимание на несколько модификаций, так как в коде OP были некоторые «ошибки»):

import javax.swing.SwingUtilities;
import java.awt.AWTException;
import java.awt.MouseInfo;
import java.awt.Robot;
import java.lang.reflect.InvocationTargetException;

public class RunRobot {
    public static void main(String[] args) {
        int x = 12,
            y = 300;
        final int[] xAct = new int[1],
                    yAct = new int[1];
        try {
            Robot robot = new Robot();
            robot.mouseMove(x, y);
            robot.waitForIdle();

            SwingUtilities.invokeAndWait(()->{
                xAct[0] = (int) MouseInfo.getPointerInfo().getLocation().getX();
                yAct[0] = (int) MouseInfo.getPointerInfo().getLocation().getY();
            });

            String sPred = String.format("Predicted mouse location : %, d, %, d", x, y),
                   sAct  = String.format("Actual    mouse location : %, d, %, d", xAct[0], yAct[0]);

            System.out.println(sPred);
            System.out.println(sAct);
        } catch (InterruptedException | AWTException | InvocationTargetException e) {
            e.printStackTrace();
        }
    }
}

Другие вопросы по теме