【发布时间】:2019-01-30 06:58:58
【问题描述】:
我在这里和其他地方对这个问题的主题进行了一些研究,我发现了 jline3,它似乎是一个明确的解决方案,并提供了大量重要的跨平台优势和功能。
但是,为了更好地理解 Java 如何使用流读取器和输入(包括原始字节),以及在 Linux 终端中实现基本的基于文本的冒险游戏,我希望能够抑制或根据用户输入从stdin 中删除箭头键转义码。
这似乎无法通过Scanner 实现,而且我不确定如何使用 Java 将终端置于原始输入模式 - 如果有办法通过 shell 脚本实现它,我'到目前为止,我一直无法弄清楚。我正在使用一个基本的 shell 脚本来调用我的 Java 程序并传入一些系统属性,所以这也是一个很好的解决方案。
到目前为止,我已经使用了ByteBuffer、CharBuffer、Decoder 等的组合,我从其他问题和一些初步研究中看到了这些,但无法实现我的目标'我正在寻找。
我怎样才能让我的 Java 程序等待用户输入而不显示或捕获箭头键转义字符(例如,^[[A、^[[B)?
感谢您提供任何帮助或其他资源。
编辑/更新:
感谢所有对此问题的回复。最终,我正在研究一个几乎完全符合我想要的解决方案,它结合了 Java Console 类及其正则表达式功能。
一个非常基本的框架如下。本质上,我选择了 exclude all, include some 方法,其中所有字符都被禁止,但我编译成 Pattern 的字符允许打印到屏幕上。
这也让我可以测试其他重要的输入键,例如 Enter 以进入和退出游戏的 命令模式,因为我希望游戏对“移动”键做出反应并让用户能够按 Enter 并输入一些命令。
我不得不摆弄stty 以允许这个解决方案,并且Java 应用程序是通过一个bash 脚本启动的。
Bash 脚本:
#!/bin/bash
# Save current terminal settings
STTY_SAVE=$(stty -g)
# Disable need to press [Enter] in order to have input processed
stty cbreak
# Disable the echoing of input
stty -echo
# Tell the terminal that erasure on the console should produce a backspace cursor movement
stty erase ^H
# Execute application
java reader_testing.Main
# Restore saved terminal settings
stty $STTY_SAVE
exit 0
注意:stty erase ^H 似乎也允许 Java 中的 Console 在 *nix 操作系统上捕获退格键字符代码 \010。如果没有该行,它似乎会执行删除(?)
Java 代码:
Console console = System.console();
int symbol = 0;
char character = 0;
String matchString = new String();
StringBuilder input = new StringBuilder();
Pattern allowed = Pattern.compile( "[a-z0-9 !@#$%^&*()_+-=]" );
Matcher matcher = null;
while ( true ) { // This is an arbitrary loop for the example
try {
symbol = console.reader().read();
if ( symbol == 10 ) { // 10 = Enter
break;
}
character = (char) symbol;
matchString = Character.toString( character );
matcher = allowed.matcher( matchString );
if ( matcher.find() ) {
input.append( character );
System.out.print( "\r" + input );
}
} catch ( IOException e ) {
e.printStackTrace();
}
}
System.out.println( "\nYou entered: " + input );
问题:
-
仍在研究退格功能,用“空”字符(例如,
李>char c = 0;)重写输入StringBuilder对象的字符并调整其大小。这最终可能根本不起作用。 我无法找到一种方法来排除大写字母 A、B、C 和 Ds,它们遵循代表箭头键的转义码序列,因此我不得不禁止所有大写字母。我试图等到阅读器检测不到更多输入,然后解析该输入,但未能成功实现。
Insert 和 Delete 等特殊键生成的字符代码包括仍会打印的数字。我还不确定如何在不禁止数字的情况下防止这种情况发生(与箭头键和大写字母的问题相同)。
最后,这些都可能不起作用或者会受到相当的限制,但是玩这个很有趣,如果情况更糟,我可以让退格键清除整个输入字符串。输入命令不是游戏的主要方面。
【问题讨论】: