I've a command line application which awaits an user input. I want to display > as the prompt.
This is my code.
while(true){
System.out.print("> ")
// do stuff
}
The problem is that the > displays every time the loop iterates but the cursor blinks at the beginning of the loop, thereby making my > a part of the user input. I want the cursor to be blinking one space after the > everytime the loop iterates and also > not to be a part of the next line object(assuming I'm using a scanner to parse input). Any help appreciated.
If you really worry about "great user experience"; than anything that only uses the "java builtin" console functions ... will not meet that requirement.
So, if that matters to you, I recommend looking into the various libraries that give you "ncurses like" functionality, like charva, java curses or lanterna.
I agree with #Aaron that "> " will not be part of the user's input, you can verify this by adding the lines below just under System.out.print("> ");
String usrInput = new java.util.Scanner(System.in).next();
System.out.println("Your input was " + usrInput);
If you are just asking how to change the while loop to make it blink after the > :
System.out.print(">_");
while(true) {
Thread.sleep(400);
System.out.print("\b ");
Thread.sleep(400);
System.out.print("\b_");
}
I wouldn't recommend to handle input this way, but it will get you the visual effect you are after.
When you use System.out.print or most other output commands, you're actually putting text in stdout / System.out, which your console will check to display said text.
It will not interfere with the user input which is transmitted via the independant stdin / System.in.
The problem is that these buffers are not modifiable, only appendable : once you've written something you can't come back to erase it, so making a prompt blink is not possible this way.
Some console might handle the BACKSPACE 0x08 ascii control character to erase the previous character, but I wouldn't rely on it.
There might be other methods that would grant you a read/write access to the console text buffer, but I doubt using it would be much easier than writing a GUI. I'd recommend either implementing your program in a language specific to your console (bash, powershell, etc.) or implementing a GUI.
Related
I am writing simple socket chat using console to output messages. The problem is that when one user types a message, and at the same time getting one, his input interrupted:
I: writing my input here, but
Other_user: hi! here is a message for you.
I: it splits to different lines, which is 1) very inconvenient 2) cannot see which simbols i deleted if press backspace
So, what i am asking is, how can I avoid this
(something like: if message is received, check input for symbols; if there are, remember them, delete last stroke in console, print message, and then recreate that stroke).
EDIT: attached picture
hard to tell without specific code, but an option is to use two threads, one to handle the socket input, one for output. attach these to System.in and System.out respectively. it seems like you might be using only one thread to do both.
I get that this isn't possible to do with normal java, although if there are any libraries out this it would be very useful.
Essentially, I'm designing a console app and running into an issue that when output happens while something is typed in the input line, that input text will move up and appear before the line that just got output. Is it possible to fix this in some form so that the text you are inputting that stays at the bottom?
EX:
I'm typing something as input into my commandline app, and then the program prints something WHILE I'm typing - this causes what was originally on the input line to be scrolled up with whatever the output text was. When you are trying to type something in this can obviously be detrimental. I know it's possible to prevent this.. (Other programs have done it... EX: Minecraft Server)
(If I need to be more descriptive I can.)
You could use the help of threads. One that listens to user input, the other process the actual output. This problem is similar to basic race condition problems when multiple threads attempt to read and write to a shared resource.
Your shared resource is that console. You need to keep the Input/Output operations synchronized. Have a look at race condition.
I am creating a very simple program, asking the user to guess words. Guessing words works just with Scanner and System.out.println(), so its very simple and no user interface is needed.
The guessing of words is done with eclipse. Now I need to add a function, which will allow the user to exit the "program" anytime by clicking CTRL+z and when they do that I'll need also to print out possible words they could've have guessed.
But I do not know how to add the CTRL+z exit function. Can anyone suggest anything on how to ? The word guessing is a loop.
You're answer is simple:
You can't do that!
Because you're using a command-line window. In command-line there is no listeners like KeyListener or MouseListener.....
If you want to do so, leave the command-line and go learn Swing in java.
See this question: How to get input without pressing enter every time?
I have two threads - one awaits for input and the other is printing the debugging info.
However only one console window, so I can't type 'exit' (or whatever to stop the process), because System.out.println constantly prints the stuff. Can I have two separate console windows for each?
P.S. I wouldn't want to use Swing just for this purpose - there must be a way.
The only way I could think of would be to have two difference processes and a link betweeen the two processes. But I don't have a clue as to how to do that. Perhaps your best bet is to use the JOptionPane class.
While you stated that you don't want to use Swing, I believe that JOptionPane would be the best option for you. Simply using JOptionPane.showInputDialog is a fast way to solve your issue. Here's a link to JOptionPane's JavaDoc.
If you really can't use Swing, there's always the option to press Ctrl + C to stop the process.
A final option would be to buffer the output and only write it after the input. After you receive input, you would flush the buffer and then deal with the input. In this manner, you would prevent the application from closing before the buffer is flushed. There are two ways to do this:
You can use a BufferedWriter with a very large size (maybe 100,000?) and store this as a static variable. Instead of calling System.out.println(), you could call MyClass.out.println()
You could override System using System.setOut(). You would create your own PrintWriter that would take any input and send it to a LinkedList (or your own LinkedList designed for chars, if you choose). I suggest you use a linked list because appending is O(1) for a linked list while appending is O(n) for an array list.
Edit:
As for hmjd's suggestion (file writing), you would do that like this:
System.setOut(new FileWriter(new File(myFileName)));
Log to a file then go into another window and tail the file (in unix/mac use "tail -f filename", in another os--install unix/cygwin!)
This keeps your log separate from your console and makes it persistent as well.
There are a lot of logging utilities out there that will help with this and will even help a bit more by telling you what file a given line is coming from.
Your question is similar to this one, so I think the answer is the same. However, maybe this question might be right for you.
I want to add a "history" function to my java programm, like known from bash etc, so pressing the arrow keys should show previous send commands.
It's no problem to write the past commands to the default output, which will in three new lines if arrow up is hit three times and in not editable output. I want the output of the programm to be written in the input field so i just have to hit enter, to resend the command.
Is this possible?
Kind Regards
Take a look at JLine, which provides command history, tab completion and line editing.
If you want to roll your own solution, this will get you started.
You want to change from using a buffered input into a direct input. You can do this by interfacing with System.in directly. You should create a thread to handle this, and have it block on a call to System.in.read() in a loop, reading one byte at a time.
Each time a byte is read, keep your own buffer updated with the current command that's being read. Every character that gets typed, add it to the buffer. If the character is a \b, delete the last character in the buffer. When you detect a \r or \n, execute the command in the buffer and clear it.
If you receive an up or down arrow, send a number of \bs to System.out equal to the length of the buffer. This will erase the local copy of any current command being entered. Then print out the new command to System.out and enter it into the buffer, replacing whatever was there. This will allow the user to delete it, add to it, or just press enter to submit it. This mimics the functionality of bash.
You can also detect a \t (tab) character and implement a tab-completion function.