Check if console supports ANSI escape codes in Java - java

I'm building a program in Java that uses menus with different colors using ANSI escape codes. Something like
System.out.println("\u001B[36m"+"Menu option"+"\u001B[0m");
The problem is that i want to check if the console where the code is going to be executed supports using this codes, so in case it doesn't, print an alternative version without the codes.
It will be something similar to:
if(console.supportsANSICode){
System.out.println("\u001B[36m"+"Menu option"+"\u001B[0m");
}
else{
System.out.println("Menu option");
}
Is there a method in java to check this?

A simple java-only solution:
if (System.console() != null && System.getenv().get("TERM") != null) {
System.out.println("\u001B[36m"+"Menu option"+"\u001B[0m");
} else {
System.out.println("Menu option");
}
The first term is there to check if a terminal is attached, second to see if TERM env var is defined (is not on Windows). This isn't perfect, but works well enough in my case.

I don't know if Java has some special way to deal with this, but there are two ways to deal with the problem itself. The usual method used (at least in the unix world) is to get the terminal used from the TERM environment variable and look up it's capabilities from the terminfo/termcap database (usually using curses or slang). Another more crude approach is to send the Device Status Report code ("\u001B[6n") and check if the terminal responds. This is of course a bit of a hack since a terminal that supports the DSR code might not support color for example.

Related

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.

Ways to Clear the Console?

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.

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

How to readLine with echo in Java?

I would like to use a BufferedReader with a kind of readLine() (or similar) that can return an echo for every keystroke pressed.
It's for a remote terminal. Other way to ask it is how is implemented a console in java.
This is what came to mind but is too ugly. Is there any known library that implement something like this?
while(condition) {
nByteRead = in.read(buffer);
if (nByteRead != -1) {
// ECHO
out.write(buffer, 0, bytes_read);
// read bytes till NEW_LINE...
// etc...!
}
}
Of course I could encapsulate this behaviour in some thread and go on with a library for this, I just wonder if there is some wheel already invented.
Thanks for any hint!
Most terminals, including the default terminals in Ubuntu and Windows (I believe) won't pass on the characters to the JVM until the user hits return. (I.e., it is buffered on a full-line basis on a lower level in the system.)
If you need to read one character at a time from the terminal, you'll have to go with a lower level system library.
Related question:
Why can't we read one character at a time from System.in?
(disclamer, I'm not completely sure I understood your question correctly.)
There's:
JLine: http://jline.sourceforge.net/
Java Curses: http://sourceforge.net/projects/javacurses/

Selenium typeKeys strips out dot from the String being typed

The following instruction
Selenium.typeKeys("location", "gmail.com");
types the string gmailcom instead of gmail.com.
What's happening there?
From the comments:
I am trying to simulate autofill and the only way to do it currently on selenium is to combine type and typeKeys. eg:
selenium.type("assigned_to", split[0]+"#");
selenium.typeKeys("assigned_to", "gmail.com");
Now my question is why typeKeys doesn't type the 'dot' in between gmail.com?
Have you tried using the Native key functions and javascript char codes?
I couldn't get a 'period' character to work using them (char 190), but I got the decimal (char 110) to work just fine, and the text box shouldn't have a problem with either.
selenium.Focus("assigned_to");
selenium.Type("assigned_to", split[0]+"#");
selenium.TypeKeys("assigned_to", "gmail");
selenium.KeyPressNative("110");
selenium.TypeKeys("assigned_to", "com");
Use the type method.
From the javadoc for typekeys:
this command may or may not have any
visible effect, even in cases where
typing keys would normally have a
visible effect
...
In some cases, you may
need to use the simple "type" command
to set the value of the field and then
the "typeKeys" command to send the
keystroke events corresponding to what
you just typed.
We had similar problems using typekeys in selenium python.
One workaround we figured to resolve this issue is to use the combination of 'type' and 'type_keys'. As you might be aware, type does not have such issues.
We did this in our selenium python script and it works just fine.
For example:
If there's an email address to be entered in a text box: test.me#test.me.uk
Then do
type(locator,’test.me#test.me.’)
type_keys(locator,’uk’)
Maybe a very crude way to do, but it did the job.
Hope this helps someone else with a similar problem.
Also try to set focus on element before write on it.
selenium.focus(locator);
selenium.typeKeys(locator, value);
it did function in my case, handling a input type=password.
Suppose the string to be typed using typeKeys is "abc.xyz.efg". Then, we can use type and typeKeys commands to write the given string.
type(locator,"abc.xyz.")
typeKeys(locator,"efg")
The above two steps are useful whenever you want to select an element in drop down box, and the drop down pops down only if we use typeKeys command.
I'm also seeing this behaviour when using Selenium RC (C#), and with different characters ('y' for example which also seems to remove the character follow it from the typing action..)
For some situations it is entirely possible to get around the issue by typing out the keys with the TypeKeys or KeyPress functions, but I haven't managed to find a solution that works when you want to type text in a field, enter control characters ([Enter] or a newline for example), and then type more text.. (using the 'Type' function in this case simply overwrites the field contents...).
If anyone manages to find a reasonable solution to this issue, please add it to this question as it's starting to come up in google now and would probably help alot of people out.. (I'd start a bounty if I could..)
This is an open bug in Selenium (bug SEL-519).
After some fiddling around with it, I finally managed to enter '.' into a textarea by using JavaScript. Execute something like window.document.getElementById('assigned_to').value += '.' via storeEval or the like.
I got the same behaviour but fixed it by passing a variable to the Type command instead of a string.
string email = #"name#gmail.com";
selenium.Type(inputfield, email);
It works like a charm!

Categories

Resources