Java continuous console while running - java

Recently I have been making a little java game where you build up a city and have to defend it. Now I want to make it ready for proper testing. I was thinking of having the server running on an old computer of mine, than I would have to make it so that, while the program is running, I can type in commands that will be executed. Like the minecraft or craftbukkit servers have. There you can type in text and press enter in the same console as where you started the program.
Anybody got any ideas?

Sounds like you just need a Scanner object.
For example, to continuously wait for input and then print that input, you would write:
Scanner s = new Scanner(System.in);
String foo = s.nextLine();
System.out.println(foo);
System.in as the constructor parameter specifies that you are reading input from the keyboard (as opposed to a file, for example).

Related

How to clear the console screen when introducing input in Java?

Is there a way to clear the console when the Java program detects the user it's introducing some data?
I'm executing a program that does the following:
User: //enter username
//show data of the username
I want to make it so the user can search for as many users he want until he ends the execution.
To make it clear and nice, after each username search, I want to clear the screen when the program detects the user is typing something (filling the buffer).
Is there any way to do this?
This is the code I'm using to clear the console (this does not detect when the user is typing):
public static void clearScreen() {
System.out.print("\033[H\033[2J");
System.out.flush();
}
Thanks in advance.
You cannot use System.in without pressing the ENTER key at the end. Its the only way. System.in is not aware of the user input until enter is pressed. So if you are using a normal command line to do this, this won't work and you have to stick different raw command lines like jline
For example :
Terminal terminal = TerminalBuilder.builder().system(true).jna(true).build();
terminal.enterRawMode(); //this enters into a raw mode and get's input on reader
reader = terminal.reader();
//finally
reader.close();
You can check it out. Although it highly doesn't make sense to bring in more dependencies unless you really want to and could just stick to a simple while loop
If you are using maven here's the dependency you can use.
<dependency>
<groupId>org.jline</groupId>
<artifactId>jline</artifactId>
</dependency>
By default, a terminal can only output text line by line.
Moving the cursor around, changing colors or clearing the screen requires special escape sequences that are interpreted by the terminal emulator in which you run your application.
C programs in Linux would usually do this via the ncurses library.
Java programs can do something similar with Lanterna (https://github.com/mabe02/lanterna) but within a GUI window. See also this article, which names other alternatives and shows how to use Lanterna: http://rememberjava.com/cli/2017/01/22/ncurses_terminal_libs.html

Java concurrent console IO

I wrote multithreaded java server-client sockets app with messaging functionality but I encountered a problem with simultaneous console IO.Main server console is listening for keyboard input and simultaneously printing out messages from the clients. On client side there is a separate thread for printout.
Here is simplified code representation:
public class ServerThread{
....
BufferedReader in = ... (sock.getInputStream);
while(true){
System.out.println(in.readline());
....
public class ServerMain{
.....
BufferedReader keyb = ... (System.in);
while(true){
in = keyb.readLine();
....
The problem occurs while I'm typing something in the main server console and at the same time a message arrives from one of the clients.
That message is then concated to what I was typing on screen and cursor moves to the beginning of the next line waiting for input.
What was typed in previously is stuck in the keyboard buffer, and I cant edit it anymore. Same problem happens on client side.
The question is how can I print messages on screen without disrupting ongoing input?
(inputted text also needs to stay printed on screen as in readLine() default behavior)
I already tried some of the solutions suggested for other similar problems:
In Lanterna and JCurses libraries there's no support for native System.IO streams. I would have to reinvent the wheel and implement it all by myself manually from memory to screen, one char at a time plus build whole console GUI layer.
The other thing was using ANSI codes but I couldn't figure out how to do what I need with them. I could read one input char at a time instead of a whole line, then if message arrives clear the line, move cursor to the beginning and printout, but afterwards in nextline I don't know how to print previously buffered text and still be able to delete chars with backspace.
edit:
GUI is not an option as I want my code to be able to run on a headless server.(also assume that there will be only one terminal, console, shell, and app running per side)
A distinct non-answer, based on: there is only one console.
And that console is an artefact from times when multiple threads weren't a real problem. "Works nicely with multiple threads" was never a requirement for that low level console.
Thus: if you really want a sophisticated solution (that isn't a hack of some sort) simply consider: not using the stdin/stdout console(s).
Instead: write a simple Swing GUI application. Have one text entry field where input is collected, and one or maybe multiple text fields where your output goes. If you want to be fancy, make it a webapp. I am sure that using some framework, you could put together a working thing within a few hours. You will learn more valuable skills by doing that, instead of spending these hours "working around" the fact that you picked the wrong technology for your problem.
Update, given the comment by the OP: then the best I can think of: don't write to the console. Write to different files. Open multiple terminals, and use tools like "tail" to show you what is happening with your output file(s).
Ok, I found the ideal solution myself:
JLine library works in conjunction with default System.IO, also there is no need to create new Terminal objects (you can) or anything else. Simply instead of BufferedReader you use LineReader
String readLine(String prompt, Character mask, String buffer)
prompt (can be null) is the unexpanded prompt pattern that will be displayed to the user on the left of the input line
mask (can also be null) is the character used to hide user input (when reading a password for example)
buffer is the initial content of the input line
Edit: In JLine's docs i found an even better solution:
printAbove
void printAbove(AttributedString str)
Prints a string before the prompt and redraw everything. If the LineReader is not actually reading a line, the string will simply be
printed to the terminal.
Parameters:
str - the string to print*

How to take standard input from user and use that across Appium Test Case?

I have a scenario where I want to take User Standard Input from the console (Using Scanner(System.in) utility in Java).
Like, When a particular text field is being appeared then User need to type the input text as standard input rather than a device itself.
I am trying below code:
System.out.println("Enter the User Input: ");
Scanner sc = new Scanner(System.in);
String inputForTextField = sc.next();
getTextField().sendKeys(inputForTextField);
But the execution is getting stuck on String inputForTextField = sc.next(); User is not able to enter the text on the console and after 60 seconds Appium session is getting timed out.
Any help/suggestion would really be appreciated!
I am also open to hearing suggestion if I can take input from User using some Java AWT prompt, I just wanted to take user input from the computer rather than the device itself.
Thanks
You can supply the values using dataprovider(Excel/Json files) or even using config.properties file. In automation, it is machine which does all the inputs, human intervention defeats the automation purpose.

Filter character of console input in Java

I'm writing a terminal version of my Java application, and this is the first time I do this. I tried Scanner and Console, but as far as I investigated, these classes only allow me to receive user input after he/she finish inputting (no manipulating/filtering).
For example, I want the user inputs his age, but if he inputs a meaningless string, all I can do is validating the string and requesting him to input again. What I really want is only allow him to input integer, i.e when he press any key which is not a number, the character will not be displayed on console. Using Swing and JTextField I can do this easily with DocumentFilter, but with console only, I still haven't found a way.
Any help is appreciated. Thanks all.
Java has something called robot API which u can use to control keyboard mouse etc...
Not the recommended way :)
Since the console is not Java program (its a c program) you have limited way to interface with it, perhaps you can write native API to get more control over it. I have not tried it but if needed use this option.

how to simulate barcode scanner for my java application?

I created a Java application and want to use barcode scanner in my Java application.
but don't have a device Barcode Scanner
How can I simulate a Barcode Scanner for testing my Java Application?
It really depends on how you want the scanner to connect to the system later on.
There are scanners that just use keyboard emulation. In that case you don't need to do anything (just make sure the right input box is active when expecting barcode input).
Other scanners connect to the system through a serial port emulation (for example, there's an USB to serial driver for Symbol/Motorola and Datalogic gun scanners). In that case, you open the serial port in Java and get scanner input as serial data. To simulate this, you'd have to connect your PC to another PC using a cross-over RS232 cable and could then use Hyperterminal/Putty/[whatever there is on linux or other OSs] to send data to your PC over the serial cable.
If you are running your application from the console,
Scanner scan = new Scanner(System.in);
String barcode = scan.nextLine();
Otherwise just pass your barcode to main method args.
I had a similar need and found the barcode-simulator project on GitHub. It covers a portion of the concerns raised in the comments, at least for the initial testing.
Still, there is nothing like the real deal. Expect that the mix of real users and real scanners are going to find unexpected holes in your application.
Provide really clear input to your clients:
When the users cursor is in the correct field have it change color and
show a message like "Waiting for Scan",
Clearly and quickly show if a scan is valid or invalid,
Make it trivial to rescan.
If your users are clear about what the path of success looks like then it should be good.

Categories

Resources