吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 2569|回复: 30
收起左侧

[Java 原创] 键盘模拟输入小工具

  [复制链接]
feiMathRandom 发表于 2025-8-4 18:03
本帖最后由 feiMathRandom 于 2025-8-5 17:48 编辑

主要是解决那些 不给粘贴密码的输入框 使用的。



模拟输入.gif

image.png
image.png

[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

免费评分

参与人数 4吾爱币 +9 热心值 +4 收起 理由
wanfon + 1 + 1 热心回复!
grrr_zhao + 1 + 1 谢谢@Thanks!
kotsc159 + 1 谢谢@Thanks!
hrh123 + 7 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!

查看全部评分

本帖被以下淘专辑推荐:

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

linfzz 发表于 2025-8-4 19:44
对单条输入来说用处不大。如果可以存储多个输入文本,可能有用。同时有泄露密码的风险。
wx0647 发表于 2025-8-5 16:37
java.lang.ClassNotFoundException: vip.hntool.keyboard.KeyboardSimulatorApp
        at java.net.URLClassLoader.findClass(URLClassLoader.java:387)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:418)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:355)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:351)
        at com.exe4j.runtime.LauncherEngine.launch(LauncherEngine.java:80)
        at com.exe4j.runtime.WinLauncher.main(WinLauncher.java:94)
exe运行报错,这是怎么回事
xoxoi 发表于 2025-8-4 20:11
mdgzs 发表于 2025-8-4 20:24
还行,有用
afti 发表于 2025-8-4 21:27
这样很方便
MylogosXx 发表于 2025-8-4 21:33
看不懂,可以说下用途吗?
kotsc159 发表于 2025-8-4 21:53

对单条输入来说用处不大。如果可以存储多个输入文本,可能有用。同时有泄露密码的风险。
HRong 发表于 2025-8-4 22:52
要装JAVA才能用吗?
空中的云 发表于 2025-8-4 23:46
和序列号辅助输入功能差不多。那个好像功能更多一点,可以借鉴一下。
火焰加鲁鲁 发表于 2025-8-5 00:55
感谢楼主分享,请问楼主有成品么
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - 52pojie.cn ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2026-5-8 22:25

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表