按编程方式按住键java

时间:2014-04-08 23:45:48

标签: java multithreading

好吧,我现在已经搜索了一整天,但没有结果。也许有人可以帮助它。

我正在尝试以编程方式在我的java程序中生成一个关键的“按住”状态。让我解释一下情况:

我经常听一个活动。考虑2个事件'A'和'B'。如果发生事件A,我想按住键盘键(X),如果发生事件'B',我想释放键(X)。现在最重要的是,这一切都必须是一个副流程,所以即使A出现,我也可以听B事件。

我尝试制作一个单独的线程,在其中创建一个无限循环,在java中使用'Robot'按键,但事实证明这是实现这一目标的最低效方式,因为它消耗了60%以上的CPU。我尝试通过更改状态来实现此目的,但似乎没有找到限制按键的方法,只有在我想要的时候才能更改。

如果可能的话,我会很感激没有任何无限循环的解决方案,因为我已经使用1来监听事件发生。 (建议欢迎)

这是我的线程代码:

public class KeyPress implements Runnable {
public String command;

public void run() {
    try {
        Robot r = new Robot();

        while (true) {
            //System.out.println(command);
            if (command.equals("up")) {
                r.keyPress(KeyEvent.VK_UP);
                r.delay(20);
                r.keyRelease(KeyEvent.VK_UP);
            } else if (command.equals("finish")) {
                break;
            }
        }

    } catch (Exception e) {
        System.out.println(e);
    }
}
}

在我的主类中,像往常一样创建线程的实例。 此外,如果有人可以解释这一点 - 我删除或注释

System.out.println(command);

语句(如代码所示),此线程停止工作。如果我添加它,它的工作原理。虽然这个问题是次要的,因为它仍然是一个不可行的解决方案。

2 个答案:

答案 0 :(得分:1)

嗯,经过漫长而累人的尝试来解决这个问题,我想我可能有一个解决方案。

首先,我每次活动创建一个帖子' A'发生了,虽然它和以前一样。当活动' B'发生,我打断线程,这使它退出。由于这些事件' A'和' B'或者,这适用于CPU使用问题。

另一个优化,可能是必须编写print()语句的问题的答案,我将变量command设为volatile。正如here所解释的那样,编译器优化很可能是我面临的问题。

以下是这些更改后的代码:

public class KeyPress implements Runnable {
public volatile String command;

public void run() {
    try {
        Robot r = new Robot();
        while (command.equals("up") && !Thread.currentThread().isInterrupted()) {
            r.keyPress(KeyEvent.VK_UP);
            r.delay(20);
        }
    } catch (Exception e) {
        System.out.println(e);
    }
}
}

我希望这可以帮助某人,并且有人可以提供有关如何改进它的建议。

答案 1 :(得分:0)

Observer pattern可能是一个很好的解决方案。

不要在线程中循环。使用这样的通知和监听模式:

听取命令:

class RobotObserver implements Observer{
    private Robot  r = new Robot();
    @Override
    public void update(Observable o, Object arg) {
        String command=arg.toString();
        if (command.equals("up")) {
            r.keyPress(KeyEvent.VK_UP);
            r.delay(20);
            r.keyRelease(KeyEvent.VK_UP);
        } else if (command.equals("finish")) {
            System.out.println(command);
        }
    }
}

通知听众:

Observable observable = new Observable();
observable.addObserver(new RobotObserver());
observable.notifyObservers("up");
observable.notifyObservers("finish");

PS:ObserverObservable都在java.util包中。