模拟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.最简单的替代方法是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模式下完全切断流。

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

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

假设您有许多类似给定示例的操作,您可能会考虑Richie_W描述的接口方法,但每个操作只生成一个例程,而不是通用的"输入/输出"方法。

例如:

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

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

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

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

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

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

    也许你可以做一些类似的事情——要更改所使用的输入设备,只需更改IODevice的实例。


    希望这个有用。

    相关内容

    • 没有找到相关文章

    最新更新