简体   繁体   中英

Java console print text while user types

In every other console application, we have to print text while the user still types something in (eg a chat, a server console etc). My question is: How can one print text while the user is typing without destroying the format?

Example:

PlayerA joins the game while PlayerB is still typing a testmessage. Instead of this:

PlayerA joined the game.
[prompt]testmessage

it looks like this:

[prompt]testmePlayerA joined the game
ssage

I tested different scenarios, with System.out.println() and System.console().readLine(), but it still doesn't work. Does it need some weird, hacky workaround or is there a better solution?

Provided you are running windows and have JNA , the following code will allow you to determine if the Console is ready to print.

Usage:

Call WinConsoleUtils.updatePos() each time after you print to the console or read from the console. Call WinConsoleUtils.isReadytoWrite() to determine if the console is ready to print or not. If it returns true, then you can print to the console without destroying the user's input. You will have to repeatedly poll to determine if the console is ready to write to yet. If you want to retrieve the current position of the cursor call 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());
    }
}

and

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM