Search code examples
javautf-8console-applicationlocaleansi-escape

Reliable coloring of text in Java System.out.println


I'd like to color certain messages in a Java console application. I've found various answers stating to include, for example, \u001B[31m before the desired String, but this is instead just printing ·[37m into my console. I suspect this may have to do with my computer being set to Japanese system locale, but I haven't found any suggestions on how to fix this so it will work under different Windows system locales. I'd appreciate any help on whether this is indeed the cause, and how I could fix it. For reference, it does work within the IDE console such as in IntelliJ or VS Code; it specifically does not work when used in the command prompt.


Solution

  • I can reproduce your problem on Windows 10 when running the following code:

        System.out.println("\u001B[31m Line 1\u001B[0m");
        System.out.println("\u001B[32m Line 2\u001B[0m");
        System.out.println("\u001B[33m Line 3\u001B[0m");
        System.out.println("\u001B[34m Line 4\u001B[0m");
        System.out.println("\u001B[35m Line 5\u001B[0m");
    

    Each string passed to println() outputs text in a different font color, and contains two ANSI escape sequences:

    • The first sets the font color. For example, "\u001b[31m" sets the font color to dark red.
    • The second (i.e. "\u001B[0m") resets the terminal back to the default colors.

    See How-to: Use ANSI colors in the terminal for more details.

    The changes in font color are rendered correctly when the output is sent to the console within Intellij IDEA, as shown in this screen shot:

    Intellij Console

    However, as you pointed out, the ANSI escape sequences are not recognized when running the same code from a Command Prompt window. Here's a screen shot:

    Windows console

    I don't think that your problem is anything to do with locales. Instead you are encountering a limitation of the Command Prompt window on Windows; it does not handle those ANSI escape sequences correctly.

    That issue has supposedly been fixed with more recent versions of Windows 10, though apparently associated changes to the Windows Registry (which I did not implement) are required. See How to make win32 console recognize ANSI/VT100 escape sequences? and Windows console with ANSI colors handling for details.

    However, there is a simpler and safer approach that worked for me:

    • Download and install Windows Terminal (wt.exe). See Install and get started setting up Windows Terminal for details.
    • Once Windows Terminal is installed and run, you can use it to open a Command Prompt window which will recognize those ANSI escape sequences. When the same code that failed from the standalone Command Prompt window (shown above) is run from the Command Prompt window within Windows Terminal this is the output:

    Terminal console

    Notes:

    • If you want to be able to run your code on any Windows machine then obviously this is not a solution since it relies on Windows Terminal being installed. However, that still seems preferable to messing with the Registry, which is potentially hazardous and may have unwanted side effects.
    • I had to make a couple of simple changes after installing Windows Terminal: enable the Touch Keyboard and Handwriting Panel Service, and restart.
    • I didn't try, but you aren't confined to just changing font color. Other features (e.g. background color, blinking, underline, bold, etc.) should also work with the appropriate ANSI escape sequences. See Console Virtual Terminal Sequences for more information.