Awt机器人按键延迟

时间:2016-02-13 20:09:37

标签: java awtrobot jintellitype

我开发了一个小工具,用于游戏,如热键,处理用户按键事件的组合,并与Awt Robot模拟几个按键。问题是被调用方法ghostWalk()仅在按下注册组合时第一次按预期工作,第二次当我按下相同组合并且调用相同方法时,仅模拟在“robot.delay”之后的最后一个键。请阅读代码评论中的更多信息。

import com.melloware.jintellitype.HotkeyListener;
import com.melloware.jintellitype.JIntellitype;
import java.awt.*;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;

public class L {
int i = 160;

public static void main(String args[]){
    L l = new L();
    l.k();
}
public void k(){
    // Register keys combination
    JIntellitype.getInstance();
    JIntellitype.getInstance().registerHotKey(1, JIntellitype.MOD_ALT, (int)'D');
    JIntellitype.getInstance().registerHotKey(2, JIntellitype.MOD_ALT, (int)'J');
    JIntellitype.getInstance().registerHotKey(3, JIntellitype.MOD_ALT, (int)'K');
    JIntellitype.getInstance().addHotKeyListener(new HotkeyListener() {
        public void onHotKey(int aIdentifier) {
            // First indentifier Alt + D
            if (aIdentifier == 1) {
                System.out.println("Alt+D hotkey pressed");
                // Start new thread
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        L gh = new L();
                        gh.ghostWalk();
                    }
                }).start();
            }
            // Second indetifier
            else if(aIdentifier == 2){
                i += 10;
                System.out.println(i);
            }
            // Third
            else if(aIdentifier == 3){
                i -= 10;
                System.out.println(i);
            }
        }
    });
}
// Method called to simulate key press
/* So, first time when i press Alt + D in game after program runs
all work good, the keys are simulated  as expected but if I press again and again
the combination only key "d" are simulated which is after "delay(i), i = 160"
If program is restarted all again is the same, only first time when i press registered
combinations the program work as expected.
Second and others times program work only if there is delay "robot = new Robot();
                                                             robot.delay(100);"
 on 100 delay program work well on 40ms need to press very fast the combination
 so the program work as expected. How to fix it ? to simulate key press without
 delay like first time when program is run.
 P.s no matter in which window(game, notepad) you press combination to simulate key press
 still work good only first time.
Example of output when i press two times combinations in game
first time: qqwewwd
second time: d
 */
public void ghostWalk(){
    Robot robot = null;
    try {
        robot = new Robot();
        //robot.delay(100);
        robot.keyPress(KeyEvent.VK_Q);
        robot.keyRelease(KeyEvent.VK_Q);
        robot.keyPress(KeyEvent.VK_Q);
        robot.keyRelease(KeyEvent.VK_Q);
        robot.keyPress(KeyEvent.VK_W);
        robot.keyRelease(KeyEvent.VK_W);
        robot.keyPress(KeyEvent.VK_R);
        robot.keyRelease(KeyEvent.VK_R);
        robot.keyPress(KeyEvent.VK_W);
        robot.keyRelease(KeyEvent.VK_W);
        robot.keyPress(KeyEvent.VK_W);
        robot.keyRelease(KeyEvent.VK_W);
        robot.delay(i);
        robot.keyPress(KeyEvent.VK_D);
        robot.keyRelease(KeyEvent.VK_D);

    } catch (Exception e) {
        e.printStackTrace();
    }
}

}

编辑:我无法理解在第一次调用ghostWalk方法之后所做的更改,我应该使用延迟,以便我的程序按预期工作。

Edit2:在我的情况下,当setAutoWaitForIdle设置为true并且delay = 5(开始模拟按键之前的延迟)时,代码开始工作 按键是延迟,就像在我的情况下延迟(i),i = 160然后启动延迟应该是60~。 (如果启动延迟是40~那么总是不能正常工作,需要非常快速地按下注册键组合idk为什么,如果启动延迟小于40-60,在我的情况下只模拟最后一次按键“D”,这是延迟后( i)中。)

如果要在首次注册的热键事件中删除robot.setAutoWaitForIdle(true)robot.delay(60),该工具将按预期工作,在第二,第三等时间工作 - 不是。在第一次JIntellitype事件之后只有这段代码工作。

public void ghostWalk(){
    Robot robot = null;
    try {
        robot = new Robot();
        robot.setAutoWaitForIdle(true);
        robot.delay(60);
        robot.keyPress(KeyEvent.VK_Q);
        robot.keyRelease(KeyEvent.VK_Q);
        robot.keyPress(KeyEvent.VK_Q);
        robot.keyRelease(KeyEvent.VK_Q);
        robot.keyPress(KeyEvent.VK_W);
        robot.keyRelease(KeyEvent.VK_W);
        robot.keyPress(KeyEvent.VK_R);
        robot.keyRelease(KeyEvent.VK_R);;
        robot.delay(i);
        robot.keyPress(KeyEvent.VK_D);
        robot.keyRelease(KeyEvent.VK_D);

    } catch (Exception e) {
        e.printStackTrace();
    }
}

1 个答案:

答案 0 :(得分:0)

您应该考虑使用setAutoDelay设置自动延迟。

如果您的操作系统在没有延迟的情况下发布,那么您的操作系统很可能无法处理输入事件。尝试50毫秒或25毫秒延迟,看看会发生什么。

您可以尝试的另一件事是在每次按键前添加waitForIdle()

编辑:对于体育项目,我尝试了JIntelliType library,以下代码段效果相对较好。我测试了在Notepad++ctrl-Q)中按热键,并且一直打印出tt rocks。但是我必须快速释放热键,否则Notepad ++开始将热键解释为其他内容(ctrl-Q已经是Notepad ++中其他内容的快捷键)。

使用机器人并不是一门精确的科学。我不得不延迟机器人150毫秒,然后waitForIdle,然后让机器人按下键。事情搞砸了。不需要设置自动延迟。

import java.awt.AWTException;
import java.awt.Robot;
import java.awt.event.KeyEvent;
import com.melloware.jintellitype.HotkeyListener;
import com.melloware.jintellitype.JIntellitype;

public class TestKeys {
    private HotkeyListener listener = new HotkeyListener() {
        @Override
        public void onHotKey(final int hotKeyId) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    JIntellitype.getInstance().removeHotKeyListener(listener);
                    handleHotKey(hotKeyId);
                    JIntellitype.getInstance().addHotKeyListener(listener);
                }
            }).start();
        }
    };

    public void registerHotKeys() {
        JIntellitype instance = JIntellitype.getInstance();
        instance.registerHotKey(1, JIntellitype.MOD_CONTROL, 'Q');
        instance.registerHotKey(2, JIntellitype.MOD_CONTROL, 'J');
        instance.addHotKeyListener(listener);
        System.out.println("Hotkeys registered");
    }

    private static void handleHotKey(int hotKeyId) {
        switch(hotKeyId) {
            case 1:
                System.out.println("Pressing some keys now!");
                pressSomeKeys();
                break;
            case 2:
                System.out.println("Bailing out, cya!");
                System.exit(0);
                break;
        }
    }

    private static void pressSomeKeys() {
        Robot r;
        try {
            r = new Robot();
        } 
        catch (AWTException e) {
            System.out.println("Creating robot failed");
            System.exit(2);
            return;
        }
        r.setAutoWaitForIdle(true);
        r.delay(150);
        r.waitForIdle();
        r.keyPress(KeyEvent.VK_T); r.keyRelease(KeyEvent.VK_T);
        r.keyPress(KeyEvent.VK_T); r.keyRelease(KeyEvent.VK_T);
        r.keyPress(KeyEvent.VK_SPACE); r.keyRelease(KeyEvent.VK_SPACE);
        r.keyPress(KeyEvent.VK_R); r.keyRelease(KeyEvent.VK_R);
        r.keyPress(KeyEvent.VK_O); r.keyRelease(KeyEvent.VK_O);
        r.keyPress(KeyEvent.VK_C); r.keyRelease(KeyEvent.VK_C);
        r.keyPress(KeyEvent.VK_K); r.keyRelease(KeyEvent.VK_K);
        r.keyPress(KeyEvent.VK_S); r.keyRelease(KeyEvent.VK_S);
    }

    public static synchronized void main(String[] args) {
        System.out.println("TestKeys started");
        TestKeys k = new TestKeys();
        k.registerHotKeys();
        try { 
            TestKeys.class.wait();
        } 
        catch (InterruptedException e) {
        }
    }
}