Cómo cambiar los colores de la consola con Java y System.out.println

13/02/2019
Artículo original

Hoy toca un truco sencillo pero útil.

Cuando programamos en Java estamos acostumbrados a enviar mensajes por la consola para informar a los usuarios de lo que va a ocurriendo. Para ello la manera por defecto de conseguirlo es mediante el uso del método System.out.println.

Este método, en principio, no permite cambiar el color de lo que se emite por pantalla. Todo se ve con el color predeterminado que tengamos, generalmente blanco (o gris claro) sobre fondo negro, algo así:

Sin embargo, cuando estamos creando una herramienta de línea de comandos nos puede resultar muy útil emplear otros colores para destacar cosas. Por ejemplo, usar el color rojo cuando se produzca una excepción y queramos avisar de ello tras haberla controlado, o el verde para cuando se lleve a cabo una tarea con éxito.

Nota: este tipo de usos del color para marcar significados no es accesible y por tanto no son apropiados si queremos que los puedan usar usuarios con problemas de visión, como por ejemplo los daltónicos que no distinguen entre rojo y verde. Asegúrate de que además de los colores utilizas algo más en el propio texto (mayúsculas, símbolos...) para indicar que se trata de un evento especial.

La buena noticia es que existen una serie de códigos de escape ANSI que nos permiten controlar ciertos aspectos de la consola, entre ellos los colores utilizados.

Si definimos las siguientes constantes en nuestro código:

public static final String ANSI_BLACK = "\u001B[30m";
public static final String ANSI_RED = "\u001B[31m";
public static final String ANSI_GREEN = "\u001B[32m";
public static final String ANSI_YELLOW = "\u001B[33m";
public static final String ANSI_BLUE = "\u001B[34m";
public static final String ANSI_PURPLE = "\u001B[35m";
public static final String ANSI_CYAN = "\u001B[36m";
public static final String ANSI_WHITE = "\u001B[37m";

Podremos utilizarlas para controlar el color que queremos mostrar con System.out.println.

Además podemos definir esta constante:

public static final String ANSI_RESET = "\u001B[0m";

que nos permitirá dejarlo todo como estaba y volver a los colores por defecto.

Así, podemos escribir lo siguiente:

System.out.println(ANSI_RED + "Texto de color rojo" + ANSI_RESET);

y veremos el color rojo como esperábamos:

dejando además la consola en su estado predeterminado, justo a continuación.

Del mismo modo podemos definir una serie de constantes para establecer el color de fondo que queremos usar con el texto, así:

public static final String ANSI_BLACK_BACKGROUND = "\u001B[40m";
public static final String ANSI_RED_BACKGROUND = "\u001B[41m";
public static final String ANSI_GREEN_BACKGROUND = "\u001B[42m";
public static final String ANSI_YELLOW_BACKGROUND = "\u001B[43m";
public static final String ANSI_BLUE_BACKGROUND = "\u001B[44m";
public static final String ANSI_PURPLE_BACKGROUND = "\u001B[45m";
public static final String ANSI_CYAN_BACKGROUND = "\u001B[46m";
public static final String ANSI_WHITE_BACKGROUND = "\u001B[47m"

Con ellas podemos establecer también el color de fondo y combinarlas con las anteriores para el color del texto, así:

System.out.println(ANSI_GREEN_BACKGROUND + ANSI_BLUE + "Texto de color azul sobre fondo verde");
System.out.println("Como no lo he resetado sigue igual.");
System.out.println("¡Reseteo ahora!" + ANSI_RESET);
System.out.println("FIN");

obteniendo esto por pantalla:

Si te fijas, mientras no le mandes el código de control de "reset" no se vuelve a establecer el color por defecto, por lo que podrías ir enviando comandos no visibles para cambio de color sin necesidad de escribir nada, y usarlos simplemente para ir controlando el cambio de colores.

Te dejo estos ejemplos (con las constantes, que es lo que te interesa) funcionando dentro de este repl.it.  Pulsa sobre el botón verde del triángulo para ejecutarlo y ver debajo los resultados:

Una pega: no funciona en Windows... Por defecto.

Esto que te acabo de enseñar funciona perfectamente en Mac y en Linux. Pero si lo intentas usar con Java en una consola de Windows verás que no te funciona.

Por suerte existe una biblioteca Open Source llamada JANSI que utiliza la Java Native Interface (JNI) para obtener los mismos resultados de manera coherente en todos los sistemas operativos, incluido Windows.

Solo tienes que descargarla, agregarla a tu proyecto y usar sus métodos específicos en vez de las constantes anteriores. Te funcionará también en el sistema de las ventanas. Mira la documentación en Github y verás que es muy sencillo.

¡Espero que te resulte útil!