Java 控制台在用户键入时打印文本

标签 java console

在所有其他控制台应用程序中,我们必须在用户仍在输入内容(例如聊天、服务器控制台等)时打印文本。 我的问题是: 如何在不破坏格式的情况下在用户键入时打印文本?

例子:

玩家 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/

相关文章:

c++ - 无法在 C++ 中使用 ReadConsoleInput 读取鼠标事件

java - 如何从 Google App Engine 应用程序的后端模块注册任务队列

java - Android: LAME 将 AudioRecoder 的 PCM 数据转换为 MP3,但 MP3 文件有一些噪音

java - 在 Java 中确定美国 ZoneIds 的夏令时

java - 添加时间我不知道如何添加

c# - 控制台上的 WriteLine 但采用复古风格

R在控制台中显示两个堆叠的进度条(带代码)

java - 如何从 URL 调用 JAX-WS 方法

c# - 用 C# 编写控制台包装器?

qt - 在 Qt 中异步运行控制台输出和 GUI