web-dev-qa-db-fra.com

Comment colorer la sortie System.out.println?

Comment puis-je colorer la sortie Java? 

Par exemple, en C et dans d'autres langues, je peux utiliser ANSI-escape comme \033[0m pour le faire. Mais en Java, ça ne marche pas.

public static void main(String[] x) {
    System.out.println("\033[0m BLABLA \033[0m\n");
}
112
Davide Aversa

Non, mais il y a des API tierces qui peuvent le gérer.

http://www.javaworld.com/javaworld/javaqa/2002-12/02-qa-1220-console.html

Edit: bien sûr, il y a des articles plus récents que celui que j'ai posté, l'information est toujours viable.

26
Jonas B

Remarque

Vous ne pourrez peut-être pas colorer le cmd Prompt de Windows, mais cela devrait fonctionner dans de nombreux terminaux unix (ou similaires).

Notez également que certains terminaux ne prennent tout simplement pas en charge certaines séquences d’échappement ANSI (le cas échéant) et, en particulier, les couleurs 24 bits.

Usage

Veuillez vous référer à la section Curses en bas pour la meilleure solution. Pour une solution personnelle ou simple (bien que ne soit pas en tant que solution multiplate-forme), reportez-vous à la section Section ANSI Escape Sequences .


TL; DR

  • Java : System.out.println((char)27 + "[31m" + "ERROR MESSAGE IN RED");

  • python : print(chr(27) + "[31m" + "ERROR MESSAGE IN RED")

  • bash ou zsh : printf '\x1b[31mERROR MESSAGE IN RED'
    • cela peut également fonctionner pour Os X: printf '\e[31mERROR MESSAGE IN RED'
  • sh : printf 'CTRL+V,CTRL+[[31mERROR MESSAGE IN RED'
    • c.-à-d., appuyez sur CTRL + V puis sur CTRL + [ pour obtenir un "raw" ESC caractère lorsque l'interprétation d'échappement n'est pas disponible
    • Si cela est fait correctement, vous devriez voir un ^[. Bien que cela ressemble à deux personnages, ce n’est qu’un seul, le ESC personnage.
    • Vous pouvez également appuyer sur CTRL+V,CTRL+[ dans vim dans l’un des langages de programmation ou de sriptage, car il utilise un littéral ESC personnage
    • En outre, vous pouvez remplacer Ctrl+[ avec ESC … Par exemple, vous pouvez utiliser CTRL+V,ESC, mais je trouve le premier plus facile, car je presse déjà CTRL et depuis [ est moins à l'écart.

Séquences d'échappement ANSI

Contexte sur les séquences d'échappement

Bien que ce ne soit pas la meilleure façon de le faire, le moyen le plus simple de le faire dans un langage de programmation ou de script consiste à utiliser séquences d'échappement. De ce lien:

Une séquence d'échappement est une série de caractères utilisés pour modifier l'état des ordinateurs et des périphériques qui leur sont connectés. Celles-ci sont également connues sous le nom de séquences de contrôle, reflétant leur utilisation dans le contrôle de périphérique.

Fond sur les séquences d'échappement ANSI

Cependant, cela devient encore plus facile que cela dans les terminaux vidéo texte, puisque ces terminaux utilisent séquences d'échappement ANSI. De ce lien:

Les séquences d'échappement ANSI constituent un standard de signalisation dans la bande permettant de contrôler l'emplacement du curseur, la couleur et d'autres options sur les terminaux de texte vidéo. Certaines séquences d'octets, la plupart commençant par Esc et '[', sont incorporées dans le texte, que le terminal recherche et interprète comme des commandes et non comme des codes de caractères.

Comment utiliser les séquences d'échappement ANSI

Généralement

  • Les séquences d'échappement commencent par un caractère d'échappement; pour les séquences d'échappement ANSI, la séquence commence toujours par ESC (ASCII: 27/hex: 0x1B).
  • Pour une liste de ce que vous pouvez faire, reportez-vous à la Liste de séquences d'échappement ANSI sur Wikipedia

Dans les langages de programmation

Certaines langues de programmation (comme Java) n'interpréteront pas \e ou \x1b comme ESC personnage. Cependant, nous savons que le caractère ASCII 27 est le ESC caractère, nous pouvons donc simplement transtyper 27 en charet l’utiliser pour commencer la séquence d’échappement.

Voici quelques façons de le faire dans les langages de programmation courants:

  • Java

    • System.out.println((char)27 + "[33mYELLOW");
  • Python 3

    • print(chr(27) + "[34mBLUE");
    • print("\x1b[35mMAGENTA");
      • Notez que \x1b est interprété correctement en python
  • Nœud JS

    • Ce qui suit PAS le rendu des couleurs en JavaScript dans la console Web
    • console.log(String.fromCharCode(27) + "[36mCYAN");
    • console.log("\x1b[30;47mBLACK_ON_WHITE");
      • Notez que \x1b fonctionne également dans le noeud

Dans les scripts d'invite OR

Si vous travaillez avec bash ou zsh, il est assez facile de colorer la sortie (dans la plupart des terminaux). Sous Linux, Os X et dans certains terminaux Windows, vous pouvez vérifier si votre terminal prend en charge la couleur en effectuant les deux opérations suivantes:

  • printf '\e[31mRED'
  • printf '\x1b[31mRED'

Si vous voyez la couleur pour les deux, alors c'est génial! Si vous voyez de la couleur pour un seul, utilisez cette séquence. Si vous ne voyez pas de couleur pour l’un d’eux, vérifiez bien que vous avez tout saisi correctement et que vous êtes en bash ou zsh; si vous ne voyez toujours aucune couleur, votre terminal ne prend probablement pas en charge les séquences d'échappement ANSI.

Si je me souviens bien, les terminaux Linux ont tendance à prendre en charge les séquences d'échappement \e et \x1b, tandis que les terminaux os x ont tendance à ne supporter que \e, mais je peux me tromper. Néanmoins, si vous voyez quelque chose comme l'image suivante, vous êtes prêt! (Notez que j'utilise le shell zsh et qu'il colore la chaîne de mon invite; de ​​plus, j'utilise rxvt ​​comme terminal sous linux.)

ANSI Escape Sequences Coloring Text Red

"Comment ça marche?" pourriez-vous demander. Fondamentalement, printfinterprète la séquence de caractères qui suit (tout ce qui se trouve à l'intérieur de single-quotes). Lorsque printfrencontre \e ou \x1b, il convertira ces caractères en caractères ESC caractère (ASCII: 27). C'est juste ce que nous voulons. Maintenant, printfenvoie ESC31m, et puisqu'il existe un ESC suivi d'une séquence d'échappement ANSI valide, nous devrions obtenir une sortie colorée (tant qu'elle est prise en charge par le terminal).

Vous pouvez également utiliser echo -e '\e[32mGREEN' (par exemple) pour colorer la sortie. Notez que l'indicateur -e pour echo"[active] l'interprétation des échappements de barre oblique inverse" et doit être utilisé si vous souhaitez que echointerprète correctement la séquence d'échappement.


En savoir plus sur les séquences d'échappement ANSI

Les séquences d'échappement ANSI peuvent faire plus que simplement produire des couleurs, mais commençons par cela et voyons exactement comment fonctionne la couleur; ensuite, nous verrons comment manipuler le curseur; Enfin, nous verrons comment utiliser les couleurs 8 bits et 24 bits (bien que le support ne soit que ténu).

Sur Wikipedia , ils font référence à ESC[ comme CSIname__, je ferai de même.

Couleur

Pour colorer la sortie à l'aide d'échappements ANSI, utilisez ce qui suit:

  • CSIn__ m
    • CSIname__: caractère d'échappement —^[[ ou ESC[
    • nname__: un nombre - l'un des suivants:
      • 30-37, 39: au premier plan
      • 40-47, 49: arrière-plan
    • mname__: un littéral ASCII mname __— met fin à la séquence d'échappement

J'utiliserai bash ou zsh pour démontrer toutes les combinaisons de couleurs possibles. Plop pour savoir par vous-même dans bash ou zsh (vous devrez peut-être remplacer \e par \x1b):

  • for fg in {30..37} 39; do for bg in {40..47} 49; do printf "\e[${fg};${bg}m~TEST~"; done; printf "\n"; done;

Résultat:

various foreground/background colors using ANSI escapes

Référence rapide (couleur)

+~~~~~~+~~~~~~+~~~~~~~~~~~+
|  fg  |  bg  |  color    |
+~~~~~~+~~~~~~+~~~~~~~~~~~+
|  30  |  40  |  black    |
|  31  |  41  |  red      |
|  32  |  42  |  green    |
|  33  |  43  |  yellow   |
|  34  |  44  |  blue     |
|  35  |  45  |  Magenta  |
|  36  |  46  |  cyan     |
|  37  |  47  |  white    |
|  39  |  49  |  default  |
+~~~~~~+~~~~~~+~~~~~~~~~~~+

Sélectionner le rendu graphique (SGR)

SGR vous permet simplement de changer le texte. Beaucoup d'entre eux ne fonctionnent pas dans certains terminaux, utilisez-les donc avec parcimonie dans les projets au niveau de la production. Cependant, ils peuvent être utiles pour rendre la sortie du programme plus lisible ou pour vous aider à distinguer différents types de sortie.

La couleur tombe en fait sous SGR, donc la syntaxe est la même:

  • CSIn__ m
    • CSIname__: caractère d'échappement —^[[ ou ESC[
    • nname__: un nombre - l'un des suivants:
      • 0: réinitialiser
      • 1-9: active divers effets de texte
      • 21-29: désactive divers effets de texte (moins pris en charge que 1-9)
      • 30-37, 39: couleur de premier plan
      • 40-47, 49: couleur de fond
      • 38: couleur de premier plan 8 ou 24 bits (voir Couleur 8/24 bits ci-dessous)
      • 48: Couleur d'arrière-plan 8 ou 24 bits (voir Couleur 8/24 bits ci-dessous)
    • mname__: un littéral ASCII mname __— met fin à la séquence d'échappement

Bien qu’il existe un support ténu pour évanouissement (2), italique (3), souligné (4), clignotant (5,6), vidéo inverse (7), masquer (8) et barré (9), certains (mais rarement tous) ont tendance à fonctionner sur les terminaux linux et os x.

Il est également intéressant de noter que vous pouvez séparer n'importe lequel des attributs ci-dessus par un point-virgule. Par exemple, printf '\e[34;47;1;3mCRAZY TEXT\n' affichera CRAZY TEXT avec un blue foreground sur un white background, et sera boldet italicname__.

Par exemple:

string attributes together example screenshot

Ajoutez ce qui suit dans votre shell bash ou zsh pour voir tous les effets de texte que vous pouvez faire. (Vous devrez peut-être remplacer \e par \x1b.)

  • for i in {1..9}; do printf "\e[${i}m~TEST~\e[0m "; done

Résultat:

SGR state 1SGR state 2

Vous pouvez voir que mon terminal supporte tous les effets de texte à l'exception de pour faible (2), masquer (8) et barrer (9).

Référence rapide (attributs SGR 0 à 9)

+~~~~~+~~~~~~~~~~~~~~~~~~+
|  n  |  effect          |
+~~~~~+~~~~~~~~~~~~~~~~~~+
|  0  |  reset           |
|  1  |  bold            |
|  2  |  faint*          |
|  3  |  italic**        |
|  4  |  underline       |
|  5  |  slow blink      |
|  6  |  rapid blink*    |
|  7  |  inverse         |
|  8  |  conceal*        |
|  9  |  strikethrough*  |
+~~~~~+~~~~~~~~~~~~~~~~~~+

* not widely supported
** not widely supported and sometimes treated as inverse

Couleur 8 bits

Bien que la plupart des terminaux le prennent en charge, il est moins pris en charge que les couleurs 0-7, 9.

Syntaxe:

  • CSI38;5;nmname __
    • CSIname__: caractère d'échappement —^[[ ou ESC[
    • 38;5;: chaîne littérale indiquant l'utilisation de couleurs 8 bits pour le premier plan
    • nname__: un nombre - l'un des suivants:
      • 0-255

Si vous souhaitez prévisualiser toutes les couleurs de votre terminal de manière agréable, il vous faut n script agréable sur Gist.github.com .

Cela ressemble à ceci:

8-bit color example screenshot

Si vous souhaitez modifier l’arrière-plan à l’aide de couleurs 8 bits, il vous suffit de remplacer le 38 par un 48:

  • CSI48;5;nmname __
    • CSIname__: caractère d'échappement —^[[ ou ESC[
    • 48;5;: chaîne littérale indiquant l'utilisation de couleurs 8 bits pour l'arrière-plan
    • nname__: un nombre - l'un des suivants:
      • 0-255

Couleur 24 bits

Également appelée couleur vraie, la couleur 24 bits offre des fonctionnalités vraiment intéressantes. La prise en charge de ce problème est définitivement croissante (pour autant que je sache, cela fonctionne dans la plupart des terminaux modernes, à l'exception de rxvt, mon terminal [insérer un emoji en colère]).

La couleur 24 bits est actuellement prise en charge dans vim (voir vim wiki pour savoir comment activer les couleurs 24 bits). C'est vraiment chouette parce que ça tire de la palette de couleurs définie pour gvim; Par exemple, il utilise le fg/bg de highlight guibg=#______ guifg=#______ pour les couleurs 24 bits! Neato, hein?

Voici comment fonctionne la couleur 24 bits:

  • CSI38;2;r;g;bmnom __
    • CSIname__: caractère d'échappement —^[[ ou ESC[
    • 38;2;: chaîne littérale indiquant l'utilisation de couleurs 24 bits pour le premier plan
    • rname __, gname __, bname__: nombres — chacun devrait être 0-255

Pour tester juste quelques-uns parmi les nombreuses couleurs que vous pouvez avoir (possibilités (2^8)^3 ou 2^24 ou 16777216, je pense), vous pouvez utiliser ceci en bash ou en zsh:

  • for r in 0 127 255; do for g in 0 127 255; do for b in 0 127 255; do printf "\e[38;2;${r};${g};${b}m($r,$g,$b)\e[0m "; done; printf "\n"; done; done;

Résultat (il s'agit de gnome-terminal puisque rxvt ​​NE PREND PAS EN CHARGE la couleur 24 bits . .. rassemblez-vous, responsable urxvt ... pour de vrai):

24-bit color example screenshot

Si vous voulez des couleurs 24 bits pour l'arrière-plan ... vous l'avez deviné! Vous venez de remplacer 38 par 48:

  • CSI48;2;r;g;bmnom __
    • CSIname__: caractère d'échappement —^[[ ou ESC[
    • 48;2;: chaîne littérale indiquant l'utilisation de couleurs 24 bits pour l'arrière-plan
    • rname __, gname __, bname__: nombres — chacun devrait être 0-255

Insertion de séquences d'échappement brutes

Parfois, \e et \x1b ne fonctionneront pas. Par exemple, dans le sh Shell, parfois ni ne fonctionne (même si cela fonctionne sur mon système maintenant , je ne pense pas il l'habitude de).

Pour contourner cela, vous pouvez utiliser CTRL+V,CTRL+[ ou CTRLV,ESC

Cela va insérer un "raw" ESC caractère (ASCII: 27). Cela ressemblera à ceci ^[, mais ne vous inquiétez pas; ce n'est qu'un caractère, pas deux.

Par exemple:

sh raw escape char example screenshot


Les malédictions

Reportez-vous à la page Curses (Programming Library) pour obtenir une référence complète sur les curses. Il est à noter que curses ne fonctionne que sur les systèmes d'exploitation Unix et de type Unix.

Up and Running avec Curses

Je n'entrerai pas dans les détails, car les moteurs de recherche peuvent révéler des liens vers des sites Web qui expliquent cela mieux que moi, mais je vais en parler brièvement ici et donner un exemple.

Pourquoi utiliser Curses Over ANSI Escapes?

Si vous lisez le texte ci-dessus, vous vous souviendrez peut-être que \e ou \x1b fonctionnera parfois avec printfname__. Eh bien, parfois, \e et \x1b ne fonctionnent pas du tout (ce n'est pas standard et je n'ai jamais travaillé avec un terminal comme celui-ci, mais c'est possible). Plus important encore, des séquences d’échappement plus complexes Home et autres clés multi-caractères) sont difficiles à prendre en charge pour chaque terminal (à moins que vous ne souhaitiez consacrer beaucoup de temps et d’efforts à analyser terminfo et termcap et à comprendre comment gérer chaque terminal).

Les malédictions résolvent ce problème. Fondamentalement, il est capable de comprendre les capacités d’un terminal en utilisant ces méthodes (comme décrit dans l’article de Wikipédia lié ci-dessus):

La plupart des implémentations de curses utilisent une base de données pouvant décrire les capacités de milliers de terminaux différents. Il existe quelques implémentations, telles que PDCurses, qui utilisent des pilotes de périphérique spécialisés plutôt qu'une base de données de terminaux. La plupart des implémentations utilisent terminfo; certains utilisent termcap. Curses présente l'avantage de la portabilité vers les terminaux à cellules de caractères et de sa simplicité. Pour une application ne nécessitant pas de graphiques bitmap ou de polices multiples, l'implémentation d'une interface à l'aide de curses sera généralement beaucoup plus simple et plus rapide qu'une application utilisant un toolkit X.

La plupart du temps, les curses interrogeront terminfo et pourront alors comprendre comment manipuler les attributs de curseur et de texte. Ensuite, vous, le programmeur, utilisez l’API fournie par curses pour manipuler le curseur ou modifier la couleur du texte ou d’autres attributs si la fonctionnalité recherchée est souhaitée.

Exemple avec Python

Je trouve que python est vraiment facile à utiliser, mais si vous voulez utiliser des sorts dans un autre langage de programmation, recherchez-le simplement sur duckduckgo ou sur tout autre moteur de recherche. :) Voici un exemple rapide en python 3:

import curses

def main(stdscr):
    # allow curses to use default foreground/background (39/49)
    curses.use_default_colors()

    # Clear screen
    stdscr.clear()

    curses.init_pair(1, curses.COLOR_RED, -1)
    curses.init_pair(2, curses.COLOR_GREEN, -1)
    stdscr.addstr("ERROR: I like tacos, but I don't have any.\n", curses.color_pair(1))
    stdscr.addstr("SUCCESS: I found some tacos.\n", curses.color_pair(2))

    stdscr.refresh() # make sure screen is refreshed
    stdscr.getkey()  # wait for user to press key

if __== '__main__':
    curses.wrapper(main)

résultat:

enter image description here

Vous pourriez penser à vous-même que c'est une façon de faire les choses beaucoup plus ronde, mais c'est vraiment beaucoup plus multi-plateforme (vraiment multi-terminal… au moins dans le monde des plates-formes unix et analogues à unix). Pour les couleurs, ce n’est pas assez aussi important, mais quand il s’agit de prendre en charge d’autres séquences d’échappement multi-séquences (telles que HomeEndPage UpPage Down, etc), alors les malédictions deviennent d’autant plus importantes.

Exemple avec Tput

  • tputest un utilitaire de ligne de commande permettant de manipuler le curseur et le texte.
  • tputest fourni avec le package cursesname__. Si vous souhaitez utiliser des applications inter-terminaux (ish) dans le terminal, vous devez utiliser tput, car il analyse terminfo ou ce dont il a besoin, utilise un ensemble de commandes normalisées (comme des curses) et renvoie la séquence d'échappement correcte.
  • exemple:
echo "$(tput setaf 1)$(tput bold)ERROR:$(tput sgr0)$(tput setaf 1) My tacos have gone missing"
echo "$(tput setaf 2)$(tput bold)SUCCESS:$(tput sgr0)$(tput setaf 2) Oh good\! I found my tacos\!"

Résultat:

example with tput

Plus d'infos sur Tput

104
dylnmc

Cela a fonctionné pour moi:

System.out.println((char)27 + "[31mThis text would show up red" + (char)27 + "[0m");

Vous avez besoin de la fin "[37m" pour que la couleur redevienne blanche (ou celle que vous utilisiez). Sinon, tout ce qui suit sera "rouge".

31
DanP

Vous pouvez utiliser la bibliothèque JANSI pour afficher les séquences d'échappement ANSI sous Windows. 

11
MrDrews

Oui c'est 100% possible 

set classpath =% classpath%; d:\jansi-1.4.jar;

Essayez ce code ci-dessous:

import org.fusesource.jansi.AnsiConsole;
import static org.fusesource.jansi.Ansi.*;
import static org.fusesource.jansi.Ansi.Color.*;

public class Sample

{

  public static void main(String[] args)
  {
    AnsiConsole.systemInstall();

    System.out.println(ansi().fg(RED).a("Hello World").reset());
    System.out.println("My Name is Raman");

    AnsiConsole.systemUninstall();
  }
}
10
Raman

Voici une solution pour la console Win32.

1) Obtenez les bibliothèques JavaNativeAccess ici: https://github.com/twall/jna/

2) Ces deux classes Java feront l'affaire.

Prendre plaisir.

package com.stackoverflow.util;

import com.Sun.jna.Library;
import com.Sun.jna.Native;
import com.Sun.jna.Platform;
import com.Sun.jna.Structure;

public class Win32 {
    public static final int STD_INPUT_HANDLE = -10;
    public static final int STD_OUTPUT_HANDLE = -11;
    public static final int STD_ERROR_HANDLE = -12;

    public static final short CONSOLE_FOREGROUND_COLOR_BLACK        = 0x00;
    public static final short CONSOLE_FOREGROUND_COLOR_BLUE         = 0x01;
    public static final short CONSOLE_FOREGROUND_COLOR_GREEN        = 0x02;
    public static final short CONSOLE_FOREGROUND_COLOR_AQUA         = 0x03;
    public static final short CONSOLE_FOREGROUND_COLOR_RED          = 0x04;
    public static final short CONSOLE_FOREGROUND_COLOR_PURPLE       = 0x05;
    public static final short CONSOLE_FOREGROUND_COLOR_YELLOW       = 0x06;
    public static final short CONSOLE_FOREGROUND_COLOR_WHITE        = 0x07;
    public static final short CONSOLE_FOREGROUND_COLOR_GRAY         = 0x08;
    public static final short CONSOLE_FOREGROUND_COLOR_LIGHT_BLUE   = 0x09;
    public static final short CONSOLE_FOREGROUND_COLOR_LIGHT_GREEN  = 0x0A;
    public static final short CONSOLE_FOREGROUND_COLOR_LIGHT_AQUA   = 0x0B;
    public static final short CONSOLE_FOREGROUND_COLOR_LIGHT_RED    = 0x0C;
    public static final short CONSOLE_FOREGROUND_COLOR_LIGHT_PURPLE = 0x0D;
    public static final short CONSOLE_FOREGROUND_COLOR_LIGHT_YELLOW = 0x0E;
    public static final short CONSOLE_FOREGROUND_COLOR_BRIGHT_WHITE = 0x0F;

    public static final short CONSOLE_BACKGROUND_COLOR_BLACK        = 0x00;
    public static final short CONSOLE_BACKGROUND_COLOR_BLUE         = 0x10;
    public static final short CONSOLE_BACKGROUND_COLOR_GREEN        = 0x20;
    public static final short CONSOLE_BACKGROUND_COLOR_AQUA         = 0x30;
    public static final short CONSOLE_BACKGROUND_COLOR_RED          = 0x40;
    public static final short CONSOLE_BACKGROUND_COLOR_PURPLE       = 0x50;
    public static final short CONSOLE_BACKGROUND_COLOR_YELLOW       = 0x60;
    public static final short CONSOLE_BACKGROUND_COLOR_WHITE        = 0x70;
    public static final short CONSOLE_BACKGROUND_COLOR_GRAY         = 0x80;
    public static final short CONSOLE_BACKGROUND_COLOR_LIGHT_BLUE   = 0x90;
    public static final short CONSOLE_BACKGROUND_COLOR_LIGHT_GREEN  = 0xA0;
    public static final short CONSOLE_BACKGROUND_COLOR_LIGHT_AQUA   = 0xB0;
    public static final short CONSOLE_BACKGROUND_COLOR_LIGHT_RED    = 0xC0;
    public static final short CONSOLE_BACKGROUND_COLOR_LIGHT_PURPLE = 0xD0;
    public static final short CONSOLE_BACKGROUND_COLOR_LIGHT_YELLOW = 0xE0;
    public static final short CONSOLE_BACKGROUND_COLOR_BRIGHT_WHITE = 0xF0;

    // typedef struct _COORD {
    //    SHORT X;
    //    SHORT Y;
    //  } COORD, *PCOORD;
    public static class COORD extends Structure {
        public short X;
        public short Y;
    }

    // typedef struct _SMALL_RECT {
    //    SHORT Left;
    //    SHORT Top;
    //    SHORT Right;
    //    SHORT Bottom;
    //  } SMALL_RECT;
    public static class SMALL_RECT extends Structure {
        public short Left;
        public short Top;
        public short Right;
        public short Bottom;
    }

    // typedef struct _CONSOLE_SCREEN_BUFFER_INFO {
    //    COORD      dwSize;
    //    COORD      dwCursorPosition;
    //    Word       wAttributes;
    //    SMALL_RECT srWindow;
    //    COORD      dwMaximumWindowSize;
    //  } CONSOLE_SCREEN_BUFFER_INFO;
    public static class CONSOLE_SCREEN_BUFFER_INFO extends Structure {
        public COORD dwSize;
        public COORD dwCursorPosition;
        public short wAttributes;
        public SMALL_RECT srWindow;
        public COORD dwMaximumWindowSize;
    }

    // Source: https://github.com/twall/jna/nonav/javadoc/index.html
    public interface Kernel32 extends Library {
        Kernel32 DLL = (Kernel32) Native.loadLibrary("kernel32", Kernel32.class);

        // HANDLE WINAPI GetStdHandle(
        //        __in  DWORD nStdHandle
        //      );
        public int GetStdHandle(
                int nStdHandle);

        // BOOL WINAPI SetConsoleTextAttribute(
        //        __in  HANDLE hConsoleOutput,
        //        __in  Word wAttributes
        //      );
        public boolean SetConsoleTextAttribute(
                int in_hConsoleOutput, 
                short in_wAttributes);

        // BOOL WINAPI GetConsoleScreenBufferInfo(
        //        __in   HANDLE hConsoleOutput,
        //        __out  PCONSOLE_SCREEN_BUFFER_INFO lpConsoleScreenBufferInfo
        //      );
        public boolean GetConsoleScreenBufferInfo(
                int in_hConsoleOutput,
                CONSOLE_SCREEN_BUFFER_INFO out_lpConsoleScreenBufferInfo);

        // DWORD WINAPI GetLastError(void);
        public int GetLastError();
    }
}
package com.stackoverflow.util;

import Java.io.PrintStream;

import com.stackoverflow.util.Win32.Kernel32;

public class ConsoleUtil {
    public static void main(String[] args)
    throws Exception {
        System.out.print("abc");
        static_color_print(
                System.out, 
                "def", 
                Win32.CONSOLE_BACKGROUND_COLOR_RED, 
                Win32.CONSOLE_FOREGROUND_COLOR_BRIGHT_WHITE);
        System.out.print("def");
        System.out.println();
    }

    private static Win32.CONSOLE_SCREEN_BUFFER_INFO _static_console_screen_buffer_info = null; 

    public static void static_save_settings() {
        if (null == _static_console_screen_buffer_info) {
            _static_console_screen_buffer_info = new Win32.CONSOLE_SCREEN_BUFFER_INFO();
        }
        int stdout_handle = Kernel32.DLL.GetStdHandle(Win32.STD_OUTPUT_HANDLE);
        Kernel32.DLL.GetConsoleScreenBufferInfo(stdout_handle, _static_console_screen_buffer_info);
    }

    public static void static_restore_color()
    throws Exception {
        if (null == _static_console_screen_buffer_info) {
            throw new Exception("Internal error: Must save settings before restore");
        }
        int stdout_handle = Kernel32.DLL.GetStdHandle(Win32.STD_OUTPUT_HANDLE);
        Kernel32.DLL.SetConsoleTextAttribute(
                stdout_handle, 
                _static_console_screen_buffer_info.wAttributes);
    }

    public static void static_set_color(Short background_color, Short foreground_color) {
        int stdout_handle = Kernel32.DLL.GetStdHandle(Win32.STD_OUTPUT_HANDLE);
        if (null == background_color || null == foreground_color) {
            Win32.CONSOLE_SCREEN_BUFFER_INFO console_screen_buffer_info = 
                new Win32.CONSOLE_SCREEN_BUFFER_INFO();
            Kernel32.DLL.GetConsoleScreenBufferInfo(stdout_handle, console_screen_buffer_info);
            short current_bg_and_fg_color = console_screen_buffer_info.wAttributes;
            if (null == background_color) {
                short current_bg_color = (short) (current_bg_and_fg_color / 0x10);
                background_color = new Short(current_bg_color);
            }
            if (null == foreground_color) {
                short current_fg_color = (short) (current_bg_and_fg_color % 0x10);
                foreground_color = new Short(current_fg_color);
            }
        }
        short bg_and_fg_color = 
            (short) (background_color.shortValue() | foreground_color.shortValue());
        Kernel32.DLL.SetConsoleTextAttribute(stdout_handle, bg_and_fg_color);
    }

    public static<T> void static_color_print(
            PrintStream ostream, 
            T value, 
            Short background_color, 
            Short foreground_color)
    throws Exception {
        static_save_settings();
        try {
            static_set_color(background_color, foreground_color);
            ostream.print(value);
        }
        finally {
            static_restore_color();
        }
    }

    public static<T> void static_color_println(
            PrintStream ostream, 
            T value, 
            Short background_color, 
            Short foreground_color)
    throws Exception {
        static_save_settings();
        try {
            static_set_color(background_color, foreground_color);
            ostream.println(value);
        }
        finally {
            static_restore_color();
        }
    }
}
5
kevinarpe

J'ai créé une bibliothèque jar appelée JCDP (Imprimante de débogage couleur Java).

Pour Linux, il utilise les codes d’échappement ANSI mentionnés par WhiteFang, mais les résume en utilisant des mots au lieu de codes, ce qui est beaucoup plus intuitif.

Pour Windows, il inclut la bibliothèque JAnsi mais crée une couche d’abstraction sur celle-ci, en maintenant l’interface intuitive et simple créée pour Linux.

Cette bibliothèque est disponible sous la licence MIT , alors n'hésitez pas à l'utiliser.

Jetez un oeil sur le dépôt github de JCDP .

4
dialex

La méthode la plus simple consiste à exécuter votre programme (non modifié) dans la console Cygwin.

La deuxième méthode la plus simple consiste à exécuter votre programme (également non modifié) dans la console Windows ordinaire, en canalisant sa sortie via tee.exe (à partir de la distribution Cygwin ou Git). Tee.exe reconnaîtra les codes d'échappement et appellera les fonctions WinAPI appropriées.

Quelque chose comme:

Java MyClass | tee.exe log.txt
Java MyClass | tee.exe /dev/null
3
user222202

Les séquences d'échappement doivent être interprétées par SOMETHING pour être converties en couleur. Le CMD.EXE standard utilisé par Java lors du démarrage à partir de la ligne de commande ne le supporte pas, donc pas Java.

2

Check This Out: J'ai utilisé les valeurs ANSI avec le code d'échappement et cela ne fonctionne probablement pas dans la commande windows Invite, mais dans les IDE et Unix Shell . Vous pouvez également vérifier la bibliothèque 'Jansi' ici pour le support Windows.

System.out.println("\u001B[35m" + "This text is PURPLE!" + "\u001B[0m");
1

System.err.println ("Errorrrrrr") imprimera le texte en rouge sur la console.

0
Kamran

J'ai écrit une bibliothèque appelée AnsiScape qui vous permet d'écrire des sorties en couleurs de manière plus structurée:

Exemple:

AnsiScape ansiScape = new AnsiScape();
String colors = ansiScape.format("{red {blueBg Red text with blue background}} {b Bold text}");
System.out.println(colors);

La bibliothèque vous permet également de définir vos propres "classes d'échappement", semblables à des classes css.

Exemple:

AnsiScapeContext context = new AnsiScapeContext();

// Defines a "class" for text
AnsiClass text = AnsiClass.withName("text").add(RED);
// Defines a "class" for the title used
AnsiClass title = AnsiClass.withName("title").add(BOLD, BLUE_BG, YELLOW);
// Defines a "class" to render urls
AnsiClass url = AnsiClass.withName("url").add(BLUE, UNDERLINE);

// Registering the classes to the context
context.add(text).add(title).add(url);

// Creating an AnsiScape instance with the custom context
AnsiScape ansiScape = new AnsiScape(context);

String fmt = "{title Chapter 1}\n" +
              "{text So it begins:}\n" +
              "- {text Option 1}\n" +
              "- {text Url: {url www.someurl.xyz}}";

System.out.println(ansiScape.format(fmt));
0
Andrei Ciobanu