I'm working on a simple overlay program for PC games. It's just a transparent rectangle positioned in the center of the screen but its size is controlled by the user's mouse wheel. So the concept is to simply match the size of the transparent rectangle to the size of the enemy player to calculate his distance.
Unfortunately I cannot make this happen with conventional mouse listeners because the mouse must be focused on the game and the overlay program at the same time. I'm trying JNativeHook, but I can't get my rectangle to update. Any advice?
public class Main extends Application implements NativeMouseWheelListener {
Rectangle r = new Rectangle();
int y = 540;
int width = 75;
int height = 180;
int velocity = 10;
@Override
public void start(Stage stage) throws Exception {
AnchorPane root = new AnchorPane();
r = rect();
root.getChildren().add(r);
root.setStyle("-fx-background-color: rgba(0, 0, 0, 0);");
Scene scene = new Scene(root, 1920, 1080);
scene.setFill(null);
stage.initStyle(StageStyle.TRANSPARENT);
stage.setScene(scene);
stage.setX(0);
stage.setY(0);
stage.show();
stage.setAlwaysOnTop(true);
}
public void nativeMouseWheelMoved(NativeMouseWheelEvent e) {
int direction = e.getWheelRotation();
System.out.println("Mouse Wheel Moved: " + direction);
r.setY(r.getY() + direction);
}
public Rectangle rect() {
r.setWidth(width);
r.setHeight(height);
r.setX(960 - (width/2));
r.setY(540);
r.setFill(Color.TRANSPARENT);
r.setStroke(Color.BLACK);
return r;
}
public static void main(String[] args) {
go();
launch(args);
}
public static void go() {
try {
GlobalScreen.registerNativeHook();
}
catch (NativeHookException ex) {
System.err.println("There was a problem registering the native hook.");
System.err.println(ex.getMessage());
ex.printStackTrace();
System.exit(1);
}
GlobalScreen.getInstance().addNativeMouseWheelListener(new Main());
}
}
I highly recommend taking @vince-emigh advice and running JNativeHook on the same thread as your ui environment by using a custom implementation of the AbstractExecutorService as follows.
Then use the class as the event dispatcher:
For more information, please see the Thread Safety article in the wiki