Java Имитация клавиатуры - PullRequest
2 голосов
/ 07 ноября 2011

Как бы я отправил текст на компьютер (например, с клавиатуры) через Java class? Я рассмотрел использование класса Robot для нажатия и отпускания каждой клавиши, но это было бы утомительно, и нет способа получить KeyCode от char.

Ответы [ 4 ]

1 голос
/ 07 ноября 2011
0 голосов
/ 18 февраля 2013

Нет, есть и мягкий способ (ну, на Windows это работает как минимум; -)):

private static void outputString(Robot robot,String str)
{
    Toolkit toolkit = Toolkit.getDefaultToolkit();
    boolean numlockOn = toolkit.getLockingKeyState(KeyEvent.VK_NUM_LOCK);

    int[] keyz=
    {
            KeyEvent.VK_NUMPAD0,
            KeyEvent.VK_NUMPAD1,
            KeyEvent.VK_NUMPAD2,
            KeyEvent.VK_NUMPAD3,
            KeyEvent.VK_NUMPAD4,
            KeyEvent.VK_NUMPAD5,
            KeyEvent.VK_NUMPAD6,
            KeyEvent.VK_NUMPAD7,
            KeyEvent.VK_NUMPAD8,
            KeyEvent.VK_NUMPAD9
    };

    if(!numlockOn)
    {
        robot.keyPress(KeyEvent.VK_NUM_LOCK);
    }

    for(int i=0;i<str.length();i++)
    {
        int ch=(int)str.charAt(i);
        String chStr=""+ch;
        if(ch <= 999)
        {
            chStr="0"+chStr;
        }           
        robot.keyPress(KeyEvent.VK_ALT);                    
        for(int c=0;c<chStr.length();c++)
        {               
            int iKey=(int)(chStr.charAt(c)-'0');
            robot.keyPress(keyz[iKey]);             
            robot.keyRelease(keyz[iKey]);               
        }
        robot.keyRelease(KeyEvent.VK_ALT);
    }       

    if(!numlockOn)
    {
        robot.keyPress(KeyEvent.VK_NUM_LOCK);
    }       
}
0 голосов
/ 28 сентября 2012

@ JavaCoder-1337 Не совсем ...

Хотя некоторые switch-case (трудный путь?) все еще необходимы для обработки некоторых (специальных) символов, большинство символов могутобрабатываться довольно легко.

Сколько вам нужно, зависит от вашей целевой аудитории , но в любом случае вы можете справиться с этим с помощью комбинации:

  • AWTKeyStroke.getAWTKeyStroke(char yourChar).getKeyCode(); - который обрабатывает самые основные из них;a-zA-Z переведены в базовую (a-z) keyEvents, и некоторые другие символы также обрабатываются аналогично (base key only, no modifiers thus no casing is applied).

AsВы можете себе представить, что этот метод особенно эффективен для упрощения работы с английским языком, поскольку в языке мало используются акцентированные буквы по сравнению со многими другими.

  • Normalizer.normalize(String textToNormalize, Form.NFD); - который разбивает большинство составных (акцентированных) символов,как áàãâä,éèêë,íìîï,etc, и они являются заглавными эквивалентами, к их базовым элементам.Пример: á (224) становится a (97), за которым следует ´ [769].

Если ваш метод send(String text) может отправлять акценты, простой swap ударения (в примере это VK_DEAD_ACUTE) и это письмо, чтобы они получили правильный порядок отправки, и вы получите желаемый á вывод.Таким образом, устраняется необходимость в фильтре á.

В сочетании с первым упрощением, для этого примера, получается 1/3 [´] вместо 3/3 [a,á,´] switch-case!

Это лишь некоторые из многих упрощений, которые можно сделать, чтобы сократить этот ужасно длинный метод switch-case, который (неразумно) предлагается многими коллегами-программистами.

Например, вы можете легко обрабатывать обсадные колонки.путем определения, является ли отправляемый символ заглавными, а затем, если необходимо, определяется текущее состояние колпачка для инвертирования операции с оболочкой:

boolean useShift = Character.isUpperCase(c);
useShift = Toolkit.getDefaultToolkit().getLockingKeyState(KeyEvent.VK_CAPS_LOCK) ? !useShift : useShift;
if (useShift) {
  keyPress(KeyEvent.VK_SHIFT);
  sendChar(aChar);
  keyRelease(KeyEvent.VK_SHIFT);
} else {
  sendChar(aChar);
}

Другой вариант (тот, который я использую), которыйеще проще, просто кодировать макрос на инструменте / языке, который (гораздо) больше подходит для такого рода операций (я использую и рекомендую AutoHotKey ), и просто вызывать его выполнение из Java:

Runtime rt = Runtime.getRuntime();
//"Hello World!" is a command-line param, forwarded to the ahk script as it's text-to-send.
rt.exec(".../MyJavaBot/sendString.ahk \"Hello World!\"");
0 голосов
/ 07 ноября 2011

Используйте каркас тестирования GUI (даже если вы не используете его для тестирования). Я рекомендую FEST . В FEST вы можете искать элементы GUI и автоматизировать все виды взаимодействия с пользователем, включая ввод текста.

Например, если у вас есть фиксатор текстового поля (термин FEST для оболочки, позволяющей управлять компонентом), вы можете сделать

JTextComponentFixture fixture =  ...;
fixture.enterText("Some text");
...