我正在创建一个自动点击程序。它可能需要一些修复,但我有一个主要问题:当我按下定义的键时,我的程序没有检测到,所以它没有开始单击。
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;
}
}
一开始我做了几种类型的检查,以了解触摸是否定义良好,然后考虑。我试图在start方法中添加triggerKey
参数;我还用开始/停止按钮进行了测试,这些按钮仍然存在于我的代码中,但这使我能够看到我的自动点击是否点击得很好(是的,它确实点击得很好,我做了一个正确的方程,它实现了理论上我想要的点击次数,因为我目前不能100%测试它)。
当autoclick单击时,我制作了一个控制台消息,但是没有发送控制台消息,因此autoclick不起作用,我在处理使用Robot类的行之后的点击的循环中制作了它
选择键的事件处理程序;Button将场景的按键处理程序设置为null,因此不会检测到进一步的按键。将您需要的事件处理程序放在一个变量中,并从那里设置它。
请注意,您不应该将JavaFX和AWT混合使用:使用JavaFX Robot而不是AWT Robot,并且您应该用动画API替换线程代码,以确保机器人调用是从正确的线程进行的。详见https://stackoverflow.com/a/60685975/2189127
这是一个正确检测按键的版本。我已经注释掉了被破坏的代码,但这与问题无关。
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;
}
}