This question already has answers here:
How to clear the console?
(14 answers)
Closed 7 years ago.
Is there any option to clear the screen in java as clrscr() in C.
As dirty hacks go, I like msparer's solution. An even dirtier method that I've seen used (I would never do this myself. I swear. Really.) is to write a bunch of newlines to the console. This doesn't clear the screen at all, but creates the illusion of a clear screen to the user.
char c = '\n';
int length = 25;
char[] chars = new char[length];
Arrays.fill(chars, c);
System.out.print(String.valueOf(chars));
If you're talking about a console application, then there isn't a clear screen option AFAIK. A quite dirty option would be to invoke the clear screen command of the underlying OS.
Then it's something like
Runtime.getRuntime().exec("cls");
for Windows or
Runtime.getRuntime().exec("clear");
for a load of other OS. You can find out the OS with System.getProperty("os.name").
If you're talking about the console, then no. Writing to the console is just a special case of an output stream. Output streams don't know anything about the screen, as they can be just as easily redirected to a file or another system device.
For any console which supports ANSI escapes the following would work (would e.g. work in Win98 console).
private final String ANSI_CLS = "\u001b[2J";
....
System.out.print(ANSI_CLS);
System.out.flush();
...
Starting with Win NT this won't work anymore and you can either
Do a JNI call (e.g. like here: Java: Clear console and control attributes
Or write out a bunch of empty lines
Otherwise you are out of luck.
And btw. you must keep in mind that System.out and System.err don't have to be console they could be set to what ever (writing into a file e.g.) an usecase where clearing the screen wouldn't make any sense at all.
On linux, you can do something like:
System.out.println("\f");
You can also use Jcurses
To clear the screen just type:
System.out.print('\u000C');
You can also try ANSI Escape Codes:
If your terminal support them, try something like this:
System.out.print("\033[2J\033[1;1H");
You can include \0333[1;1H to be sure if \0333[2J does not move the cursor in the upper left corner.
More specifically:
033 is the octal of ESC
2J is for clearing the entire console/terminal screen
1;1H moves the cursor to row 1 and column 1
Jansi is an excellent workaround. I am an amateur coder and Jansi is easy to setup especially with Eclipse.
The following is a link to the homepage of Jansi:
http://jansi.fusesource.org/
The following is a link to a site containing a code as a demonstration of AnsiConsole class contained in the Jansi package:
http://www.rgagnon.com/javadetails/java-0047.html
For Windows, Java Console API project provides functionality to determine console size and set cursor position. Clearing the screen is trivial with that. It's a version 0.2 now so it's not exactly production ready, but it works.
Alternatively, you can simply print out some new lines via System.out.println(). 640 should be enough for everybody :-) It's not the same as clearing screen, but for user's intents and purposes it'd do.
you should give a try with JNA and try mapping native libraries:
on linux you must map C functions from ncurses library
on windows you must map functions from both msvcrt and kernel32, as clearly stated here
PS
let me known if you need some sample code
Related
With Java 11 on Windows, I can get info about my files using:
import javax.swing.filechooser.FileSystemView
var type = FileSystemView.getFileSystemView().getSystemTypeDescription(file)
var icon = FileSystemView.getFileSystemView().getSystemIcon(file)
On Ubuntu (20.04) however, things are different. By now, I've figured out that the icon has a ToolkitImage inside instead of a BufferedImage, which is annoying because it's internal API, but I can render that now.
The remaining problem is the file type, which still returns null on Ubuntu when using the FileSystemView, or returns "Generic File" for every file if using the new FileChooser().getTypeDescription(file) way.
How can I get a proper file type description on Ubuntu?
getFileSystemView is broken
A bold claim: Whatever you wanted this to do, it won't work. Based on looking at the source. You can skip this section if you're willing to accept it's a dead end, but I best back up such a claim, so read on if you'd like to be convinced:
The sources I have here for both JDK11 and JDK17 do the following relatively simplistic approach for FileSystemView.getFileSystemView():
If the value of File.separator is \\, return the windows implementation.
If the value is /, return the unix implementation (that'd therefore be just about everything else, notably including macs).
Otherwise return the generic implementation. Let's forget about this, which OS has neither / or \\ at this point? pre-MacOSX mac os is long dead at this point, that's the only one I can think of.
The unix implementation is:
return null;
Oof. That's not going to get us very far. The windows implementation goes with ShellFolder. Which is general code; I do not understand why the unix implementation just disregards it.
Perhaps this explanation makes the most sense: .getSystemTypeDescription is intended to return the opinion of the OS itself as to how one would describe the type of file this is. The reason the unix implementation just return null;s is simply that as a concept this isn't how unix works. The OS itself doesn't have some sort of registry that maps file extensions to names (such as windows' HKEY_LOCAL_MACHINE/.txt and friends), nor does it have a concept where each file has its own metadata that contains additional info, such as 'which app created me' / 'which app should be used to open me when double clicked', such as MacOSX does. (Of course, if you do run this on a mac, you still get null, which really isn't excusable).
Of course, we now get into a more tricky debate: What is your OS, really. One could say 'well, its linux, and KDE, or GnomeDesktop or whatnot, well, that's just this app, you know'. But one could also say that you run the java app on the OS 'KDE/Linux'. In other words, what does System mean when we talk about FileSystemView. Evidently, the JDK impl source I'm looking at (which is OpenJDKs) chooses to define it as 'just linux', which has no such thing as the 'system's opinion on what type of file this is', making return null; a correct, but mostly useless, answer.
The getSystemIcon implementation of the abstract supertype itself is weird: It is a near carbon copy of the windows-specific implementation of getSystemTypeDescription - namely: Get the ShellFolder object, then ask it. I have no idea why on unix, 'just ask the shellfolder' is the implementation of getSystemIcon, whereas 'just return null' is the implementation of getSystemTypeDescription - why not also ask the shellfolder?
At any rate, even if you did, not much use there: The default shell folder implementation always returns null. This is sun.awt code so it is considerably more likely that the implementation of AWT for that specific platform overrides it, but this isn't in the openjdk sources as far as I looked, at any rate.
The default impl of getSystemIcon will return either a generic file icon or a generic folder icon (by invoking UIManager.getIcon("FileView.directotyIcon"), for example) if the ShellFolder returns null as an icon.
So let's give up on this implementation: Conclude it cannot help you.
Define 'type description'
What does that really mean? I can only foresee 3 useful takes on what this is supposed to mean:
Something that human eyeballs and brains will likely understand.
A mime type, which is a universal standard for describing file types.
"Whatever the window manager that the user is using would see in the local equivalent of a file explorer app - explorer.exe, on windows, Finder.app on mac, etc".
Presumably the getSystemTypeDescription is the method that is supposed to answer the 3rd option (the local window manager's description). But, given that OpenJDK doesn't actually implement this (well, it does, in a useless way, by just returning null), the only way you're getting that is if you put in the considerable effort to figure out how each and every popular window manager used worldwide does it and port it all over to java code. I assume you're not interested in doing that kind of work.
But the other 2 - there are ways to get that.
Let's start with mime types.
Plan A is to ask java:
import java.nio.file.*;
class Test {
public static void main(String[] args) throws Exception {
var p = Paths.get("test.otf");
Files.createFile(p);
System.out.println(Files.probeContentType(p));
Files.delete(p);
}
}
Save to that a file and run it: java Test.java (yay JDK11+ where you can just pass java files to the JVM executable), and see if it works. That is, that should be returning application/font-sfnt for you. It does, for me at any rate, with Coretto JDK17 (java -version: openjdk version "17.0.3" 2022-04-19 LTS) on Ubuntu 20.04.1.
Running it with Temurin 17 (JDK from the Adoptium project) on mac: font/otf. Oh well, that's embarrassing, perhaps. But it's not necessarily a bad answer. Unfortunately, the Mac's own Finder app has a 'type description' column and that's "OpenType® font", not "font/otf". Presumably macs have a mimetype to human readable description database someplace that as far as I know you can't access with generic java code. Still, "font/otf" is better than "an .otf file", presumably.
If the probe method isn't working for you, you can always choose to check if /etc/mime.types exists, which should exist on linuxen. For each line, .split("\\s+"); v[0] is the mime type, and the remaining elements are each an extension without the dot, e.g. my ubuntu install would list application/font-sfnt as being the mime type for types otf and ttf.
Yet another alternative is to ship a known list of extension-to-mimetype mappings. For example, The Eclipse Jetty has a MimeTypes class that is pre-filled with this sizable list of known extensions.
Steve Jobs / flash the MIME gang-sign
If you're like Steve or the MIME consortium, this whole business of treating 'the stuff after the last dot in the file name' as somehow indicative of what kind of file it is, leaves a bad taste in your mouth and you'd like to avoid it. You can, sort of. On unixen anyway. Most unix installs have /usr/bin/file - both my mac and the ubuntu install I'm looking at has this. You can ProcessBuilder.exec that. This tool does not look at the file name at all, solely at the actual content. It might be slow (reads the whole thing if it needs to), but, if I run it on an OTF file, it spits out:
actual-valid-font-file.tof: OpenType font data
which is certainly a string I could show to a user that's "prettier" than font/otf, though it isn't quite what a native mac app would show (which shows OpenType® font as mentioned before.
On windows, where file (the filetype guesser application) isn't usually available, well, it sounds like FileSystemView.getFileSystemView().getSystemTypeDescription(file) actually works. I bet the number of systems where /usr/bin/file doesn't exist, and getSystemTypeDescription returns nothing useful, is infinitesemal.
Icons
Presumably you want the same thing here: Give me that icon which would be familiar to the user, which runs into the same issue, especially on linux: Each and every 'file explorer' app has its own icon set, and there are a lot of file explorer apps - just about every window manager ships their own version of it and there are a lot of linux window managers. I'm not sure any JVM impl out there has code to fetch the right icon out of all of those different window manager implementations, and I don't think there's a standardized way to accomplish this using just plain jane disk access, either.
But, we've established you can pick up the mime type (if using /usr/bin/file, there's the --mime-type option. (My /usr/bin/file gives me application/vnd.ms-opentype, so that's 3 different mimetypes for the same thing already, boy that whole XKCD comic of 'there are 14 different standards' comes up a lot, doesn't it)
Given a mime type, there are loads of icon sets out there, free and open source.
The Oxygen icons project is a FOSS iconset hosted on github with an icon (in various sizes) for a boatload of mimetypes. You could use .getSystemIcon first, and if that doesn't return a suitable answer (bit tricky; sometimes you get a generic 'its a file' icon which you might not want), then use an icon set. You won't be matching the Look-n-Feel of the platform, but then again if this question is really just "I want to write an app in swing that looks indistinguishable from the host OS, be it windows, mac, KDE, Gnome, Xfce, Cinnamon, Budgie, or Enlightenment", the only pragmatic answer pretty much has to be: "Just give up on that pipe dream".
NB: Hoi :)
The code for getSystemTypeDescription is
public String getSystemTypeDescription(File f) {
return null;
}
which is overridden in WindowsFileSystemView, but not in UnixFileSystemView. Maybe JFileChooser suits your needs:
JFileChooser chooser = new JFileChooser();
String type = chooser.getTypeDescription(file);
I get a FileNotFoundException during the execution of getSystemIcon. Following the code, in the method getShellFolder there is this snippet
if (!Files.exists(Paths.get(file.getPath()), LinkOption.NOFOLLOW_LINKS)) {
throw new FileNotFoundException();
}
so symbolic links are not followed, and maybe that's the issue. But again, JFileChooser works:
Icon icon = chooser.getIcon(file);
Say I allow the user to edit something, like the phone number in an Address Book (actually, that's exactly what I'm doing). Is there something that I can add to println that will allow me to insert a variable to display as fully editable text? The assignment that I'm doing this for doesn't actually call for this, but I think it would be cool to have. I'm looking on Google but can't find anything, then again I don't really know what I'm looking for and whether or not I have the correct terms in mind ...
No, not using only what Java provides in the framework. Editing some text would require to
act on key press, which is not possible as in Java the input is buffered (i.e., wait for Enter to be pressed)
to move around in the text you output, which is also not possible
This could be done using some native code (ncurse on linux, ...), using JNI or JNA, but not that easily.
Note that there are some projects that aim to add those functionalities, so if you can use something outside of the core libraries, you could give them a tries... for instance http://code.google.com/p/java-console-api/
There are various options for this, in order of simplicity and portability to features and complexity:
Simply prompt for the information, reading a complete (return-terminated) line of response, and allow the normal terminal input facilities to be used for basic editing.
Use something like the gnu readline library to allow more advanced editing. You still won't have widgets (text input boxes at specific places on screen) as such though. There's a java implementation here: http://java-readline.sourceforge.net/
Use something like ncurses to specifically position the cursor, print text labels, handle keypresses, and implement your own text input box. Not fun.
Use a textual user interface library (TUI), like this one: http://www.bmsi.com/tuipeer/
If you opened a window that looks like the console window, and could react to keypress events, then you could do what you are asking, but, otherwise, if you are just running a program, the program will have ceased executing and returned control to your console, so it can't do anything else.
But, if you use a scriptable version of java you could write your own shell, and then you could do what you are asking, as the shell would not cease executing.
But, that will probably be beyond your course.
Does Java support controlling the cursor when outputting to a console? For example, I'd like to set the character position, and possibly color, before doing a System.out.print(). Think of the way an application like top writes to the console. Thanks!
You usually do not use system.out to do these things. most applications in *nix use NCURSES (http://en.wikipedia.org/wiki/Ncurses) for this. You can try http://sourceforge.net/projects/javacurses/ if you need something this smart.
However, you can always sysout backspace (\b) characters if you want to delete what you wanted, and hope for the best
Ha. You can still do it in Linux.
Reference this man page for the codes themselves
http://man7.org/linux/man-pages/man4/console_codes.4.html
public class quickTest{
public static void main( String[] args ){
//This will undo the current line by erasing it
//and then putting the curser back at column 1
System.out.println( "Hello.\u001b[1K\u001b[1GHi." );
}
}
Not directly. In the old days ANSI escape sequences was supported, but not anymore.
I would suggest you look into a good Java Curses library supporting Windows. I cannot recommend any :(
Just a quick one here.
What are the benefits of using java.io.Console as opposed to using a BufferedReader wrapping an InputStreamReader for System.in?
Why would I use it?
Thanks for any advice!
Because it's code that is already written for you...no need to re-invent the wheel. Chances are, you're not going to get it any better than it already is.
You can use java.io.Console to present an interactive command-line to the user. You could do all that with System.in yourself, but you would have to implement things like noticing when the input was done, or readPassword, etc.
See java.io.Console is finally here!
One of the most popular feature
requests for J2SE in recent times has
been the request to improve console
support and provide a way to enter
passwords with echo disabled.
Developers know this feature 4050435
as it has been skulking in the Top 25
RFEs list for some time.
java.io.Console only works when you start a Java program from a command line without redirecting STDIN/STDOUT.
The main advantage I see with Console over System.in is that you have the readPassword() method, which won't echo the characters typed by the user (I couldn't find a way to do this with System.in).
You also have readLine() which will present a prompt and read a single line. You don't have to create your own LineNumberReader.
But, if you want your Java program to be able to read from STDIN when it's redirected from a file or pipe, you still have to use System.in.
Another trick I'm pretty sure you won't get with Console--I created my own input and output streams and replaced System.in/out with them. My implementation of the stream appended to a log file as well as echoing to the screen.
When I turned on my poor-man's "Debug Info", I could even have it tell me what program/line the sysout came from (It was slow though. It created an exception and examined the appropriate stack entry so it was off by default)
java.io.Console is used to take and read input from the user at runtime and output are displayed after processing the input from user.
For more and detailed information visit https://www.examsmyantra.com/article/58/java/java-io---console-input-and-output
Say I allow the user to edit something, like the phone number in an Address Book (actually, that's exactly what I'm doing). Is there something that I can add to println that will allow me to insert a variable to display as fully editable text? The assignment that I'm doing this for doesn't actually call for this, but I think it would be cool to have. I'm looking on Google but can't find anything, then again I don't really know what I'm looking for and whether or not I have the correct terms in mind ...
No, not using only what Java provides in the framework. Editing some text would require to
act on key press, which is not possible as in Java the input is buffered (i.e., wait for Enter to be pressed)
to move around in the text you output, which is also not possible
This could be done using some native code (ncurse on linux, ...), using JNI or JNA, but not that easily.
Note that there are some projects that aim to add those functionalities, so if you can use something outside of the core libraries, you could give them a tries... for instance http://code.google.com/p/java-console-api/
There are various options for this, in order of simplicity and portability to features and complexity:
Simply prompt for the information, reading a complete (return-terminated) line of response, and allow the normal terminal input facilities to be used for basic editing.
Use something like the gnu readline library to allow more advanced editing. You still won't have widgets (text input boxes at specific places on screen) as such though. There's a java implementation here: http://java-readline.sourceforge.net/
Use something like ncurses to specifically position the cursor, print text labels, handle keypresses, and implement your own text input box. Not fun.
Use a textual user interface library (TUI), like this one: http://www.bmsi.com/tuipeer/
If you opened a window that looks like the console window, and could react to keypress events, then you could do what you are asking, but, otherwise, if you are just running a program, the program will have ceased executing and returned control to your console, so it can't do anything else.
But, if you use a scriptable version of java you could write your own shell, and then you could do what you are asking, as the shell would not cease executing.
But, that will probably be beyond your course.