在所有其他控制台应用程序中,我们必须在用户仍然输入内容时打印文本(例如聊天,服务器控制台等)。 我的问题是: 如何在用户输入时打印文本而不破坏格式?
示例:
PlayerA加入游戏,而PlayerB仍在键入测试消息。而不是:
PlayerA加入了游戏 [提示]测试消息
看起来像这样:
[prompt] testmePlayerA加入了游戏 ssage
我使用System.out.println()和System.console()。readLine()测试了不同的场景,但它仍然无法正常工作。它需要一些奇怪的,hacky的解决方法还是有更好的解决方案?
答案 0 :(得分:0)
如果您正在运行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 + '}';
}
}
}