Can I find the console width with Java?

0 votes
asked Aug 17, 2009 by masher

Is there a way to find the width of the console in which my Java program is running?

I would like this to be cross platform if possible...

I have no desire to change the width of the buffer or the window, I just want to know its width so I can properly format text that is being printed to screen.

7 Answers

0 votes
answered Aug 17, 2009 by jesper

Java 6 has a class java.io.Console, but it unfortunately lacks the functionality you're asking for. Getting the console window width is not possible with the standard Java library and pure, cross-platform Java.

Here is an alternative Java console library which allows you to get the screen size, but it includes a Windows-specific DLL. You might be able to take the source code and compile the C part into a Linux or Mac OS X shared library, so that it will work on those platforms as well.

0 votes
answered Aug 17, 2009 by stephen-c

There are no reliable cross-platform solutions to this problem. Indeed, there are situations where it is not possible to know what the real console width is.

For example, on a Linux system you can typically find out the notional terminal dimensions from the LINES and COLUMNS environment variables. While these variables are automatically updated when you resize some "terminal emulator" windows, this is not always the case. Indeed, in the case of a remote console connected via telnet protocol, there is no way to get the actual terminal dimensions to the user's shell.

EDIT: Just to add that if the user changes the dimensions of his/her xterm on Linux after launching a Java app, the Java app won't be notified, and it won't see the new dimensions reflected in its copy of the LINES and COLUMNS environment variables!

EDIT 2: My mistake, they are bash shell variables, but are not exported to the environment by default. You can "fix" this by running export COLUMNS LINES before you run your Java application.

0 votes
answered Aug 14, 2011 by aubreybourke

I have been working on this problem before. I use a couple of different techniques. However it is difficult to have a truly cross platform solution.

I tried doing try something like this:

String os = System.getProperty("os.name").toLowerCase();

    //Windows
    if(os.contains("win")){
        System.out.append("Windows Detected");
        //set Windows Dos Terminal width 80, height 25
        Process p = Runtime.getRuntime().exec("mode 80, 25");
    }
    //Mac
    if(os.contains("mac")){
        System.out.println("Macintosh Detected");
        //... I dont know...try Google
    }
    //Linux
    if(os.contains("linux")){
        System.out.println("Linux Detected");

You can read/test and append "export COLUMNS" to the .bashrc file in every Linux users home directory with the String.contains("export COLUMNS") method and the user.dir property.

That would allow you to get the columns to load up every time the java app starts up.

Then I would pass it to a temp file. Like this:

try {
    ProcessBuilder pb = new ProcessBuilder("bash","-c","echo $COLUMNS >/home/$USER/bin/temp.txt" );  
        pb.start();

    }catch (Exception e) {
        System.out.println("exception happened - here's what I know: ");
        e.printStackTrace();
        System.exit(-1);
    }
}

Another option you have is to execute yor Java.jar with a bash script at startup. Inside the script you can use "tput cols" to get the width. Then pass that value to your Java app as a String[] arg.

Like so:

//#!/bin/bash

//#clear the screen

clear 

//#get the console width and height

c=$[$(tput cols)]

l=$[$(tput lines)]

//#pass the columns, lines and an optional third value as String[] args.

java -jar ~/bin/Plus.jar $c $l $1

why is this such a difficult task with Java? Obviously a good place to write a good API. I guess we could try Apache.commons.exec as well?

0 votes
answered Aug 18, 2013 by jack-oconnor

Edit: See @dave_thompson_085's comment about ProcessBuilder, as that's almost certainly a better approach.

Another answer mentioned running tput cols in a script before you start your command. But if you want to run that after Java has already started, using Runtime.getRuntime().exec(), you'll find that tput can't talk to your terminal, because Java has redirected stdout and stderr. As a not-at-all-portable workaround, you can use the magical /dev/tty device, which refers to the terminal of the current process. That lets you run something like this:

Process p = Runtime.getRuntime().exec(new String[] {
    "bash", "-c", "tput cols 2> /dev/tty" });
// Read the output of this process to get your terminal width

This works for me on Linux, but I wouldn't expect it to work everywhere. It will hopefully work on Mac. It definitely won't work on Windows, though it might with Cygwin.

0 votes
answered Aug 22, 2013 by michael-scheper

Python seems to have a good solution: 11.9.3. Querying the size of the output terminal. I wouldn't hold my breath waiting for this to be available in core Java, but you might be able to use Jython to make the Python functionality available.

0 votes
answered Aug 22, 2013 by michael-scheper

Actually, a Java library already exists to do this in Java: JLine 2. (There's an old version on SourceForce, but that link to GitHub seems to be the latest.)

This worked for me under Linux (Mint 14) and Windows (I don't know what version), using JLine 2.11:

terminalWidth = jline.TerminalFactory.get().getWidth();

JLine promises to work on Mac, too.

I've found that it returns bad widths (like 1!) under the Eclipse console (but even Java's native Console doesn't work under Eclipse!), and, unfortunately, under Cygwin. But I've worked around this with code that checks for unreasonable values (< 10) and just uses 80 in those cases.

0 votes
answered Sep 15, 2017 by panayotis

For me, the only way to get an idea of the terminal window (still not correct when the window resizes) is to use a command like

ProcessBuilder pb = new ProcessBuilder("cmd.exe", "/c", "mode con");
pb.redirectError(ProcessBuilder.Redirect.INHERIT);

When run without the cmd.exe part, it shows that the command could not be found. Also note the redirectError part. If not used then the Java output size will be used, not the actual one. Only with this combination it was possible to grab the actual size.

Welcome to Q&A, where you can ask questions and receive answers from other members of the community.
Website Online Counter

...