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

Emulating user input for java.util.Scanner

提问人:perimosocordiae 提问时间:10/5/2008 最后编辑:skaffmanperimosocordiae 更新时间:3/5/2012 访问量:5460

问:

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

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

我想继续使用它,但让 mousePressed 事件模拟用户实际输入他们的输入。这不是一个有效的解决方案,但它在我的应用程序中是有意义的。那么问题来了:如何模拟用户从代码端打字 System.in?

输入 java.util.scanner

评论


答:

0赞 Richard Walton 10/5/2008 #1

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

  • 公共字符串 getInput();
  • public void showOutput(字符串输出);

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

    也许您可以执行类似操作 - 要更改使用的输入设备,只需更改 IODevice 的实例即可。


    希望这有一些用处。

    0赞 Richard Walton 10/5/2008 #2

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

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

    0赞 Jason Cohen 10/5/2008 #3

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

    例如:

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

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

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

    1赞 McDowell 10/5/2008 #4

    这是可能的 - 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 模式下完全切断流。

    评论

    0赞 perimosocordiae 10/5/2008
    谢谢!这正是我一直在寻找的。你是对的,应该有一种更好的方法来处理用户输入,但我试图得到一些几乎没有空间的东西,可以快速实现错误。花费的时间/精力比我预期的要多......啊,好吧。吸取的教训。