Как я могу раскрасить вывод Java?
Например, на C и других языках я могу использовать ANSI-escape, например \033[0m
. Но в Java это не работает.
public static void main(String[] x) {
System.out.println("\033[0m BLABLA \033[0m\n");
}
Как я могу раскрасить вывод Java?
Например, на C и других языках я могу использовать ANSI-escape, например \033[0m
. Но в Java это не работает.
public static void main(String[] x) {
System.out.println("\033[0m BLABLA \033[0m\n");
}
Нет, но есть сторонний API, который может обрабатывать его
http://www.javaworld.com/javaworld/javaqa/2002-12/02-qa-1220-console.html
Изменить: конечно, есть более новые статьи, чем те, которые я опубликовал, однако информация по-прежнему остается жизнеспособной.
Возможно, вы не сможете окрасить Window cmd prompt
, но он должен работать во многих терминалах unix (или unix-like).
Также обратите внимание, что некоторые терминалы просто не поддерживают некоторые (если есть) escape-последовательности ANSI и, особенно, 24-битные цвета.
Для лучшего решения обратитесь к разделу Curses внизу. Для личного или простого решения (хотя не как кросс-платформенное решение), обратитесь к разделу ANSI Escape Sequences.
java: System.out.println((char)27 + "31m" + "ERROR MESSAGE IN RED");
python: print(chr(27) + "31m" + "ERROR MESSAGE IN RED")
printf '\x1b[31mERROR MESSAGE IN RED'
printf '\e[31mERROR MESSAGE IN RED'
printf '
CTRL + V, CTRL + [ [31mERROR MESSAGE IN RED'
^[
. Хотя это выглядит как два символа, это действительно один символ ESC.В то время как это не лучший способ сделать это, самый простой способ сделать это на языке программирования или скриптинга - использовать escape-последовательности. По этой ссылке:
Управляющая последовательность представляет собой серию символов, используемых для изменения состояния компьютеров и их подключенных периферийных устройств. Они также известны как управляющие последовательности, отражающие их использование в управлении устройством.
Тем не менее, это становится еще проще, чем в видеотексте, поскольку эти терминалы используют ANSI escape-последовательности. По этой ссылке:
Управляющие последовательности ANSI являются стандартом для внутриполосной сигнализации для управления расположением курсора, цветом и другими параметрами на текстовых текстовых терминалах. Определенные последовательности байтов, большинство из которых начинаются с Esc и '[', встроены в текст, который терминал ищет и интерпретирует как команды, а не как коды символов.
27
/hex: 0x1B
).Некоторые программирующие langauges (например, Java) не будут интерпретировать \e
или \x1b
как символ ESC. Однако мы знаем, что символ ASCII 27
имеет символ ESC, поэтому мы можем просто приписать 27
в char
и использовать его для запуска escape-последовательности.
Вот несколько способов сделать это в общих языках программирования:
Java
System.out.println((char)27 + "[33mYELLOW");
Python 3
print(chr(27) + "[34mBLUE");
print("\x1b[35mMAGENTA");
\x1b
правильно интерпретируется в pythonNode JS
console.log(String.fromCharCode(27) + "[36mCYAN");
console.log("\x1b[30;47mBLACK_ON_WHITE");
\x1b
также работает в nodeЕсли вы работаете с bash или zsh, довольно легко покрасить вывод (в большинстве терминалов). В Linux, Os X и в некоторых терминалах Windows вы можете проверить, поддерживает ли ваш терминал цвет, выполнив следующие действия:
printf '\e[31mRED'
printf '\x1b[31mRED'
Если вы видите цвет для обоих, то это здорово! Если вы видите цвет только для одного, используйте эту последовательность. Если вы не видите цвета ни для одного из них, тогда дважды проверьте, чтобы убедиться, что вы правильно ввели все, и что вы находитесь в bash или zsh; если вы все еще не видите никакого цвета, ваш терминал, вероятно, не поддерживает escape-последовательности ANSI.
Если я правильно помню, терминалы linux имеют тенденцию поддерживать как escape-последовательности \e
, так и \x1b
, тогда как терминалы os x имеют тенденцию поддерживать \e
, но я могу ошибаться. Тем не менее, если вы видите что-то вроде следующего изображения, тогда вы все настроены! (Обратите внимание, что я использую оболочку, zsh, и она окрашивает строку приглашения, также я использую urxvt в качестве моего терминала в Linux.)
"Как это работает?" вы можете спросить. Bascially, printf
интерпретирует последовательность символов, которая следует (все внутри одиночных кавычек). Когда printf
встречается \e
или \x1b
, он преобразует эти символы в символ ESC (ASCII: 27). Это то, что мы хотим. Теперь printf
отправляет ESC 31m
, и поскольку существует ESC, за которым следует действительная escape-последовательность ANSI, мы должны получить цветной вывод (пока он поддерживается терминалом).
Вы также можете использовать echo -e '\e[32mGREEN'
(например) для вывода цвета. Обратите внимание, что флаг -e
для echo
"[позволяет] интерпретировать escape-обраты с обратным слэшем" и должен использоваться, если вы хотите, чтобы echo
надлежащим образом интерпретировал escape-последовательность.
Последовательности escape ANSI могут делать больше, чем просто вывод цвета, но пусть начнется с этого и посмотрим, как именно работает цвет; то мы увидим, как манипулировать курсором; наконец, мы рассмотрим, как использовать 8-битный цвет, а также 24-битный цвет (хотя он имеет лишь незначительную поддержку).
В Wikipedia они относятся к ESC [ как CSI
, поэтому я сделаю то же самое.
Для вывода цвета с использованием экранов ANSI используйте следующее:
CSI
n
m
CSI
: escape-символ- ^[[
или ESC [n
: номер один из следующего:
30
- 37
, 39
: передний план40
- 47
, 49
: backgroundm
: буквальный ASCII m
- завершает escape-последовательностьЯ буду использовать 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;
Результат:
+~~~~~~+~~~~~~+~~~~~~~~~~~+
| 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, поэтому синтаксис одинаков:
CSI
n
m
CSI
: escape-символ- ^[[
или ESC [n
: номер один из следующего:
0
: reset1
- 9
: включает различные текстовые эффекты21
- 29
: отключает различные текстовые эффекты (менее поддерживается, чем 1
- 9
)30
- 37
, 39
: цвет переднего плана40
- 47
, 49
: цвет фона38
: 8- или 24-битный цвет переднего плана (см. 8/24-битный цвет)48
: 8- или 24-битный цвет фона (см. 8/24-битный цвет)m
: буквальный ASCII m
- завершает escape-последовательностьНесмотря на то, что слабая поддержка слабых (2), курсив (3), подчеркивание (4), мигание (5,6), обратное видео (7), скрытие (8) и вычеркнутое (9), некоторые (но редко все) имеют тенденцию работать на терминалах linux и os x.
Также стоит отметить, что вы можете отделить любой из вышеуказанных атрибутов с помощью двоеточия. Например, printf '\e[34;47;1;3mCRAZY TEXT\n'
покажет CRAZY TEXT
с blue foreground
на a white background
, и это будет bold
и italic
.
Например:
Выполните следующие действия в оболочке bash или zsh, чтобы увидеть все текстовые эффекты, которые вы можете сделать. (Возможно, вам нужно заменить \e
на \x1b
.)
for i in {1..9}; do printf "\e[${i}m~TEST~\e[0m "; done
Результат:
Вы можете видеть, что мой терминал поддерживает все текстовые эффекты кроме для слабых (2), скрывает (8) и вычеркивает (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
В то время как большинство терминалов поддерживают это, оно менее поддерживается, чем 0-7
, 9
цвета.
Синтаксис:
CSI
38;5;
n
m
CSI
: escape-символ- ^[[
или ESC [38;5;
: буквальная строка, которая обозначает использование 8-битных цветовn
: номер один из следующего:
0
- 255
Если вы хотите просмотреть все цвета в своем терминале красивым способом, у меня есть приятный script на gist.github.com.
Он выглядит следующим образом:
Также известный как истинный цвет, 24-битный цвет обеспечивает отличную функциональность. Поддержка этого определенно возрастает (насколько я знаю, он работает в большинстве современных терминалов, кроме urxvt, мой терминал [вставить сердитый эможи]).
24-битный цвет фактически поддерживается в vim (см. vim wiki, чтобы узнать, как включить 24-битные цвета). Это действительно аккуратно, потому что он тянет из цветов, определенных для gvim; например, он использует fg/bg из highlight guibg=#______ guifg=#______
для 24-битных цветов! Неато, да?
Вот как работает 24-битный цвет:
CSI
38;2;
r
;
g
;
b
m
CSI
: escape-символ- ^[[
или 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-терминале, так как urxvt НЕ ПОДДЕРЖИВАЕТ 24-битный цвет... объедините его, поддерживающий urxvt... для реального):
Иногда \e
и \x1b
не будут работать. Например, в sh-оболочке иногда не работает (хотя в моей системе сейчас она работает), я не думаю, что она использовалась).
Чтобы обойти это, вы можете использовать CTRL + V, CTRL + [ или CTRL V, ESC
Это добавит символ "raw" ESC (ASCII: 27). Это будет выглядеть как ^[
, но не волнуйтесь; это только один символ, а не два.
Например:
Я довольно устал, так как я работал над этим довольно долгое время, но я закончу это позже сегодня или когда-нибудь в ближайшем будущем, чтобы, если кто-то хочет сделать профессиональное или более кросс-платформенное приложение который использует цвет, движение курсора и т.д., это должно помочь.
Теперь вы можете просто ссылаться на страницу Curses (Библиотека программирования).
Это сработало для меня:
System.out.println((char)27 + "[31mThis text would show up red" + (char)27 + "[0m");
Вам нужно финал "[37m", чтобы вернуть цвет в белый цвет (или все, что вы использовали). Если вы этого не сделаете, это может сделать все, что следует за "красным".
Да, это на 100% возможно
set 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();
}
}
Вы можете использовать библиотеку JANSI, чтобы отображать escape-последовательности ANSI в Windows.
Вот решение для консоли Win32.
1) Получите библиотеки JavaNativeAccess здесь: https://github.com/twall/jna/
2) Эти два класса Java сделают трюк.
Enjoy.
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();
}
}
}
Я создал библиотеку jar
, называемую JCDP (цветной отладочный принтер Java).
Для Linux он использует escape-коды ANSI, упомянутые WhiteFang, но абстрагирует их, используя слова вместо кодов, которые гораздо более интуитивно понятны.
Для Windows он фактически включает библиотеку JAnsi, но создает над ним слой абстракции, поддерживая интуитивно понятный и простой интерфейс, созданный для Linux.
Эта библиотека лицензируется в соответствии с Лицензией MIT, поэтому не стесняйтесь ее использовать.
Посмотрите JCDP github репозиторий.
Самый простой способ - запустить вашу программу (немодифицированную) в консоли Cygwin.
Второй самый простой способ - запустить программу (также немодифицированную) на обычной консоли Windows, конвейерную обработку ее вывода через tee.exe(из Cygwin или Git distribution). Tee.exe распознает escape-коды и вызовет соответствующие функции WinAPI.
Что-то вроде:
java MyClass | tee.exe log.txt
java MyClass | tee.exe /dev/null
Последовательности Escape должны интерпретироваться SOMETHING для преобразования в цвет. Стандартный CMD.EXE, используемый java при запуске из командной строки, не поддерживает это, поэтому Java не делает.
Check This Out: я использовал значения ANSI с escape-кодом и, вероятно, не работал в командной строке Windows, а в среде IDE и Unix. вы также можете проверить библиотеку "Jansi" здесь для поддержки Windows.
System.out.println("\u001B[35m" + "This text is PURPLE!" + "\u001B[0m");
System.err.println( "Errorrrrrr" ), он будет печатать текст с красным цветом на консоли.
Я написал библиотеку под названием 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));
Это работает в eclipse, чтобы превратить его в красный цвет, не знаю о других местах.
System.err.println(" BLABLA ");