2

So basically i tried to get this while loop to run inside this thread, it should activate when "activate" evaluates to true but for some reason it is not working. "activate" is boolean value which activates when user presses mouse button (i setted up listener for that). If anyone wonders im using jnativehook library for this project. Any help or explanation would be greatly appreciated.

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);
        }
    }       
}
Solomon Slow
  • 25,130
  • 5
  • 37
  • 57
IchBinIVAN
  • 21
  • 1
  • 1
    Your example is incomplete. Please show, at least, the code that sets `activate` to `true`. It might also be helpful if you showed how the various threads get started. – Solomon Slow Nov 13 '19 at 19:51

4 Answers4

1

One possibility is that the compiler (either the Java compiler, or the JIT compiler) has decided that it does not need to test activate because it can prove that nothing inside the while loop ever changes it. In most compiled programming languages, the compiler is allowed to assume that the code will be single threaded unless you do something special to tell it otherwise. That assumption is justified because it enables the compiler to generate much more efficient code most of the time.

Accessing the variable from within a synchronized block, or declaring the variable to be volatile would prevent the compiler from making that assumption.

Better still would be to use a private final AtomicBoolean activate;.

Solomon Slow
  • 25,130
  • 5
  • 37
  • 57
1

activate is never set to true. If you don't believe me then add this line at the bottom of your while loop:

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

LowKeyEnergy
  • 652
  • 4
  • 11
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();
}
}
Albert Lipaev
  • 66
  • 1
  • 1
  • 5
0

Thanks for all suggestion fixed the problem by passing class instance to my MouseListener class.

For anyone that gets same problem:

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;
}** 

Here is the class that changes "activate" to "true".

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);
    }
}

}

IchBinIVAN
  • 21
  • 1