Home > other >  Creating an autoclick using JavaFX
Creating an autoclick using JavaFX

Time:01-14

I'm creating an autoclick program. It will probably need some fixes, but I have a major problem: My program does not detect when I press the defined key, so it does not start clicking.

package fr.didier.autoclicker;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.input.KeyCode;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

import java.awt.*;
import java.awt.event.InputEvent;
import java.util.Random;

public class AutoClicker extends Application {
    private int minCps;
    private int maxCps;
    private Thread clickThread;
    private boolean running = false;
    private boolean paused = false;
    private Random random = new Random();
    private KeyCode triggerKey = KeyCode.UNDEFINED;
    private TextField minCpsField;
    private TextField maxCpsField;
    private Button startButton;
    private Button stopButton;
    private Button chooseKeyButton;
    private Label keyLabel;

    public AutoClicker() {
    }

    @Override
    public void start(Stage primaryStage) throws Exception {
        minCpsField = new TextField();
        maxCpsField = new TextField();
        chooseKeyButton = new Button("Choose key");
        keyLabel = new Label("Key: not chosen");

        chooseKeyButton.setOnAction(e -> {
            keyLabel.setText("Press a key to choose as trigger");
            primaryStage.getScene().setOnKeyPressed(event -> {
                if (event.isControlDown() || event.isAltDown() || event.isShiftDown()) {
                    keyLabel.setText("Please choose a key that is not already in use by the operating system or other applications");
                } else {
                    triggerKey = event.getCode();
                    keyLabel.setText("Key: "   triggerKey);
                    primaryStage.getScene().setOnKeyPressed(null);
                }
            });
        });

        HBox minCpsBox = new HBox(new Label("Min CPS: "), minCpsField);
        HBox maxCpsBox = new HBox(new Label("Max CPS: "), maxCpsField);
        HBox keyBox = new HBox(chooseKeyButton, keyLabel);
        VBox root = new VBox(minCpsBox, maxCpsBox, keyBox);

        Scene scene = new Scene(root, 300, 250);

        primaryStage.setScene(scene);
        primaryStage.show();

        primaryStage.getScene().setOnKeyPressed(event -> {
            if (event.getCode() == triggerKey) {
                if (!running) {
                    if (minCpsField.getText().isEmpty() || maxCpsField.getText().isEmpty()) {
                        keyLabel.setText("Please set the min and max CPS values before starting the autoclick");
                    } else {
                        minCps = Integer.parseInt(minCpsField.getText());
                        maxCps = Integer.parseInt(maxCpsField.getText());
                        start(triggerKey);
                    }
                } else {
                    if (!paused) {
                        pause();
                    } else {
                        resume();
                    }
                }
            }
        });

        primaryStage.getScene().setOnKeyReleased(event -> {
            if (event.getCode().equals(triggerKey)) {
                if (running) {
                    pause();
                }
            }
        });
    }

    public void start(KeyCode triggerKey) {
        this.triggerKey = triggerKey;
        running = true;
        clickThread = new Thread(() -> {
            while (running) {
                while (!paused) {
                    try {
                        int delay = 1000 / (random.nextInt(maxCps - minCps   1)   minCps);
                        Thread.sleep(delay);

                        Robot robot = new Robot();
                        robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
                        robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
                    } catch (InterruptedException | AWTException e) {
                        e.printStackTrace();
                    }
                }
            }
        });
        clickThread.start();
    }


    public void stop() {
        running = false;
        paused = false;
        clickThread = null;
    }

    public void pause() {
        paused = true;
    }

    public void resume() {
        paused = false;
    }
}

At first I made several types of checks to know if the touch was well-defined, then taken into account. I tried to add the triggerKey argument in the start method; I also made tests with Start/Stop buttons which are still present in my code but which allowed me to see if my autoclick was clicking well (and yes it does click well, I made a correct equation, which realizes the number of clicks I want well in theory since I can't really test it at 100% currently).

I made a console message when the autoclick clicks, but no console message is sent so the autoclick doesn't work, I made it in the loop that handles clicks after the line that uses the Robot class

CodePudding user response:

Your event handler for the "Choose key" button sets the key pressed handler for the scene to null, so no further key presses will be detected. Put the event handler you need in a variable, and set it from there.

Note that you should not mix JavaFX and AWT: use the JavaFX Robot instead of the AWT robot, and you should replace the threading code with Animation API to ensure the robot calls are being made from the correct thread. See https://stackoverflow.com/a/60685975/2189127 for details.

Here's a version that properly detects the key press. I have commented out the code that is broken but that is unrelated to the question.

public class AutoClicker extends Application {
    private int minCps;
    private int maxCps;
    private Thread clickThread;
    private boolean running = false;
    private boolean paused = false;
    private Random random = new Random();
    private KeyCode triggerKey = KeyCode.UNDEFINED;
    private TextField minCpsField;
    private TextField maxCpsField;
    private Button startButton;
    private Button stopButton;
    private Button chooseKeyButton;
    private Label keyLabel;

    public AutoClicker() {
    }

    @Override
    public void start(Stage primaryStage) throws Exception {
        minCpsField = new TextField();
        maxCpsField = new TextField();
        chooseKeyButton = new Button("Choose key");
        keyLabel = new Label("Key: not chosen");

        EventHandler<KeyEvent> keyEventEventHandler = event -> {
            if (event.getCode() == triggerKey) {
                if (!running) {
                    if (minCpsField.getText().isEmpty() || maxCpsField.getText().isEmpty()) {
                        keyLabel.setText("Please set the min and max CPS values before starting the autoclick");
                    } else {
                        minCps = Integer.parseInt(minCpsField.getText());
                        maxCps = Integer.parseInt(maxCpsField.getText());
                        start(triggerKey);
                    }
                } else {
                    if (!paused) {
                        pause();
                    } else {
                        resume();
                    }
                }
            }
        };

        chooseKeyButton.setOnAction(e -> {
            keyLabel.setText("Press a key to choose as trigger");
            primaryStage.getScene().setOnKeyPressed(event -> {
                if (event.isControlDown() || event.isAltDown() || event.isShiftDown()) {
                    keyLabel.setText("Please choose a key that is not already in use by the operating system or other applications");
                } else {
                    triggerKey = event.getCode();
                    keyLabel.setText("Key: "   triggerKey);
                    primaryStage.getScene().setOnKeyPressed(keyEventEventHandler);
                }
            });
        });

        HBox minCpsBox = new HBox(new Label("Min CPS: "), minCpsField);
        HBox maxCpsBox = new HBox(new Label("Max CPS: "), maxCpsField);
        HBox keyBox = new HBox(chooseKeyButton, keyLabel);
        VBox root = new VBox(minCpsBox, maxCpsBox, keyBox);

        Scene scene = new Scene(root, 300, 250);

        primaryStage.setScene(scene);
        primaryStage.show();



        primaryStage.getScene().setOnKeyReleased(event -> {
            if (event.getCode().equals(triggerKey)) {
                if (running) {
                    pause();
                }
            }
        });
    }

    public void start(KeyCode triggerKey) {
        this.triggerKey = triggerKey;
        running = true;
        System.out.println("Start...");

        // Replace all this code with Animation API and JAvaFX Robot

//        clickThread = new Thread(() -> {
//            while (running) {
//                while (!paused) {
//                    try {
//                        int delay = 1000 / (random.nextInt(maxCps - minCps   1)   minCps);
//                        Thread.sleep(delay);
//
//                        Robot robot = new Robot();
//                        robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
//                        robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
//                    } catch (InterruptedException | AWTException e) {
//                        e.printStackTrace();
//                    }
//                }
//            }
//        });
//        clickThread.start();
    }


    // Similarly, use Animation API to control the pause/resume functionality:

    public void stop() {
//        running = false;
//        paused = false;
//        clickThread = null;
    }

    public void pause() {
//        paused = true;
    }

    public void resume() {
//        paused = false;
    }
}
  • Related