Ways to Clear the Console? - java

I have been on this for a while now, and for the past three days have ripped apart the Internet for ways to effectively clear the console in Java.
Ways I have seen it "done"
This way
for(int x = 0; x!=100; x++){
System.out.println();
} Sucks, as you can just scroll up and see the printed statements again.
Console.Clear(); and all variations of it, have not worked for me.
Runtime.getRuntime().exec("cls"); has not worked in any cases i have tried to use it in.
(I use JCreator to code, I have no idea if this has anything to do with my issue)
This way by joesumbody122, looked interesting:
private static void clearLine()
{
Console.Write(new string(' ', Console.BufferWidth - Console.CursorLeft));
}
and
private static void clearLine(int left, int top)
{
int pLeft = Console.CursorLeft;
int pTop = Console.CursorTop;
Console.setCursorPosition(left, top);
Console.Write(new string(' ', Console.BufferWidth - Console.CursorLeft));
Console.setCursorPosition(pLeft, pTop);
}
But sadly i could not get it to work for me. It gave me errors that all the methods that he called from Console did not exist. java.io.*; was imported His method clears one line specifically, so if someone could get this working, (Again, I use JCreator to code, I have no idea if this has anything to do with my issue) I could see it being looped to clear all the lines.
Ways to make less sucky?
Back to this for(int x = 0; x!=100; x++){
System.out.println();
} Is there a way to prevent the user from scrolling up in the command line? To set the cursor to the top left of the prompt? That would make this method a whole lot more useful.
Another Theory
Is there a way to simply tell java to stop printing in one command line, start printing in another, and close the window of the first so it only appears to have cleared the console, but instead created an entirely new one? I have pondered this the last two hours, and in theory it would work, but i don't know if the code to do so even exists.

There is no reliable way that works everywhere. You've already mostly discovered this.
Generally, command-line output goes into a terminal scrollback buffer, of which only the last n lines are displayed, but previous lines are available through a scrolling mechanism. A command-line program does not write directly to this buffer, but writes to stdout which is, in most cases, piped to the terminal process which then displays the data.
Some terminal programs (i.e. those supporting ANSI escapes) might let you clear the visible portion of the screen. As far as I know, only Windows' cmd.exe responds to a 'clear screen' request by clearing the entire scrollback buffer. On Linux AFAIK it's not possible to discard the buffer completely. And, on Windows, cls is not an executable command but a shell builtin, so you cannot run it from Java System.exec().
Also, any command-line program can have its output redirected to a file with out the program being aware of it, in which case 'clear screen' doesn't have much meaning.
If you MUST have this level of control then you will have to write your own display window using Swing, AWT or GWT or whatever and manage all interaction there.

If it's a command-line app and the terminal/shell you're running the app in supports ANSI escape codes then you can just do this:
System.out.print("\033[H\033[2J");
System.out.flush();

The answer depends on weather or not you are using Linux or Windows OS. If you are using linux and want to clear the console then try:
try {
new ProcessBuilder("/usr/bin/clear").inheritIO().start().waitFor();
} catch(Exception e) {}
If you are using windows try:
try {
new ProcessBuilder("cmd", "/c", "cls").inheritIO().start().waitFor();
} catch(Exception e) {}
You can handle the exception any way you want.It does not matter becasue you will not get one.

Related

Typed text displays in console when not asking for input, how can I stop this?

I'm trying to make a simple text-based game using Java in Eclipse, and everything was working just fine until it randomly started to allow you to type at any point in the program instead of just when requesting input with a Scanner. I found this really weird and did what I could to fix it but nothing worked, so now I'm back at square one. When I run my program, I can type anywhere in the console and it actually shows up and I don't want this to happen. This is my first few lines of code and there are obviously no Scanners in here so I don't understand what could be the problem.
This is happening in all of my projects and I really want to get back to coding with it working.
import java.util.Scanner;
public class Game {
public static void main(String[] args) throws InterruptedException {
String com = "Computer: ";
System.out.print(com +"H");
Thread.sleep(75);
System.out.print("i");
Thread.sleep(75);
System.out.println(".");
Thread.sleep(2000);
This is normal behavior for most consoles; it's not coming from Java or your Java code. When you type into the console, it echoes the characters you type back to you.
There do exist ways to turn off echoing. Console.readPassword() will turn it off until you hit Enter. Unfortunately, Console doesn't expose the ability to turn echoing on and off directly, only while asking for a line of input.
The JLine library can turn it on and off with Terminal.echo():
Terminal terminal = TerminalBuilder.terminal();
terminal.echo(false);
Whether this works right might depend on the way in which the program is run; I haven't tried it from Eclipse.
When I tried this, what I typed while echoing was off appeared the next time I turned echo on. Once again, normal console behavior. If you're typing into the console, it's always listening to you. If you don't want that, I found a hack around it, that worked once or twice at least:
// Skip over anything that's been typed in already.
// Re-implementing skip() with read(), because skip() can throw an "Illegal seek"
// error that read() won't.
System.in.read(new byte[System.in.available()]);
terminal.echo(true);

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*

Implement Command History within Java Program?

I need some coding advice. I've written a simple Java program which runs within one of my company's internal websites. Its a command line program where users enter commands like copy file1 to remote1 and compare file1 to file2 archive diff and so on. My colleagues like it and use it frequently.
The problem is the users' commands tend to be long and repetitive. They have asked me if it is possible to implement a command history in the program. This way, they can use the up arrow or something to scroll through, edit, and resubmit previous commands. There's no need to remember commands entered in previous sessions, only the current session.
I've thought about it, and I think I could come up with a solution from scratch... but it would take a few weeks to develop. I'd much rather implement an available package or module, if one exists and isn't too much trouble. I know this is an open-ended question, but can anyone recommend such a resource?
I don't see why it should take so long to develop. Here's a rudimentary solution:
class CommandSession {
private List<Command> commands = new ArrayList<>();
private ListIterator<Command> scroller;
public void execute(Command command) {
scroller = null;
commands.add(command);
command.execute();
}
public Command scrollUp() {
if (scroller == null) {
scroller = commands.listIterator(commands.size());
}
if (scroller.hasPrevious()) {
return scroller.previous();
}
return null;
}
}
You could tweak this in various ways for more advanced functionality, but overall it's a pretty basic concept.
if you are using a *nix environment then rlwrap may be what's you're looking for.
rlwrap tries to be completely transparent - you (or your shell) shouldn't notice any difference between command and rlwrap command -
except the added readline functionality, of course. This should even
hold true when you are re-directing, piping and sending signals from
and to command, or when command manipulates its terminal settings.
There are many options to add (programmable) completion, handle
multi-line input, colour and re-write prompts. If you don't need them
(and you probably don't), you can skip the rest of this manpage.
if not, you can use cygwin to be able to use it
I've used CRaSH in my project. It's basically a SSH shell that the user is expected to connect to (supports username/password too) and yes, supports history in commands. Commands are written in Groovy.

How to Clear Console in Java?

I have been pulling my hair for this since quite long time. I have researched for an hour on how to clear a console in Java.
All I found was dirty hacking either by printing a bunch of lines or executing this
Runtime.getruntime.exec("cls/clear");
However, nothing seems to be working for me. Isn't there really any a way of clearing the console in Java like in C (clrscr();). Isn't there any external library by which this can be achieved.
Please let me know if anyone has ever done this before using a proper function, library etc. instead of dirty hacking.
If your terminal supports ANSI escape codes, this clears the screen and moves the cursor to the first row, first column:
System.out.print("\033[H\033[2J");
System.out.flush();
This works on almost all UNIX terminals and terminal emulators. The Windows cmd.exe does not interprete ANSI escape codes.
Try this code
import java.io.IOException;
public class CLS {
public static void main(String... arg) throws IOException, InterruptedException {
new ProcessBuilder("cmd", "/c", "cls").inheritIO().start().waitFor();
}
}
Now when the Java process is connected to a console, it will clear the console.
Runtime.getRuntime().exec("PlatformDepedentCode");
You need to replace "PlatformDependentCode" with your platform's clear console command.
The exec() method executes the command you entered as the argument, just as if it is entered in the console.
In Windows you would write it as Runtime.getRuntime().exec("cls");.
Use the following code:
System.out.println("\f");
'\f' is an escape sequence which represents FormFeed. This is what I have used in my projects to clear the console. This is simpler than the other codes, I guess.
You need to instruct the console to clear.
For serial terminals this was typically done through so called "escape sequences", where notably the vt100 set has become very commonly supported (and its close ANSI-cousin).
Windows has traditionally not supported such sequences "out-of-the-box" but relied on API-calls to do these things. For DOS-based versions of Windows, however, the ANSI.SYS driver could be installed to provide such support.
So if you are under Windows, you need to interact with the appropriate Windows API. I do not believe the standard Java runtime library contains code to do so.
You can easily implement clrscr() using simple for loop printing "\b".
If you are using windows and are interested in clearing the screen before running the program, you can compile the file call it from a .bat file.
for example:
cls
java "what ever the name of the compiles class is"
Save as "etc".bat and then running by calling it in the command prompt or double clicking the file

Java's Scanner class: using left- and right buttons with Bash

I'm not too familiar with Linux/Bash, so I can't really find the right terms to search for.
Take the snippet:
public class Main {
public static void main(String[] args) {
java.util.Scanner keyboard = new java.util.Scanner(System.in);
while(true) {
System.out.print("$ ");
String in = keyboard.nextLine();
if(in.equals("q")) break;
System.out.println(" "+in);
}
}
}
If I run it on my Linux box using Bash, I can't use any of the arrow buttons (I'm only interested in the left- and right button, btw). For example, if I type "test" and then try to go back by pressing the left button, ^[[D appears instead of my cursor going back one place:
$ test^[[D
I've tried the newer Console class as well, but the end result is the same. On Windows' cmd.exe shell, I don't have this problem.
So, the question is: is there a way to change my Java code so that I can use the arrow keys without Bash transforming them in sequences like ^[[D but actually move the cursor instead?
I'm hoping that I can solve this on a "programming level". If this is not possible, then I guess I'd better try my luck on Superuser to see if there's something I need to change on my Bash console.
Thanks in advance.
Bash is the shell, not the terminal; from your program you're talking to the terminal. To provide that functionality, bash and many other programs use readline - there appears to be a Java wrapper for it but I've never used it. I'm sure someone else will come along with a more definitive answer.
Another option would be a Java curses library.

Categories

Resources