我怎么能减少100行代码? (Java机器人)

问题描述 投票:-1回答:1

所以我创建了一个存储文本的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;
java awtrobot
1个回答
0
投票

所以这里是你如何缩短动作创建和使用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();
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.