2

所以基本上我试图让这个while循环在这个线程中运行,它应该在“激活”评估为真时激活,但由于某种原因它不起作用。“激活”是布尔值,当用户按下鼠标按钮时激活(我为此设置了监听器)。如果有人想知道我在这个项目中使用 jnativehook 库。任何帮助或解释将不胜感激。

private boolean activate;
private Robot robot;


@Override
public void run() {
    try {
        robot = new Robot();
    } catch (AWTException e) {
        e.printStackTrace();
    }

    while(true) {
        if (activate == true) {
            robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
            robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
            robot.delay(100);
        }
    }       
}
4

4 回答 4

1

一种可能性是编译器(Java 编译器或 JIT 编译器)已决定不需要测试activate,因为它可以证明while循环内没有任何东西会改变它。在大多数编译型编程语言中,编译器被允许假设代码是单线程的,除非你做一些特别的事情来告诉它。这个假设是合理的,因为它使编译器能够在大多数时间生成更高效的代码。

synchronized块中访问变量或将变量声明为volatile将阻止编译器做出该假设。

更好的是使用private final AtomicBoolean activate;.

于 2019-11-13T19:53:52.650 回答
1

activate 永远不会设置为 true。如果您不相信我,请将此行添加到您的 while 循环底部:

System.out.println("activate = " + activate);

于 2019-11-13T19:58:11.453 回答
0
// Here is the sample program which should run your method correctly. All the changes 
// are commented upon. Don't judge harshly, not a professional with java


import java.awt.AWTException;
import java.awt.Robot;
import java.awt.event.InputEvent;
import java.util.Scanner;

class Processor extends Thread {

// Have to initialize the variable here
private boolean activate = true;
private Robot robot;

public void run() {
    try {
        robot = new Robot();
    } catch (AWTException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    // No need for while (true) here
    while (activate) {
        robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
        robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
        robot.delay(100);
    }
}

// method to stop the program
public void shutdown() {
    activate = false;
}
}

public class App {
public static void main(String[] args) throws AWTException, InterruptedException, NullPointerException {
    // activates the process
    Processor p = new Processor();
    p.start();

    // Press any key to stop the process
    // program will run endlessly until scanner value (key input) is provided
    Scanner key_input = new Scanner(System.in);
    key_input.nextLine();
    p.shutdown();
}
}
于 2019-11-13T21:48:02.497 回答
0

感谢所有建议通过将类实例传递给我的 MouseListener 类来解决问题。

对于遇到同样问题的任何人:

public boolean activate;
public boolean toggled;

private Robot robot;
public MouseListener mouseListener = new MouseListener();
public KeyboardListener keyListener = new KeyboardListener();
public static Game instance;

public Game() {
    this.activate = false;
//  this.toggled = false;

    try {
        GlobalScreen.registerNativeHook();
        GlobalScreen.isNativeHookRegistered();
        GlobalScreen.addNativeMouseListener(mouseListener);
        GlobalScreen.addNativeKeyListener(keyListener);
    } catch (NativeHookException e) {
        e.printStackTrace();
    }
}

public void run() {
    try {
        robot = new Robot();
    } catch (AWTException e) {
        e.printStackTrace();
    }

    while(true) {
        try {
            Thread.sleep(1L);
            if(Game.this.isActivate()) {
                robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
                robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
                robot.delay(100);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }       
}

public boolean isActivate() {
    return activate;
}

public void setActivate(boolean activate) {
    this.activate = activate;
}

public boolean isToggled() {
    return toggled;
}

public void setToggled(boolean toggled) {
    this.toggled = toggled;
} 

**public static Game getGame() {
    if(Game.instance == null) {
    Game.instance = new Game();
    }
    return Game.instance;
}** 

这是将“激活”更改为“真”的类。

public void nativeMouseClicked(NativeMouseEvent e) {
    // nothing
}


public void nativeMousePressed(NativeMouseEvent e) {
    if(e.getButton() == NativeMouseEvent.BUTTON1) {
        Game.getGame().setActivate(true);
    }
}


public void nativeMouseReleased(NativeMouseEvent e) {
    if(e.getButton() == NativeMouseEvent.BUTTON1) {
        Game.getGame().setActivate(false);
    }
}

}

于 2019-11-16T16:45:37.587 回答