0

I have 2 threads, one that waits for user input with nextLine, the other that writes to stdout. This is a demo example:

package com.ricvail.example;
import java.util.Scanner;
import java.util.Timer;
import java.util.TimerTask;
public class App {
    public static void main( String[] args )
    {
        Timer t = new Timer();
        t.scheduleAtFixedRate(new TimerTask() {
            @Override
            public void run() {
                System.out.print("This will interrupt the user while he's typing");
            }
        }, 5000, 5000);
        boolean exitLoop=false;
        Scanner stdin = new Scanner(System.in);
        while (!exitLoop){
            String inputLine = stdin.nextLine();
            System.out.println("Echoing: "+ inputLine);
        }
    }
    public int asd(){
        return 3;
    }
}

How can I modify the println() and nextLine() statements so that the first does not interfere with the second?
I mean, right now if I try to write "Hello, I'm typing something" that's what happens:

Hello, I'm tyThis will interrupt the user while he's typingping something
Echoing: ping something
This will interrupt the user while he's typing

I would like to be able to read what the user has been typing so far, erase his line, replace it with the println, and then write back the user input on stdIn. I think curses might help me but I'm not allowed to use external libraries, is there a way to do it with plain java?

  • Err, synchronization? But probably this is out of your control, and Java's. – user207421 Jul 04 '17 at 09:43
  • in eclipse as example, i think its not possible to remove and store what is written inside the console. – XtremeBaumer Jul 04 '17 at 09:45
  • I wonder if you could achieve it by using \b character (backspace) – Joel Jul 04 '17 at 09:53
  • @EJP Can you maybe be a bit more specific? The only way I can think of using synchronization is to wait to present the output until the user has finished typing, but of course this is not the behaviour I'm looking for since what is written by the timer in this example actually comes from a server and needs to be read by the user in real time – Riccardo Vailati Jul 04 '17 at 09:59
  • @Joel actually I used the \r character, and yes it seems to be part of the solution, but I still don't know how to "write to stdin" – Riccardo Vailati Jul 04 '17 at 10:07
  • I don't believe what you're trying to do is possible (at least not using this fundamental approach). Although you could synchronise two threads to enable one to erase it's output, wait for a message to be printed, and then reprint what had been input so far, you just can't do this with stdin. The basic problem is that stdin waits for return to be pressed before returning the input. There's no way to access the backing buffer before that, which is what you would need. – Speakjava Jul 04 '17 at 10:10
  • Anyway what you're trying to do seems very weird. I don't know what's the whole point of that, but maybe you could try a different approach to achieve your high-level goal. – Joel Jul 04 '17 at 10:13
  • I just spent some time trying to make this work and the problem boils down to the fact that you need the console (and thus stdin and System.in) to be in raw mode rather than cooked. In raw mode you could access each character as it is typed, rather than having to wait for return to be pressed. There is no platform independent way of doing this, see https://stackoverflow.com/questions/1066318/how-to-read-a-single-char-from-the-console-in-java-as-the-user-types-it. – Speakjava Jul 04 '17 at 10:55

0 Answers0