[英]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),该接口定义了以下方法:
然后,我有两个实现该接口的类-一个使用主机的终端(就像您现在所做的那样),另一个使用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.