提问人:perimosocordiae 提问时间:10/5/2008 最后编辑:skaffmanperimosocordiae 更新时间:3/5/2012 访问量:5460
模拟 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?
答:
我曾经制作过一个可以通过命令行或使用 GUI 运行的应用程序。
我这样做的方法是定义一个接口(名为 IODevice),它定义了以下方法:
然后,我有两个类实现了这个接口 - 一个使用主机的终端(就像你现在所做的那样),另一个使用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 实现可以为每个逻辑操作使用适当的对话框,而不仅仅是一个实际上只是命令行版本的文本区域。
此外,这更容易编写单元测试,因为在测试中,您可以以任何方式存根这些例程。
这是可能的 - 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 模式下完全切断流。
评论