用户类型时Java控制台打印文本

时间:2014-06-17 14:37:17

标签: java console

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

示例:

PlayerA加入游戏,而PlayerB仍在键入测试消息。而不是:

  

PlayerA加入了游戏   [提示]测试消息

看起来像这样:

  

[prompt] testmePlayerA加入了游戏   ssage

我使用System.out.println()和System.console()。readLine()测试了不同的场景,但它仍然无法正常工作。它需要一些奇怪的,hacky的解决方法还是有更好的解决方案?

1 个答案:

答案 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 + '}';
        }        
    }
}