Подтвердить что ты не робот

Прослушивание ввода без фокуса в Java

Я делаю небольшую программу на Java, используя класс Robot. Программа берет на себя мышь. в то время как в процессе отладки, если он начинает действовать так, что я не хочу, чтобы это было сложно выйти из программы, так как я не могу переместить указатель мыши на кнопку завершения в eclipse, и я не могу использовать горячие клавиши для нажмите его, потому что мышь постоянно щелкает в другом окне, вместо этого вместо этого фокусируется окно.

То, что я хотел бы сделать, это просто подключить keylistener, так что, когда я нажму q, я могу выйти из программы, но единственный способ, которым я знаю, как это сделать, заключается в создании окна, и этому окну требуется фокус для захвата вход. Есть ли способ слушать ввод с клавиатуры или мыши из любого места, независимо от того, что имеет фокус?

4b9b3361

Ответ 1

Это не тривиальная проблема, и Java не дает вам способ сделать это элегантно. Вы можете использовать решение, подобное предложению banjollity, но даже это не будет работать все время, если ваши странные щелчки мыши откроют другое полноразмерное окно, открытое в настоящее время на панели задач.

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

Итак, чтобы ответить на ваш вопрос, я представляю, что вы хотите, это какое-то поведение для вашей программы, где он слушает нажатия клавиш во всем мире, а не только в вашем приложении. Что-то вроде этого потребует, чтобы вы получили доступ к функциям, предлагаемым вашей ОС по выбору, и для доступа к нему в Java вам нужно будет сделать это с помощью уровня Java Native Interface (JNI).

Итак, что вы хотите сделать:

  • Внедрить программу на C, которая будет прослушивать глобальные нажатия клавиш на вашей ОС, если эта ОС - Windows, а не поиск документации по перехватам окон, которая хорошо документирована Microsoft и MSDN в Интернете и в других местах. Если ваша ОС - Linux или Mac OS X, вам нужно будет слушать глобальные нажатия клавиш с помощью библиотек разработки X11. Это можно сделать на дистрибутиве ubunutu linux в соответствии с Howto, который я написал в http://ubuntuforums.org/showthread.php?t=864566

  • Подключите свой код C к вашему Java-коду через JNI. Этот шаг на самом деле является более легким шагом. Следуйте процедуре, которую я использую в своем учебном пособии в http://ubuntuforums.org/showthread.php?t=864566 под обоими окнами и linux в качестве процедуры для подключения вашего кода C к вашему Java-коду будут идентичны для обеих ОС.

Важно помнить, что гораздо проще получить код JNI, если вы сначала код и отлаживаете свой код на C/С++ и убедитесь, что он работает. Тогда интеграция с Java упрощена.

Ответ 3

Была такая же проблема. В моем случае робот просто контролировал одно приложение Windows, которое было максимизировано. Я поместил эти строки в верхней части основной петли, управляющей роботом:

Цвет iconCenterColor = новый Цвет (255,0,0);//если значок программы красный

if (iconCenterColor.equals(robot.getPixelColor(10,15)))  throw new IllegalStateException ( "робот не взаимодействует с нужным приложением" );

Чтобы отменить робот, просто выберите alt-tab в другое приложение. Отлично подходит для простого робота, управляющего приложением.

Ответ 4

Запустите программу из командной строки в терминале и используйте Ctrl-C для ее завершения.

Ответ 5

Попросите свою программу открыть второе окно, которое отображается под вашим основным окном, но максимально, тогда ваши ошибочные щелчки мыши будут получены в максимально развернутом окне, и он сможет получить ваш ввод на клавиатуре.

Ответ 6

Здесь используется чистый Java-способ для решения проблемы, которую вы описали (а не проблема KeyListener... тест quit рано при использовании проблемы с роботом):

На протяжении всего теста сравните положение мыши с тем, которое недавно установил ваш тест. Если он не соответствует, выйдите из теста. Примечание. важная часть этого кода - это метод testPosition. Здесь код, который я использовал недавно:

public void testSomething() throws Exception {
    try {
        // snip

        // you can even extract this into a method "clickAndTest" or something
        robot.mouseMove(x2, y2);
        click();
        testPosition(x2, y2);

        // snip
    } catch (ExitEarlyException e) {
        // handle early exit
    }
}

private static void click() throws InterruptedException {
    r.mousePress(InputEvent.BUTTON1_DOWN_MASK);
    Thread.sleep(30 + rand.nextInt(50));
    r.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
    Thread.sleep(30 + rand.nextInt(50));
}

private static void testPosition(int x2, int y2) throws ExitEarlyException {
    Point p = MouseInfo.getPointerInfo().getLocation();
    if(p.x != x2 || p.y != y2) throw new ExitEarlyException();
}