繁体   English   中英

模拟java.util.Scanner的用户输入

[英]Emulating user input for java.util.Scanner

我正在用Java编写游戏,我希望用户能够从命令行和GUI提供输入。 当前,我使用此方法获取输入:

    static String getInput(){
        System.out.println("Your move:");
        Scanner sc = new Scanner(System.in);
        return sc.nextLine();
    }

我想继续使用它,但让mousePressed事件也可以模拟用户实际在其输入中输入的内容。 解决方案的效率并不高,但是在我的应用程序中才有意义。 所以问题是:如何模拟从代码端键入System.in的用户?

这是可能的-System.in的最简单替代是PipedInputStream 这必须与从另一个线程(在本例中为Swing线程)写入的PipedOutputStream挂钩。

public class GameInput {

    private Scanner scanner;

    /**CLI constructor*/
    public GameInput() {
        scanner = new Scanner(System.in);
    }

    /**GUI constructor*/
    public GameInput(PipedOutputStream out) throws IOException {
        InputStream in = new PipedInputStream(out);
        scanner = new Scanner(in);
    }

    public String getInput() {
        return scanner.nextLine();
    }

    public static void main(String[] args) throws IOException {
        GameInput gameInput;

        PipedOutputStream output = new PipedOutputStream();
        final PrintWriter writer = new PrintWriter(output);
        gameInput = new GameInput(output);

        final JTextField textField = new JTextField(30);
        final JButton button = new JButton("OK");
        button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                String data = textField.getText();
                writer.println(data);
                writer.flush();
            }
        });

        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().setLayout(new FlowLayout());
        frame.getContentPane().add(textField);
        frame.getContentPane().add(button);
        frame.pack();
        frame.setVisible(true);

        String data = gameInput.getInput();
        System.out.println("Input=" + data);
        System.exit(0);
    }

}

但是,最好重新考虑游戏逻辑,以在GUI模式下完全切断流。

我制作了一个可以通过命令行或使用GUI运行的应用程序。
我这样做的方法是定义一个接口(名为IODevice),该接口定义了以下方法:

  • 公共字符串getInput();
  • 公共无效的showOutput(String output);

  • 然后,我有两个实现该接口的类-一个使用主机的终端(就像您现在所做的那样),另一个使用JTextArea(输出)/ JOptionPane(输入)。

    也许您可以做类似的事情-要更改使用的输入设备,只需更改IODevice的实例。


    希望这是有用的。

    老实说,在重读您的问题后,我不确定您想要什么。

    无论如何,也许您需要检出java.lang.System.setIn(InputStream in)方法。 这将允许您更改用于从终端读取输入的阅读器(即,将其从实际终端更改为您喜欢的任何内容)

    假设您有许多像给定示例一样的操作,则可以考虑Richie_W描述的接口方法,但是每个操作只创建一个例程,而不是通用的“输入/输出”方法。

    例如:

    public interface IGameInteraction
    {
        public String askForMove( String prompt );
        public boolean askAreYouSure( String prompt );
    }
    

    您的命令行实现很清晰; 现在,您的GUI实现可以为每个逻辑操作使用一个适当的对话框,而不仅仅是一个文本区域,而该文本区域实际上只是命令行版本。

    此外,这更易于编写单元测试,因为您可以在测试中以任何方式将这些例程存根。

    暂无
    暂无

    声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

     
    粤ICP备18138465号  © 2020-2024 STACKOOM.COM