好友
阅读权限 10
听众
最后登录 1970-1-1
本帖最后由 feiMathRandom 于 2025-8-5 17:48 编辑
主要是解决那些 不给粘贴密码的输入框 使用的。
[Java] 纯文本查看 复制代码
public class KeyboardSimulatorApp extends Application {
private TextArea contentArea;
private Button startButton;
private Button stopButton;
private Label statusLabel;
private AtomicBoolean isRunning = new AtomicBoolean(false);
private Thread simulationThread;
private Robot robot;
// 特殊字符映射表
private static final Map<Character, Integer> charToKeyCode = new HashMap<>();
private static final Map<Character, Boolean> charRequiresShift = new HashMap<>();
static {
// 初始化字符到虚拟键码的映射
for (char c = 'a'; c <= 'z'; c++) {
charToKeyCode.put(c, KeyEvent.getExtendedKeyCodeForChar(c));
charRequiresShift.put(c, false);
}
for (char c = 'A'; c <= 'Z'; c++) {
charToKeyCode.put(c, KeyEvent.getExtendedKeyCodeForChar(Character.toLowerCase(c)));
charRequiresShift.put(c, true);
}
for (char c = '0'; c <= '9'; c++) {
charToKeyCode.put(c, KeyEvent.getExtendedKeyCodeForChar(c));
charRequiresShift.put(c, false);
}
// 特殊字符映射(美式键盘布局)
addSpecialChar(' ', KeyEvent.VK_SPACE, false);
addSpecialChar('!', KeyEvent.VK_1, true);
addSpecialChar('@', KeyEvent.VK_2, true);
addSpecialChar('#', KeyEvent.VK_3, true);
addSpecialChar('$', KeyEvent.VK_4, true);
addSpecialChar('%', KeyEvent.VK_5, true);
addSpecialChar('^', KeyEvent.VK_6, true);
addSpecialChar('&', KeyEvent.VK_7, true);
addSpecialChar('*', KeyEvent.VK_8, true);
addSpecialChar('(', KeyEvent.VK_9, true);
addSpecialChar(')', KeyEvent.VK_0, true);
addSpecialChar('-', KeyEvent.VK_MINUS, false);
addSpecialChar('_', KeyEvent.VK_MINUS, true);
addSpecialChar('=', KeyEvent.VK_EQUALS, false);
addSpecialChar('+', KeyEvent.VK_EQUALS, true);
addSpecialChar('[', KeyEvent.VK_OPEN_BRACKET, false);
addSpecialChar('{', KeyEvent.VK_OPEN_BRACKET, true);
addSpecialChar(']', KeyEvent.VK_CLOSE_BRACKET, false);
addSpecialChar('}', KeyEvent.VK_CLOSE_BRACKET, true);
addSpecialChar(';', KeyEvent.VK_SEMICOLON, false);
addSpecialChar(':', KeyEvent.VK_SEMICOLON, true);
addSpecialChar('\'', KeyEvent.VK_QUOTE, false);
addSpecialChar('\"', KeyEvent.VK_QUOTE, true);
addSpecialChar('\\', KeyEvent.VK_BACK_SLASH, false);
addSpecialChar('|', KeyEvent.VK_BACK_SLASH, true);
addSpecialChar(',', KeyEvent.VK_COMMA, false);
addSpecialChar('<', KeyEvent.VK_COMMA, true);
addSpecialChar('.', KeyEvent.VK_PERIOD, false);
addSpecialChar('>', KeyEvent.VK_PERIOD, true);
addSpecialChar('/', KeyEvent.VK_SLASH, false);
addSpecialChar('?', KeyEvent.VK_SLASH, true);
addSpecialChar('`', KeyEvent.VK_BACK_QUOTE, false);
addSpecialChar('~', KeyEvent.VK_BACK_QUOTE, true);
}
private static void addSpecialChar(char ch, int keyCode, boolean requiresShift) {
charToKeyCode.put(ch, keyCode);
charRequiresShift.put(ch, requiresShift);
}
@Override
public void start(Stage primaryStage) {
try {
robot = new Robot();
robot.setAutoDelay(10);
} catch (AWTException e) {
showErrorAlert("系统支持错误", "无法创建系统键盘模拟器", "请确保应用程序有适当的系统权限");
System.exit(1);
}
// 创建UI组件
VBox root = new VBox(15);
root.setPadding(new Insets(20));
root.setStyle("-fx-background-color: #f5f7fa;");
Label titleLabel = new Label("系统键盘输入模拟器");
titleLabel.setFont(Font.font(22));
titleLabel.setTextFill(Color.DARKBLUE);
contentArea = new TextArea();
contentArea.setPromptText("输入要模拟的内容(支持所有字符)...");
contentArea.textProperty().addListener((obs, oldValue, newValue) -> {
if (!newValue.matches("[\u0000-\u007F]*")) {
contentArea.setText(oldValue);
}
});
contentArea.setWrapText(true);
contentArea.setPrefRowCount(10);
contentArea.setFont(Font.font("Consolas", 14));
contentArea.setStyle("-fx-border-color: #ccc; -fx-border-radius: 5;");
// 状态标签
statusLabel = new Label("就绪");
statusLabel.setFont(Font.font(14));
statusLabel.setTextFill(Color.GRAY);
// 按钮区域
HBox buttonBox = new HBox(15);
buttonBox.setAlignment(javafx.geometry.Pos.CENTER);
startButton = new Button("开始模拟");
startButton.setStyle("-fx-background-color: #4CAF50; -fx-text-fill: white; -fx-font-weight: bold;");
startButton.setPrefSize(120, 40);
startButton.setFont(Font.font(14));
startButton.setOnAction(e -> startSimulation());
stopButton = new Button("停止模拟");
stopButton.setStyle("-fx-background-color: #f44336; -fx-text-fill: white; -fx-font-weight: bold;");
stopButton.setPrefSize(120, 40);
stopButton.setFont(Font.font(14));
stopButton.setDisable(true);
stopButton.setOnAction(e -> stopSimulation());
buttonBox.getChildren().addAll(startButton, stopButton);
// 信息面板
VBox infoBox = new VBox(10);
infoBox.setStyle("-fx-background-color: #e3f2fd; -fx-border-radius: 5; -fx-padding: 15;");
Label infoTitle = new Label("使用说明:");
infoTitle.setFont(Font.font(16));
Label info1 = new Label("1. 在文本区域输入需要模拟的内容");
Label info2 = new Label("2. 点击" + startButton.getText() + "按钮");
Label info3 = new Label("3. 在5秒内切换到目标应用程序");
Label info4 = new Label("4. 系统将自动将文本输入到目标应用");
Label info5 = new Label("5. 按" + stopButton.getText() + "可随时停止模拟");
infoBox.getChildren().addAll(infoTitle, info1, info2, info3, info4, info5);
// 添加所有组件到根容器
root.getChildren().addAll(titleLabel, contentArea, buttonBox, statusLabel, infoBox);
Scene scene = new Scene(root, 650, 550);
// 添加快捷键
scene.setOnKeyPressed(e -> {
if (e.isControlDown() && e.getCode() == javafx.scene.input.KeyCode.ENTER) {
if (!isRunning.get()) {
startSimulation();
}
} else if (e.getCode() == javafx.scene.input.KeyCode.ESCAPE) {
if (isRunning.get()) {
stopSimulation();
}
}
});
primaryStage.setTitle("键盘输入模拟器 v2.0");
primaryStage.setScene(scene);
primaryStage.show();
}
private void startSimulation() {
String content = contentArea.getText().trim();
if (content.isEmpty()) {
showErrorAlert("输入错误", "内容为空", "请输入要模拟的内容");
return;
}
statusLabel.setText("模拟即将开始 - 请切换到目标应用的输入框");
statusLabel.setTextFill(Color.DARKBLUE);
startButton.setDisable(true);
stopButton.setDisable(false);
isRunning.set(true);
simulationThread = new Thread(() -> {
try {
// 等待用户切换到目标应用程序
Thread.sleep(5000);
statusLabel.setText("正在模拟输入...");
statusLabel.setTextFill(Color.DARKGREEN);
// 模拟输入
for (char c : content.toCharArray()) {
if (!isRunning.get()) break;
if (c == '\n') {
typeKey(KeyEvent.VK_ENTER);
} else if (c == '\t') {
typeKey(KeyEvent.VK_TAB);
} else {
// 特殊字符处理
Character keyChar = Character.valueOf(c);
if (charToKeyCode.containsKey(keyChar)) {
int keyCode = charToKeyCode.get(keyChar);
boolean requiresShift = charRequiresShift.getOrDefault(keyChar, false);
if (requiresShift) {
robot.keyPress(KeyEvent.VK_SHIFT);
}
typeKey(keyCode);
if (requiresShift) {
robot.keyRelease(KeyEvent.VK_SHIFT);
}
} else {
// 对于未识别的字符,尝试直接输入
String charStr = String.valueOf(c);
if (!charStr.matches("\\p{Print}")) {
continue; // 跳过不可打印字符
}
typeKey(KeyEvent.getExtendedKeyCodeForChar(c));
}
}
// 按键之间的随机延迟(40-180毫秒),使输入更真实
Thread.sleep(40 + (int)(Math.random() * 140));
}
} catch (InterruptedException e) {
// 正常中断
} finally {
Platform.runLater(() -> {
statusLabel.setText("模拟已完成");
statusLabel.setTextFill(Color.GRAY);
startButton.setDisable(false);
stopButton.setDisable(true);
isRunning.set(false);
});
}
});
simulationThread.setDaemon(true);
simulationThread.start();
}
private void stopSimulation() {
isRunning.set(false);
if (simulationThread != null && simulationThread.isAlive()) {
simulationThread.interrupt();
}
statusLabel.setText("模拟已停止");
statusLabel.setTextFill(Color.DARKRED);
startButton.setDisable(false);
stopButton.setDisable(true);
}
private void typeKey(int keyCode) {
try {
robot.keyPress(keyCode);
robot.keyRelease(keyCode);
} catch (Exception e) {
// 忽略键码错误
}
}
private void showErrorAlert(String title, String header, String content) {
Platform.runLater(() -> {
Alert alert = new Alert(Alert.AlertType.ERROR);
alert.setTitle(title);
alert.setHeaderText(header);
alert.setContentText(content);
alert.showAndWait();
});
}
public static void main(String[] args) {
launch(args);
}
}
下载地址.txt
50 Bytes, 下载次数: 24, 下载积分: 吾爱币 -1 CB
免费评分
查看全部评分