Как раскрасить вывод System.out.println?

Как я могу раскрасить вывод Java?

Например, в C и других языках я могу использовать ANSI-escape, например \033[0m, чтобы сделать это. Но в Java это не работает.

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

person Davide Aversa    schedule 19.09.2009    source источник


Ответы (13)


Нет, но есть сторонние API, которые могут с этим справиться

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

Изменить: конечно, есть более новые статьи, чем та, которую я опубликовал, но информация все еще актуальна.

Ссылка выше не работает, вместо этого см. этот вопрос: Как печатать цвет в консоли с помощью System.out.println?

person Jonas B    schedule 19.09.2009
comment
В этом сообщении есть хороший ответ stackoverflow.com/a/5762502/70535 - person codecraig; 11.06.2015
comment
Ссылка сейчас не работает - person YektaDev; 08.12.2020

Примечание

Возможно, вы не сможете раскрасить cmd prompt окна, но это должно работать на многих терминалах unix (или подобных unix).

Также обратите внимание, что некоторые терминалы просто не будут поддерживать некоторые (если таковые имеются) управляющие последовательности ANSI и особенно 24-битные цвета.

использование

Найдите лучшее решение в разделе Проклятия внизу. Индивидуальное или простое решение (хотя не как кросс-платформенное решение) см. в разделе Escape-последовательности ANSI.


TL;DR

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

  • питон: print(chr(27) + "[31m" + "ERROR MESSAGE IN RED")

  • bash or zsh: printf '\x1b[31mERROR MESSAGE IN RED'
    • this may also work for Os X: printf '\e[31mERROR MESSAGE IN RED'
  • sh: printf 'CTRL+V,CTRL+[[31mERROR MESSAGE IN RED'
    • ie, press CTRL+V and then CTRL+[ in order to get a "raw" ESC character when escape interpretation is not available
    • Если все сделано правильно, вы должны увидеть ^[. Хотя это выглядит как два символа, на самом деле это всего лишь один символ ESC.
    • Вы также можете нажать CTRL+V,CTRL+[ в vim в любом языков программирования или написания сценариев, поскольку в них используется буквальный символ ESC
    • Кроме того, вы можете заменить Ctrl+[ на ESC… например, вы можете использовать CTRL+V ,ESC, но первое мне кажется проще, так как я уже нажимаю CTRL и поскольку [ меньше мешает .

Escape-последовательности ANSI

Общие сведения об управляющих последовательностях

Хотя это не лучший способ сделать это, самый простой способ сделать это на языке программирования или скриптов — использовать экранирующие последовательности. Из этой ссылки:

Escape-последовательность — это последовательность символов, используемая для изменения состояния компьютеров и подключенных к ним периферийных устройств. Они также известны как управляющие последовательности, что отражает их использование в управлении устройством.

Предыстория управляющих последовательностей ANSI

Однако это становится еще проще, чем в текстовых видеотерминалах, так как эти терминалы используют экранирующие последовательности ANSI. Из этой ссылки:

Управляющие последовательности ANSI являются стандартом внутриполосной сигнализации для управления положением курсора, цветом и другими параметрами текстовых видеотерминалов. Определенные последовательности байтов, большинство из которых начинаются с Esc и '[', встроены в текст, который терминал ищет и интерпретирует как команды, а не как коды символов.

Как использовать управляющие последовательности ANSI

В целом

На языках программирования

Некоторые языки программирования (например, Java) не интерпретируют \e или \x1b как символ ESC. Однако мы знаем, что символ ASCII 27 является символом ESC, поэтому мы можем просто привести тип 27 к char и использовать его для начала управляющей последовательности.

Вот несколько способов сделать это на распространенных языках программирования:

  • Ява

    • System.out.println((char)27 + "[33mYELLOW");
  • Питон 3

    • print(chr(27) + "[34mBLUE");
    • print("\x1b[35mMAGENTA");
      • Note that \x1b is interpretted correctly in python
  • JS-узел

    • The following will NOT color output in JavaScript in the Web Console
    • console.log(String.fromCharCode(27) + "[36mCYAN");
    • console.log("\x1b[30;47mBLACK_ON_WHITE");
      • Note that \x1b also works in node

В приглашении оболочки ИЛИ сценариях

Если вы работаете с bash или zsh, довольно легко раскрасить вывод (в большинстве терминалов). В Linux, Os X и некоторых терминалах Windows вы можете проверить, поддерживает ли ваш терминал цвет, выполнив оба следующих действия:

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

Если вы видите цвет для обоих, то это здорово! Если вы видите цвет только для одного, используйте эту последовательность. Если вы не видите цвет ни для одного из них, дважды проверьте, что вы все набрали правильно и что вы находитесь в bash или zsh; если вы по-прежнему не видите никакого цвета, возможно, ваш терминал не поддерживает управляющие последовательности ANSI.

Если я правильно помню, терминалы Linux, как правило, поддерживают escape-последовательности как \e, так и \x1b, в то время как терминалы OS X поддерживают только \e, но я могу ошибаться. Тем не менее, если вы видите что-то вроде следующего изображения, то все готово! (Обратите внимание, что я использую оболочку zsh, и она окрашивает мою строку приглашения; кроме того, я использую urxvt в качестве терминала в Linux.)

Управляющие последовательности ANSI окрашивают текст в красный цвет

"Как это работает?" спросите вы. По сути, printf интерпретирует следующую последовательность символов (все, что заключено в одинарные кавычки). Когда printf встречается с \e или \x1b, он преобразует эти символы в символ ESC (ASCII: 27). Это именно то, что мы хотим. Теперь printf отправляет ESC31m, и, поскольку есть ESC, за которым следует правильная управляющая последовательность ANSI, мы должны получить цветной вывод (если он поддерживается терминалом). ).

Вы также можете использовать echo -e '\e[32mGREEN' (например) для цветного вывода. Обратите внимание, что флаг -e для echo "[включает] интерпретацию escape-последовательностей с обратной косой чертой" и должен использоваться, если вы хотите, чтобы echo правильно интерпретировал escape-последовательность.


Подробнее об управляющих последовательностях ANSI

Управляющие последовательности ANSI могут делать больше, чем просто вывод цвета, но давайте начнем с этого и посмотрим, как именно работает цвет; затем мы увидим, как манипулировать курсором; наконец, мы посмотрим и посмотрим, как использовать 8-битный цвет, а также 24-битный цвет (хотя он имеет лишь незначительную поддержку).

В Википедии они ссылаются на ESC[ как CSI, так и я поступлю так же.

Цвет

Для раскрашивания вывода с помощью escape-последовательности ANSI используйте следующее:

  • CSI n m
    • CSI: escape character—^[[ or ESC[
    • n: a number—one of the following:
      • 30-37, 39: foreground
      • 40-47, 49: фон
    • m: литерал ASCII m — завершает управляющую последовательность.

Я буду использовать bash или zsh, чтобы продемонстрировать все возможные комбинации цветов. Вставьте следующее в bash или zsh, чтобы убедиться в этом (возможно, вам придется заменить \e на \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;

Результат:

различные цвета переднего плана/фона с использованием escape-последовательности ANSI

Краткий справочник (цвет)

+~~~~~~+~~~~~~+~~~~~~~~~~~+
|  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  |
+~~~~~~+~~~~~~+~~~~~~~~~~~+

Выберите графическое представление (SGR)

SGR просто позволяет вам изменить текст. Многие из них не работают на определенных терминалах, поэтому используйте их с осторожностью в проектах производственного уровня. Однако они могут быть полезны, чтобы сделать программный вывод более читабельным или помочь вам различать разные типы вывода.

Цвет на самом деле подпадает под SGR, поэтому синтаксис такой же:

  • CSI n m
    • CSI: escape character—^[[ or ESC[
    • n: a number—one of the following:
      • 0: reset
      • 1-9: включает различные текстовые эффекты
      • 21-29: отключает различные текстовые эффекты (поддерживается меньше, чем 1-9)
      • 30-37, 39: основной цвет
      • 40-47, 49: цвет фона
      • 38: 8- или 24-битный цвет переднего плана (см. 8/24-битный цвет ниже)
      • 48: 8- или 24-битный цвет фона (см. 8/24-битный цвет ниже)
    • m: литерал ASCII m — завершает управляющую последовательность.

Хотя есть только незначительная поддержка для слабого (2), курсивного (3), подчеркнутого (4), мигающего (5,6), обратного видео (7), скрытого (8) и зачеркнутого (9), некоторые (но редко все), как правило, работают на терминалах Linux и OS X.

Также стоит отметить, что любой из вышеперечисленных атрибутов можно отделить точкой с запятой. Например, printf '\e[34;47;1;3mCRAZY TEXT\n' покажет CRAZY TEXT с blue foreground на white background, и это будут bold и italic.

Eg:

Снимок экрана примера строковых атрибутов

Поместите следующее в оболочку bash или zsh, чтобы увидеть все текстовые эффекты, которые вы можете сделать. (Возможно, вам придется заменить \e на \x1b.)

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

Результат:

«Состояние SGR состояние 2

Как видите, мой терминал поддерживает все текстовые эффекты, кроме для бледного (2), скрытия (8) и зачеркнутого (9).

Краткий справочник (атрибуты 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

8-битный цвет

Хотя это поддерживается большинством терминалов, он поддерживается меньше, чем 0-7, 9 цветов.

Синтаксис:

  • CSI 38;5; n m
    • CSI: escape character—^[[ or ESC[
    • 38;5;: литеральная строка, обозначающая использование 8-битных цветов для переднего плана.
    • n: a number—one of the following:
      • 0-255

Если вы хотите хорошо просмотреть все цвета в своем терминале, у меня есть хороший скрипт по существу. github.com.

Это выглядит так:

Пример скриншота с 8-битным цветом

Если вы хотите изменить фон, используя 8-битные цвета, просто замените 38 на 48:

  • CSI 48;5; n m
    • CSI: escape character—^[[ or ESC[
    • 48;5;: литеральная строка, обозначающая использование 8-битных цветов для фона.
    • n: a number—one of the following:
      • 0-255

24-битный цвет

Также известный как истинный цвет, 24-битный цвет обеспечивает некоторые действительно интересные функции. Поддержка этого определенно растет (насколько я знаю, это работает в большинстве современных терминалов, кроме urxvt, моего терминала [вставьте злой смайлик]).

24-битный цвет фактически поддерживается в vim (см. vim wiki, чтобы узнать, как включить 24-битный цвет). битовые цвета). Это действительно здорово, потому что оно основано на цветовой схеме, определенной для gvim; например, он использует fg/bg из highlight guibg=#______ guifg=#______ для 24-битных цветов! Неато, да?

Вот как работает 24-битный цвет:

  • CSI 38;2; r ; g ; b m
    • CSI: escape character—^[[ or ESC[
    • 38;2;: литеральная строка, обозначающая использование 24-битных цветов для переднего плана.
    • r,g,b: числа — каждое должно быть 0-255

Чтобы протестировать лишь несколько из множества возможных цветов (я думаю, (2^8)^3 или 2^24 или 16777216), вы можете использовать это в bash или 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;

Результат (это в gnome-terminal, так как urxvt НЕ ПОДДЕРЖИВАЕТ 24-битный цвет... соберитесь, сопровождающий urxvt... серьезно):

Пример скриншота с 24-битным цветом

Если вам нужны 24-битные цвета для фона... вы уже догадались! Вы просто замените 38 на 48:

  • CSI 48;2; r ; g ; b m
    • CSI: escape character—^[[ or ESC[
    • 48;2;: литеральная строка, обозначающая использование 24-битных цветов для фона.
    • r,g,b: числа — каждое должно быть 0-255

Вставка необработанных Escape-последовательностей

Иногда \e и \x1b не работают. Например, в оболочке sh иногда ничего не работает (хотя в моей системе сейчас работает, не думаю, что раньше).

Чтобы обойти это, вы можете использовать CTRL+V,CTRL+[ или CTRLV,ESC

Это вставит «сырой» символ ESC (ASCII: 27). Это будет выглядеть так ^[, но не волнуйтесь; это только один символ, а не два.

Eg:

пример скриншота sh raw escape char


Проклятия

Обратитесь к странице Curses (библиотека программирования) для получения полной информации о curses. Следует отметить, что curses работает только в unix и unix-подобных операционных системах.

Работа с проклятиями

Я не буду вдаваться в подробности, потому что поисковые системы могут показать ссылки на веб-сайты, которые могут объяснить это намного лучше, чем я, но я кратко расскажу об этом здесь и приведу пример.

Зачем использовать Curses вместо ANSI Escape?

Если вы читали приведенный выше текст, то могли вспомнить, что \e или \x1b иногда будут работать с printf. Ну иногда \e и \x1b вообще не будут работать (это не стандартно и я никогда не работал с таким терминалом, но это возможно). Что еще более важно, более сложные управляющие последовательности (например, Home и другие многосимвольные клавиши) трудно поддерживать для каждого терминала (если только вы не готовы потратить много времени и усилий на синтаксический анализ terminfo и termcap и т.д.). выяснить, как обращаться с каждым терминалом).

Проклятия решают эту проблему. По сути, он может понять, какие возможности есть у терминала, используя эти методы (как описано в статье в Википедии, ссылка на которую приведена выше):

Большинство реализаций curses используют базу данных, которая может описывать возможности тысяч различных терминалов. Есть несколько реализаций, таких как PDCurses, которые используют специализированные драйверы устройств, а не терминальную базу данных. Большинство реализаций используют термининформацию; некоторые используют терминтермкап. Преимущество Curses заключается в обратной переносимости на терминалы с символьными ячейками и простоте. Для приложения, которое не требует растровой графики или нескольких шрифтов, реализация интерфейса с помощью curses обычно будет намного проще и быстрее, чем реализация с использованием инструментария X.

Большую часть времени curses будет опрашивать terminfo и затем сможет понять, как манипулировать атрибутами курсора и текста. Затем вы, программист, используете API, предоставляемый curses, для манипулирования курсором или изменения цвета текста или других атрибутов, если нужна искомая функциональность.

Пример с Python

Я считаю, что python действительно прост в использовании, но если вы хотите использовать curses на другом языке программирования, просто найдите его в Duckduckgo или любой другой поисковой системе. :) Вот быстрый пример в 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 __name__ == '__main__':
    curses.wrapper(main)

результат:

введите описание изображения здесь

Вы можете подумать про себя, что это гораздо более окольный способ ведения дел, но на самом деле он гораздо более кросс-платформенный (действительно кросс-терминальный… по крайней мере, в мире unix- и unix-подобных платформ). Для цветов это совсем не так важно, но когда дело доходит до поддержки других управляющих последовательностей, состоящих из нескольких последовательностей (таких как Home, End, Page Up, Page Down и т. д.), то curses становится еще более важным.

Пример с Tput

  • tput — это утилита командной строки для управления курсором и текстом.
  • tput поставляется с пакетом curses. Если вы хотите использовать кросс-терминальные (ish) приложения в терминале, вам следует использовать tput, поскольку он анализирует terminfo или что-то еще, что ему нужно, использует набор стандартизированных команд (например, curses) и возвращает правильную escape-последовательность.
  • пример:
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\!"

Результат:

пример с tput

Дополнительная информация о Tput

person dylnmc    schedule 25.06.2014
comment
(char) 27 также может быть представлен символом (он также может быть представлен как строка, поскольку это строка представляет собой последовательность символов и escape-последовательность "\" и то, что следует за ней до тех пор, пока "m" не будет рассматриваться как один символ) "\u001b" или (как я заметил на ubuntuforums.org) персонаж "\003". - person dylnmc; 27.06.2014
comment
он работает на Win7 в Idea14 - person nahab; 22.07.2016

Это сработало для меня:

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

Вам нужно окончание «[37m», чтобы вернуть цвет к белому (или к тому, что вы использовали). Если вы этого не сделаете, все, что следует за ним, может стать «красным».

person DanP    schedule 26.08.2014
comment
Прохладный! Как вы делаете другой цвет таким образом? - person Z2VvZ3Vp; 09.10.2014
comment
Обратитесь к этому вопросу для других кодов ANSI: stackoverflow.com/questions/5762491/ - person Rohit; 29.10.2014
comment
у меня не работает... я пытаюсь внутри eclipse и вызываю файл jar из cmd - person Lele; 23.07.2015

Библиотеку JANSI можно использовать для отображения управляющих последовательностей ANSI в Windows.

person MrDrews    schedule 14.06.2011

Да это 100% возможно

установить classpath=%classpath%;d:\jansi-1.4.jar;

Попробуйте этот код ниже:

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();
  }
}
person Raman    schedule 13.03.2014

Вот решение для консоли Win32.

1) Получите библиотеки JavaNativeAccess здесь: https://github.com/twall/jna/

2) Эти два класса Java сделают свое дело.

Наслаждаться.

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();
        }
    }
}
person kevinarpe    schedule 02.12.2010

Самый простой способ — запустить вашу программу (без изменений) в консоли Cygwin.

Второй простейший способ — запустить вашу программу (тоже немодифицированную) в обычной консоли Windows, передав ее вывод через tee.exe (из дистрибутива Cygwin или Git). Tee.exe распознает escape-коды и вызовет соответствующие функции WinAPI.

Что-то типа:

java MyClass | tee.exe log.txt
java MyClass | tee.exe /dev/null
person user222202    schedule 15.05.2013

Я создал jar библиотеку под названием JCDP (Цветная отладка Java). принтер).

Для Linux он использует escape-коды ANSI, о которых упоминал WhiteFang, но абстрагирует их, используя слова вместо кодов, что гораздо более интуитивно понятно.

Для Windows он фактически включает библиотеку JAnsi, но создает над ней слой абстракции, поддерживая интуитивно понятный и простой интерфейс, созданный для Linux.

Эта библиотека находится под лицензией лицензии MIT, так что не стесняйтесь ее использовать.

Посмотрите репозиторий JCDP на github.

person dialex    schedule 01.04.2012

Escape-последовательности должны быть ЧТО-ТО интерпретированы для преобразования в цвет. Стандартный CMD.EXE, используемый java при запуске из командной строки, не поддерживает это, поэтому Java не поддерживает.

person Thorbjørn Ravn Andersen    schedule 19.09.2009
comment
если вы работаете в ОС, отличной от Windows, есть большая вероятность, что терминальное приложение выполнит интерпретацию управляющей последовательности. - person Jherico; 19.09.2009

Проверьте это: я использовал значения ANSI с escape-кодом, и, вероятно, это не работает в командной строке Windows, но в IDE и оболочке Unix. вы также можете проверить библиотеку Jansi здесь для поддержки Windows.

System.out.println("\u001B[35m" + "This text is PURPLE!" + "\u001B[0m");
person Kumar Gaurav Sharma    schedule 07.06.2017
comment
Хотя этот код может дать ответ на вопрос, предоставление дополнительного контекста относительно того, как и/или почему он решает проблему, улучшит долгосрочную ценность ответа. Пожалуйста, прочтите это как ответить, чтобы получить качественный ответ. - person thewaywewere; 07.06.2017

Я написал библиотеку под названием AnsiScape, которая позволяет вам записывать цветной вывод более структурированным образом:

Пример:

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

Библиотека также позволяет вам определять свои собственные «экранирующие классы», похожие на классы CSS.

Пример:

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));
person Andrei Ciobanu    schedule 15.11.2017

System.err.println("Errorrrrrr") будет печатать текст красным цветом на консоли.

person Kamran    schedule 12.06.2017

Это работает в eclipse, чтобы сделать его красным, не знаю о других местах.

System.err.println(" BLABLA ");
person joe    schedule 22.07.2015
comment
Оператор спросил о System.out, а не о System.err. Эти два потока могут указывать на разные местоположения. - person John; 22.07.2015
comment
Прочитайте вопрос How to color System.out.println output? - person August; 05.08.2015
comment
Речь идет о печати шрифтов разного цвета. Шрифты ошибок печатаются красным цветом самой java. Ваш ответ не относится к вопросу. - person Shubham Pandey; 27.12.2019