【问题标题】:How am I supposed to reduce 100 lines code to fewer? (Java robot)我应该如何将 100 行代码减少到更少? (Java机器人)
【发布时间】:2019-03-14 16:02:29
【问题描述】:

所以我制作了一个 javafx 应用程序来存储文本,你可以选择你希望程序输入的文本(用于游戏设置绑定)

我有这个:

public class AutoClicker {

private Robot robot;

public AutoClicker() {
    try {
        robot = new Robot();
    } catch (AWTException ex) {
        System.out.println("Problem in AutoClicker constructor: " + ex);
    }
}

public void click(int button) {
    robot.keyPress(button);
    robot.delay(10);
    robot.keyRelease(button);
}

public void oneModifier(int pressing, int button) {
    robot.keyPress(pressing);
    robot.delay(10);
    robot.keyPress(button);
    robot.delay(10);
    robot.keyRelease(button);
    robot.delay(10);
    robot.keyRelease(pressing);
    robot.delay(10);

}

public void twoModifier(int pressing1, int pressing2, int button) {
    robot.keyPress(pressing1);
    robot.delay(10);
    robot.keyPress(pressing2);
    robot.delay(10);
    robot.keyPress(button);
    robot.delay(10);
    robot.keyRelease(button);
    robot.delay(10);
    robot.keyRelease(pressing2);
    robot.delay(10);
    robot.keyRelease(pressing1);
    robot.delay(10);

}

public void clickingENG(String tmp) {

    int length = tmp.length();
    int[] text = new int[length];

    for (int i = 0; i < length; i++) {
        text[i] = tmp.charAt(i);
    }

    for (int i = 0; i < text.length; i++) {
        switch (text[i]) {
            case ' ':
                click(KeyEvent.VK_SPACE);
                break;
            case '.':
                click(KeyEvent.VK_PERIOD);
                break;
            case '"':
                oneModifier(KeyEvent.VK_SHIFT, KeyEvent.VK_QUOTE);
                break;
            case '/':
                click(KeyEvent.VK_SLASH);
                break;
            case '\\':
                click(KeyEvent.VK_BACK_SLASH);
                break;
            case '+':
                oneModifier(KeyEvent.VK_SHIFT, KeyEvent.VK_EQUALS);
                break;
            case '!':
                oneModifier(KeyEvent.VK_SHIFT, KeyEvent.VK_1);
                break;
            case '0':
                click(KeyEvent.VK_0);
                break;
            case '1':
                click(KeyEvent.VK_1);
                break;
            case '2':
                click(KeyEvent.VK_2);
                break;
            case '3':
                click(KeyEvent.VK_3);
                break;
            case '4':
                click(KeyEvent.VK_4);
                break;
            case '5':
                click(KeyEvent.VK_5);
                break;
            case '6':
                click(KeyEvent.VK_6);
                break;
            case '7':
                click(KeyEvent.VK_7);
                break;
            case '8':
                click(KeyEvent.VK_8);
                break;
            case '9':
                click(KeyEvent.VK_9);
                break;
            default:
                click(text[i] - 32);
                break;
        }
    }
    click(KeyEvent.VK_ENTER);
}
}

您可以看到很多情况...如果我想使用大写...(ABCDEFGHIJKLMON...)我需要另外 26 个情况...不谈论符号...仅此而已案例...这很丑,如果我再做150个案例会更丑,而且要花很多时间...

如果它得到'A',有什么办法我不必做下一个:

case 'A':
  oneModifier(KeyEvent.VK_SHIFT, KeyEvent.VK_A);
  break;

对于“B”:

case 'B':
  oneModifier(KeyEvent.VK_SHIFT, KeyEvent.VK_B);
  break;

【问题讨论】:

  • 您好,欢迎您。你能对你的问题更具体一点吗?这将有助于贡献者更快地了解您的最终目标。
  • 您可以将 char-clickevent 存储在 Hashmap 中,然后查找。
  • 或者只是 click(Character.getNumericValue(text.charAt(i)); 可能会起作用。
  • Hashmap 可能是个好主意,仍然需要输入很多但更少。 Character.getNumericValue 不起作用。很多例外。您的意思是键是“案例”的哈希图,值是...?

标签: java awtrobot


【解决方案1】:

以下是如何缩短动作创建并使用Map 来避免大量的case 构造。

Map 维护“脚本”文件中的实际角色与将要执行的操作之间的映射;我使用现有的Runnable 接口来包装它。

class AutoClicker {

    private Robot robot;
    private final Map<Character, Runnable> runnables = new HashMap<>();

    public AutoClicker() {
        try {
            robot = new Robot();
        } catch (AWTException ex) {
            System.out.println("Problem in AutoClicker constructor: " + ex);
        }
        // fill the map
        runnables.put(' ', click(KeyEvent.VK_SPACE));
        runnables.put('.', click(KeyEvent.VK_PERIOD));
        runnables.put('"', oneModifier(KeyEvent.VK_SHIFT, KeyEvent.VK_QUOTE));
        runnables.put('/', click(KeyEvent.VK_SLASH));
        runnables.put('\\', click(KeyEvent.VK_BACK_SLASH));
        runnables.put('+', oneModifier(KeyEvent.VK_SHIFT, KeyEvent.VK_EQUALS));
        runnables.put('!', oneModifier(KeyEvent.VK_SHIFT, KeyEvent.VK_1));
        // the VK_<X> events are sequential, as are the keys being pressed
        for (int i = 0; i < 10; i++) {
            runnables.put((char) ('0' + i), click(KeyEvent.VK_0 + i));
        }
        // for upper case letters, you can add another for loop starting from 'A'
        // and adding oneModifier(KeyEvent.VK_SHIFT, KeyEvent.VK_A + i) actions
    }

    // create an action. You might want to split that into two methods,
    // one performing the click (without wrapping) and a parameter less.    
    private Runnable wrapInPressAndRelease(int button, Optional<Runnable> wrapped) {
        return () -> {
            robot.keyPress(button);
            robot.delay(10);
            // "click" does not run anything in between press/release,
            // the modified click runs the click itself
            wrapped.ifPresent(Runnable::run);
            robot.keyRelease(button);
            if (wrapped.isPresent()) {
                // why is there delay after modified action?
                robot.delay(10);
            }
        };
    }

    // you can inline those methods, I left them in to retain a connection to your original code
    public Runnable click(int button) {
        return wrapInPressAndRelease(button, Optional.empty());
    }

    public Runnable oneModifier(int pressing, int button) {
        return wrapInPressAndRelease(pressing, Optional.of(click(button)));
    }

    public Runnable twoModifier(int pressing1, int pressing2, int button) {
        // wrap the already wrapped click into another
        return wrapInPressAndRelease(pressing1, Optional.of(oneModifier(pressing2, button)));
    }

    // now we can use the stored actions.
    // not sure why you created the intermediate text int array, I removed that.
    public void clickingENG(String tmp) {

        for (int i = 0; i < tmp.length(); i++) {
            char fromEngine = tmp.charAt(i);
            Runnable robotAction = runnables.getOrDefault(fromEngine,
                    click(fromEngine - 32, Optional.empty()));
            robotAction.run();
        }
        click(KeyEvent.VK_ENTER, Optional.empty()).run();
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-12-09
    • 2021-07-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多