JNativeHook KeyEvent到Java KeyCode

时间:2016-09-02 13:58:56

标签: java awtrobot

我正在编写一个可以记录鼠标和键输入的程序,并在完成录制后播放它们。为了全局记录这些输入,我使用了JNativeHook。 这适用于所有Mouselisteners,但NativeKeyListeners的NativeKeyCodes与Java的KeyCodes不同。作为一种解决方法,我获得KeyText,然后将其转换回带

的KeyCode
AWTKeyStroke ks = AWTKeyStroke.getAWTKeyStroke(keytext);
ks.getKeyCode()

这适用于字母,数字甚至F键(例如:F10)。 但每当它试图转换像#34; Backspace"它落后于例外:

java.lang.IllegalArgumentException: String formatted incorrectly
    at java.awt.AWTKeyStroke.getVKValue(AWTKeyStroke.java:576)
    at java.awt.AWTKeyStroke.getAWTKeyStroke(AWTKeyStroke.java:522)
    at main.ScriptPlayer.executeCommand(ScriptPlayer.java:71)
    at main.ScriptPlayer.access$5(ScriptPlayer.java:55)
    at main.ScriptPlayer$1.run(ScriptPlayer.java:38)

有没有办法成功地将NativeKeyEvent(例如从退格)转换为来自Java的KeyCode?

监听器中的完整代码:

package listener;

import java.awt.MouseInfo;
import java.awt.Point;
import java.awt.event.InputEvent;

import main.InputRecorder;

import org.jnativehook.keyboard.NativeKeyEvent;
import org.jnativehook.mouse.NativeMouseEvent;

import util.KeyBindings;

public class InputRecordListener extends InputAdapter{

    private InputRecorder recorder;

    public InputRecordListener(InputRecorder recorder){
        this.recorder = recorder;
    }

    @Override
    public void nativeMouseMoved(NativeMouseEvent e) {
        recorder.move(getLocation());
    }

    @Override
    public void nativeMouseDragged(NativeMouseEvent e) {
        nativeMouseMoved(e);
    }

    @Override
    public void nativeMousePressed(NativeMouseEvent e) {
        recorder.mousePressed(convertButtonToButtonMask(e.getButton()));
    }

    @Override
    public void nativeMouseReleased(NativeMouseEvent e) {
        recorder.mouseReleased(convertButtonToButtonMask(e.getButton()));
    }

    @Override
    public void nativeKeyPressed(NativeKeyEvent e) {
        if (e.getKeyCode() == KeyBindings.leftButton || e.getKeyCode() == KeyBindings.rightButton) return;
        System.out.println(NativeKeyEvent.getKeyText(e.getKeyCode()));
        recorder.keyPressed(NativeKeyEvent.getKeyText(e.getKeyCode()));
    }

    @Override
    public void nativeKeyReleased(NativeKeyEvent e) {
        if (e.getKeyCode() == KeyBindings.leftButton || e.getKeyCode() == KeyBindings.rightButton) return;
        System.out.println(NativeKeyEvent.getKeyText(e.getKeyCode()));
        recorder.keyReleased(NativeKeyEvent.getKeyText(e.getKeyCode()));
    }

    private static Point getLocation(){
        return MouseInfo.getPointerInfo().getLocation();
    }

    private static int convertButtonToButtonMask(int button){
        switch(button){
        case 1:
            return InputEvent.BUTTON1_MASK;
        case 2:
            return InputEvent.BUTTON3_MASK;
        case 3:
            return InputEvent.BUTTON2_MASK;
        default:
            throw new IllegalArgumentException();
        }
    }
}

播放器中的完整代码(在机器人上执行命令的类)

package main;

import java.awt.AWTException;
import java.awt.AWTKeyStroke;
import java.awt.Robot;
import java.io.BufferedReader;
import java.io.StringReader;

import util.TimeRecorder;

public class ScriptPlayer {

    private Robot robot;
    private boolean playing;
    private boolean paused;
    private boolean loop = false;
    private long resumptionTime = 0;

    public void playScript(final String script){
        new Thread(){
            public void run(){
                playing = true;
                paused = false;
                try {
                    if (robot == null)robot = new Robot();
                } catch (AWTException e) {
                    e.printStackTrace();
                }
                do{
                    BufferedReader reader = new BufferedReader(new StringReader(script));
                    try {
                        String line = reader.readLine();
                        int i = 0;
                        TimeRecorder tr = new TimeRecorder();
                        while (line != null && playing){
                            AutoClicker.getInstance().log(++i + ": " + line);
                            tr.start();
                            executeCommand(line);
                            while(paused || resumptionTime > System.currentTimeMillis()){sleep(1);}
                            AutoClicker.getInstance().logln("     Command Executed In " + tr.getTimeMillisPassed() + " Millis");
                            line = reader.readLine();
                        }
                    }
                    catch (Exception e) {
                        e.printStackTrace();
                        break;
                    }
                }while (loop);
                playing = false;
                AutoClicker.getInstance().stopPlaying();
            }
        }.start();
    }

    //A command can look like this: "keypress: H"
    private void executeCommand(String command){
        if (command.contains("move")){
            int xValue = Integer.parseInt(command.substring(6, command.indexOf("/")));
            int yValue = Integer.parseInt(command.substring(command.indexOf("/") + 1));
            robot.mouseMove(xValue, yValue);
        }else if (command.contains("wait")){
            int value = Integer.parseInt(command.substring(6));
            resumptionTime = System.currentTimeMillis() + value;
        }else if (command.contains("mousepress")){
            int mask = Integer.parseInt(command.substring(12));
            robot.mousePress(mask);
        }else if (command.contains("mouserelease")){
            int mask = Integer.parseInt(command.substring(14));
            robot.mouseRelease(mask);
        }else if (command.contains("keypress")){
            String keytext = command.substring(10);
            AWTKeyStroke ks = AWTKeyStroke.getAWTKeyStroke(keytext);
            System.out.println(keytext);
            robot.keyPress(ks.getKeyCode());
        }else if (command.contains("keyrelease")){
            String keytext = command.substring(12);
            AWTKeyStroke ks = AWTKeyStroke.getAWTKeyStroke(keytext);
            System.out.println(keytext);
            robot.keyRelease(ks.getKeyCode());
        }
    }

    public void terminate(){
        playing = false;
    }

    public void pause(){
        resumptionTime = resumptionTime - System.currentTimeMillis();
        paused = true;
    }

    public void resume(){
        resumptionTime = resumptionTime + System.currentTimeMillis();
        paused = false;
    }

    public void setLoop(boolean loop){
        this.loop = loop;
    }
}

0 个答案:

没有答案