在所有其他控制台应用程序中,我们必须在用户仍在输入内容(例如聊天、服务器控制台等)时打印文本。 我的问题是: 如何在不破坏格式的情况下在用户键入时打印文本?
例子:
玩家 A 加入游戏,而玩家 B 仍在输入测试消息。而不是这个:
PlayerA joined the game.
[prompt]testmessage
看起来像这样:
[prompt]testmePlayerA joined the game
ssage
我测试了不同的场景,使用 System.out.println() 和 System.console().readLine(),但它仍然不起作用。它需要一些奇怪的、棘手的解决方法还是有更好的解决方案?
最佳答案
假设您正在运行 Windows 并且有 JNA , 以下代码将允许您确定控制台是否已准备好打印。
用法:
每次打印到控制台或从控制台读取后调用 WinConsoleUtils.updatePos()
。调用 WinConsoleUtils.isReadytoWrite()
以确定控制台是否准备好打印。如果它返回 true,那么您可以在不破坏用户输入的情况下打印到控制台。您将不得不反复轮询以确定控制台是否已准备好写入。如果要检索光标的当前位置,请调用 WinConsoleUtils.getCursorPoition()
。
import com.sun.jna.Native;
import com.sun.jna.Pointer;
import java.awt.Point;
public class WinConsoleUtils {
private final static Kernel32 INSTANCE = (Kernel32) Native.loadLibrary("Kernel32", Kernel32.class);
private static final Pointer STDIN= INSTANCE.GetStdHandle(-11);
private static Point LAST_POS= new Point();
public static Point getCursorPosition(){
Kernel32.CONSOLE_SCREEN_BUFFER_INFO info = new Kernel32.CONSOLE_SCREEN_BUFFER_INFO();
INSTANCE.GetConsoleScreenBufferInfo(STDIN,info);
Point pos = new Point(info.dwCursorPosition.X,info.dwCursorPosition.Y);
return pos;
}
public static void updatePos(){
LAST_POS = getCursorPosition();
}
public static boolean isReadytoWrite(){
return LAST_POS.equals(getCursorPosition());
}
}
和
import com.sun.jna.Library;
import com.sun.jna.Pointer;
import com.sun.jna.Structure;
import java.util.Arrays;
import java.util.List;
public interface Kernel32 extends Library{
public boolean GetConsoleScreenBufferInfo(Pointer hConsoleOutput, CONSOLE_SCREEN_BUFFER_INFO lpConsoleScreenBufferInfo);
public Pointer GetStdHandle(int i);
public static class CONSOLE_SCREEN_BUFFER_INFO extends Structure {
public COORD dwSize, dwCursorPosition;
public short wAttributes;
public SMALL_RECT srWindow;
public COORD dwMaximumWindowSize;
@Override
protected List getFieldOrder() {
return Arrays.asList(new String[]{"dwSize","dwCursorPosition","wAttributes","srWindow","dwMaximumWindowSize"});
}
@Override
public String toString() {
return "CONSOLE_SCREEN_BUFFER_INFO{" + "dwSize=" + dwSize + ", dwCursorPosition=" + dwCursorPosition + ", wAttributes=" + wAttributes + ", srWindow=" + srWindow + ", dwMaximumWindowSize=" + dwMaximumWindowSize + '}';
}
}
public static class COORD extends Structure {
public short X, Y;
@Override
protected List getFieldOrder() {
return Arrays.asList(new String[]{"X","Y"});
}
@Override
public String toString() {
return "COORD{" + "X=" + X + ", Y=" + Y + '}';
}
}
public static class SMALL_RECT extends Structure {
public short Left, Top, Right, Bottom;
@Override
protected List getFieldOrder() {
return Arrays.asList(new String[]{"Left","Top","Right","Bottom"});
}
@Override
public String toString() {
return "SMALL_RECT{" + "Left=" + Left + ", Top=" + Top + ", Right=" + Right + ", Bottom=" + Bottom + '}';
}
}
}
关于Java 控制台在用户键入时打印文本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24266629/