Skip to main content
ansicode
Java

ANSI escape codes in Java

Java string literals have no `\e` escape — write `\033` (octal) or `\u001b` (Unicode escape). `System.out.println("\033[31mred\033[0m")` is byte-clean on every JVM. On Windows, Conhost since Windows 10 1709 parses VT natively, but for compatibility with older Conhost (and to handle the Maven / Gradle / IntelliJ output-wrapping that often strips ANSI), call `AnsiConsole.systemInstall()` from **Jansi** — it swaps `System.out` and `System.err` with wrappers that translate ANSI to Win32 console-API calls on legacy hosts and pass through on modern ones. For more than ad-hoc print statements: **JLine 3** is Java's `readline` (raw mode, line editing, history, completion, masked password, terminal capability detection) — the foundation under Spring Shell, JBang, Groovy's `groovysh`, and OpenJDK's `jshell`. **picocli** annotation-drives CLI arg parsing with ANSI-aware help formatters via `Help.Ansi.AUTO` (honours `NO_COLOR` and `isatty`). For full-screen TUIs reach for **Lanterna** — a Swing-style hierarchy of `Window` / `Panel` / `Component` rendered to ANSI.

Recommended libraries

  • Jansi

    The canonical Windows-VT shim + ANSI builder. `AnsiConsole.systemInstall()` swaps `System.out` / `System.err` so escapes work on Conhost pre-1709 (translates ANSI → Win32 console API). Fluent builder: `Ansi.ansi().fg(RED).bold().a("error:").reset().a(" perm denied")`. The output layer under Maven, Gradle, Spring Boot dev tools.

  • JLine 3

    Java's `readline` — raw mode, line editing, history, tab completion, masked password, terminal capability detection. Foundation under Spring Shell, JBang, Groovy `groovysh`, OpenJDK `jshell`. Bridges to Jansi on Windows; uses native PTY (`org.jline.terminal.impl.PosixSysTerminal`) on POSIX.

  • picocli

    Annotation-driven CLI framework — `@Command`, `@Option`, `@Parameters`. Auto-generates ANSI-coloured `--help` via `Help.Ansi.AUTO` (respects `NO_COLOR` + `isatty`). Markup syntax in description strings: `@|bold,fg(red) error|@`, `@|underline link|@`. Integrates with Jansi for Windows VT.

  • Lanterna

    Cross-platform full-screen TUI library — Swing-style hierarchy of `Window`, `Panel`, `Component`, `Label`, `Button`, `TextBox` rendered to ANSI. Supports keyboard and mouse, multi-window layouts, theming. Used by classic Java TUI projects (text-mode games, sysadmin dashboards).

Idiomatic patterns

Direct System.out — \033 (octal) or \u001b (Unicode)
public class Main {
    public static void main(String[] args) {
        // Java has no \e literal — use \033 (octal) or \u001b (Unicode).
        System.out.println("\033[1;31merror:\033[0m permission denied");
        System.out.println("\u001b[1;32mok:\u001b[0m all 142 tests passed");
    }
}
Jansi builder + AnsiConsole.systemInstall (Windows-safe)
import org.fusesource.jansi.AnsiConsole;
import static org.fusesource.jansi.Ansi.*;
import static org.fusesource.jansi.Ansi.Color.*;

public class Main {
    public static void main(String[] args) {
        AnsiConsole.systemInstall();   // safe no-op on modern hosts
        try {
            System.out.println(ansi()
                .fg(RED).bold().a("error:")
                .reset().a(" permission denied"));

            // Truecolor (Jansi 2.x):
            System.out.println(ansi()
                .fgRgb(0xcb, 0xa6, 0xf7).a("lavender truecolor").reset());
        } finally {
            AnsiConsole.systemUninstall();
        }
    }
}
picocli @Command with ANSI-aware help
import picocli.CommandLine;
import picocli.CommandLine.Command;
import picocli.CommandLine.Option;
import picocli.CommandLine.Help.Ansi;

@Command(
    name = "deploy",
    mixinStandardHelpOptions = true,
    description = "@|bold,fg(blue) Deploy|@ a service to @|fg(yellow) production|@."
)
public class Deploy implements Runnable {
    @Option(names = {"-r", "--region"},
            description = "AWS region (@|fg(cyan) e.g. us-east-1|@)")
    String region;

    public void run() {
        // Ansi.AUTO respects NO_COLOR + isatty automatically.
        System.out.println(Ansi.AUTO.string(
            "@|bold,fg(green) ok|@: deploying to " + region));
    }

    public static void main(String[] args) {
        System.exit(new CommandLine(new Deploy()).execute(args));
    }
}
JLine 3 raw-mode key reader
import org.jline.terminal.Terminal;
import org.jline.terminal.TerminalBuilder;

public class Main {
    public static void main(String[] args) throws Exception {
        try (Terminal term = TerminalBuilder.builder()
                .jansi(true)     // bridge to Jansi on Windows
                .system(true)    // attach to controlling TTY
                .build()) {

            Terminal.SignalHandler prev = term.handle(Terminal.Signal.INT, sig -> System.exit(0));
            term.enterRawMode();
            term.writer().println("press any key (q to quit):");
            term.writer().flush();

            int c;
            while ((c = term.reader().read()) != 'q') {
                term.writer().printf("0x%02x %n", c);
                term.writer().flush();
            }
        }
    }
}

Related sequences

Other languages