【问题标题】:How to color System.out.println output? [duplicate]如何为 System.out.println 输出着色? [复制]
【发布时间】:2010-11-29 17:59:44
【问题描述】:

如何为 Java 输出着色?

例如,在 C 和其他语言中,我可以使用像 \033[0m 这样的 ANSI 转义来执行此操作。但在 Java 中它不起作用。

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

【问题讨论】:

    标签: java colors system.out


    【解决方案1】:

    没有,但是有第三方 API 可以处理它

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

    编辑:当然有比我发布的文章更新的文章,但信息仍然可行。

    以上链接已失效,请改为查看此问题:How to print color in console using System.out.println?

    【讨论】:

    【解决方案2】:

    转义序列必须由 SOMETHING 解释才能转换为颜色。 java 从命令行启动时使用的标准 CMD.EXE 不支持,因此 Java 不支持。

    【讨论】:

    • 如果您在非 Windows 操作系统上运行,终端应用程序很有可能会进行转义序列解释。
    【解决方案3】:

    这是 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();
            }
        }
    }
    

    【讨论】:

      【解决方案4】:

      您可以使用 JANSI 库在 Windows 中呈现 ANSI 转义序列。

      【讨论】:

        【解决方案5】:

        我创建了一个名为 JCDPjar 库(Java 彩色调试打印机)。

        对于 Linux,它使用 WhiteFang 提到的 ANSI 转义码,但使用单词而不是更直观的代码来抽象它们。

        对于 Windows,它实际上包含 JAnsi 库,但在其上创建了一个抽象层,保持为 Linux 创建的直观和简单的界面。

        这个库是在MIT License 下获得许可的,所以请随意使用它。

        看看JCDP's github repository

        【讨论】:

          【解决方案6】:

          最简单的方法是在 Cygwin 控制台中运行您的程序(未修改)。

          第二种最简单的方法是在普通的 Windows 控制台中运行您的程序(也未修改),通过 tee.exe(来自 Cygwin 或 Git 发行版)流水线化其输出。 Tee.exe 将识别转义码并调用相应的 WinAPI 函数。

          类似:

          java MyClass | tee.exe log.txt
          java MyClass | tee.exe /dev/null
          

          【讨论】:

            【解决方案7】:

            是的,这是 100% 可能的

            设置类路径= %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();
              }
            }
            

            【讨论】:

            • 太棒了——这是最简单、最直接、视觉上可以理解的解决方案,并且普遍适用!
            【解决方案8】:

            注意

            您可能无法为 Window 的 cmd prompt 着色,但它应该可以在许多 unix(或类 unix)终端中使用。

            另外,请注意,某些终端根本不支持某些(如果有)ANSI 转义序列,尤其是 24 位颜色。

            用法

            请参阅底部的诅咒部分以获得最佳解决方案。对于个人或简单的解决方案(尽管 不是 作为跨平台解决方案),请参阅 ANSI Escape Sequences 部分。


            TL;DR

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

            • pythonprint(chr(27) + "[31m" + "ERROR MESSAGE IN RED")

            • bashzshprintf '\x1b[31mERROR MESSAGE IN RED'
              • 这也可能适用于 Os X:printf '\e[31mERROR MESSAGE IN RED'
            • shprintf 'CTRL+V,CTRL+[[31mERROR MESSAGE IN RED'
              • 即,当转义解释不可用时,按 CTRL+V 然后按 CTRL+[ 以获得“原始”ESC 字符
              • 如果操作正确,您应该会看到^[。虽然看起来像两个字符,但实际上只有一个,ESC字符。
              • 你也可以在vim中按CTRL+V,CTRL+[ > 在任何编程或脚本语言中,因为它使用文字 ESC 字符
              • 另外,您可以将 Ctrl+[ 替换为 ESC ...例如,您可以使用 CTRL+V,ESC,但我发现前者更容易,因为我已经按下 CTRL 并且因为 [ 不那么有效顺便说一句。

            ANSI 转义序列

            转义序列的背景

            虽然这不是最好的方法,但在编程或脚本语言中最简单的方法是使用 escape sequences。从那个链接:

            转义序列是一系列字符,用于更改计算机及其连接的外围设备的状态。这些也称为控制序列,反映了它们在设备控制中的用途。

            ANSI 转义序列的背景

            但是,它比视频文本终端更容易,因为这些终端使用 ANSI escape sequences。从那个链接:

            ANSI 转义序列是带内信号的标准,用于控制视频文本终端上的光标位置、颜色和其他选项。某些字节序列,大多数以 Esc 和 '[' 开头,嵌入到文本中,终端查找并解释为命令,而不是字符代码。

            如何使用 ANSI 转义序列

            一般

            • 转义序列以转义字符开头;对于 ANSI 转义序列,该序列始终以 ESC 开头(ASCII:27 / 十六进制:0x1B)。
            • 有关您可以执行的操作的列表,请参阅ANSI Escape Sequence List on Wikipedia

            在编程语言中

            某些编程语言(如 Java)不会将 \e\x1b 解释为 ESC 字符。但是,我们知道 ASCII 字符 27 ESC 字符,所以我们可以简单地将27 转换为char 并使用它来开始转义顺序。

            以下是一些常用编程语言的方法:

            • Java

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

              • print(chr(27) + "[34mBLUE");
              • print("\x1b[35mMAGENTA");
                • 请注意,\x1b 在 python 中被正确解释
            • 节点 JS

              • 以下内容将在 Web 控制台中的 JavaScript 中为输出着色
              • console.log(String.fromCharCode(27) + "[36mCYAN");
              • console.log("\x1b[30;47mBLACK_ON_WHITE");
                • 请注意,\x1b 也适用于节点

            在 Shell 提示符或脚本中

            如果您使用的是 bashzsh,则很容易为输出着色(在大多数终端中)。在 Linux、Os X 和某些 Window 的终端中,您可以通过执行以下两个操作来检查您的终端是否支持颜色:

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

            如果您看到两者的颜色,那就太好了!如果您只看到一个颜色,请使用该序列。如果您没有看到其中任何一个的颜色,请仔细检查以确保您输入的所有内容都正确并且您使用的是 bash 或 zsh;如果您仍然看不到任何颜色,那么您的终端可能不支持 ANSI 转义序列。

            如果我没记错的话,linux 终端倾向于支持\e\x1b 转义序列,而 os x 终端只倾向于支持\e,但我可能错了。尽管如此,如果您看到类似下图的内容,那么您已经准备就绪! (请注意,我使用的是 shell,zsh,它为我的提示字符串着色;另外,我在 linux 中使用 urxvt 作为我的终端。)

            “这是如何工作的?” 你可能会问。基本上,printf 正在解释后面的字符序列(单引号中的所有内容)。当printf 遇到\e\x1b 时,会将这些字符转换为ESC 字符(ASCII:27)。这正是我们想要的。现在,printf 发送 ESC31m,因为有一个 ESC 后跟一个有效的 ANSI 转义序列,我们应该得到彩色输出(只要它是终端支持)。

            您还可以使用echo -e '\e[32mGREEN'(例如)进行颜色输出。请注意,echo-e 标志 “[启用] 反斜杠转义解释” 如果您希望 echo 正确解释转义序列,则必须使用该标志。


            更多关于 ANSI 转义序列

            ANSI 转义序列可以做的不仅仅是颜色输出,但让我们从它开始,看看颜色是如何工作的;然后,我们将看到如何操作光标;最后,我们将看看如何使用 8 位颜色和 24 位颜色(虽然它只支持微弱的支持)。

            Wikipedia 上,他们将ESC[ 称为CSI,所以我也会这样做。

            颜色

            要使用 ANSI 转义进行颜色输出,请使用以下命令:

            • CSInm
              • CSI:转义字符—^[[ESC[
              • n:一个数字——以下之一:
                • 30-3739:前景
                • 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;

            结果:

            快速参考(颜色)

            +~~~~~~+~~~~~~+~~~~~~~~~~~+
            |  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,所以语法是一样的:

            • CSInm
              • CSI:转义字符—^[[ESC[
              • n:一个数字——以下之一:
                • 0:重置
                • 1-9:开启各种文字效果
                • 21-29:关闭各种文字效果(比1-9支持的少)
                • 30-3739:前景色
                • 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' 将在white background 上显示CRAZY TEXTblue foreground,它将是bolditalic

            例如:

            在您的 bash 或 zsh shell 中执行以下操作,以查看您可以执行的所有文本效果。 (您可能需要将\e 替换为\x1b。)

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

            结果:

            你可以看到我的终端支持faint (2), conceal (8)和except >划掉 (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 颜色。

            语法:

            • CSI38;5;nm
              • CSI:转义字符—^[[ESC[
              • 38;5;:表示前景使用 8 位颜色的文字字符串
              • n:一个数字——以下之一:
                • 0-255

            如果您想以一种不错的方式预览终端中的所有颜色,我有a nice script on gist.github.com

            看起来像这样:

            如果您想使用 8 位颜色更改背景,只需将 38 替换为 48

            • CSI48;5;nm
              • CSI:转义字符—^[[ESC[
              • 48;5;:表示使用 8 位颜色作为背景的文字字符串
              • n:一个数字——以下之一:
                • 0-255

            24 位彩色

            也称为真彩色,24 位彩色提供了一些非常酷的功能。对此的支持肯定在增加(据我所知,它适用于大多数现代终端,​​除了 urxvt,我的终端 [插入愤怒的表情符号])。

            vim 实际上支持 24 位颜色(请参阅vim wiki 了解如何启用 24 位颜色)。它真的很整洁,因为它来自为 gvim 定义的颜色方案;例如,它使用来自highlight guibg=#______ guifg=#______ 的fg/bg 作为24 位颜色!尼托,嗯?

            这是 24 位颜色的工作原理:

            • CSI38;2;r;g;bm
              • CSI:转义字符—^[[ESC[
              • 38;2;:表示前景使用 24 位颜色的文字字符串
              • r,g,b:数字——每个都应该是0-255

            要测试只是您可以拥有的许多颜色((2^8)^32^2416777216 可能,我认为),您可以在 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 位颜色的背景...您猜对了!您只需将38 替换为48

            • CSI48;2;r;g;bm
              • CSI:转义字符—^[[ESC[
              • 48;2;:表示使用 24 位颜色作为背景的文字字符串
              • r,g,b:数字——每个都应该是0-255

            插入原始转义序列

            有时\e\x1b 不起作用。例如,在 sh shell 中,有时两者都不起作用(虽然它在我的系统上现在 可以,但我认为以前不会)。

            要避免这种情况,您可以使用 CTRL+VCTRL+[CTRL V,ESC

            这将插入一个“原始”ESC 字符(ASCII:27)。它看起来像这样^[,但不要担心;它只有一个字符,而不是两个。

            例如:


            诅咒

            请参阅Curses (Programming Library) page 以获取有关诅咒的完整参考。需要注意的是,curses 仅适用于 unix 和类 unix 操作系统。

            带着诅咒开始行动

            我不会详细介绍,因为搜索引擎可以显示指向网站的链接,这些网站可以比我更好地解释这一点,但我将在这里简要讨论并举一个例子。

            为什么在 ANSI 转义上使用诅咒?

            如果您阅读了上面的文字,您可能会记得\e\x1b 有时会与printf 一起使用。好吧,有时\e\x1b 根本不起作用(这不是标准的,我从未使用过这样的终端,但这是可能的)。更重要的是,每个终端都难以支持更复杂的转义序列(想想 Home 和其他多字符键)(除非您愿意花费大量时间和精力来解析 terminfo 和 termcap 以及弄清楚如何处理每个终端)。

            Curses 解决了这个问题。基本上,它能够使用这些方法(如上面链接的维基百科文章所述)了解终端具有哪些功能:

            curses 的大多数实现都使用可以描述数千个不同终端功能的数据库。有一些实现,例如 PDCurses,它们使用专门的设备驱动程序而不是终端数据库。大多数实现使用 terminfo;一些使用termcap。 Curses 具有向后可移植到字符单元终端和简单性的优点。对于不需要位图图形或多种字体的应用程序,使用 curses 的接口实现通常比使用 X 工具包的接口实现简单和快速。

            大多数时候,curses 会轮询 terminfo,然后就能理解如何操作光标和文本属性。然后,您,程序员,使用 curses 提供的 API 来操作光标或更改文本颜色或其他属性,如果您需要的功能是需要的。

            Python 示例

            我发现 python 真的很容易使用,但是如果你想在不同的编程语言中使用 curses,那么只需在 dadduckgo 或任何其他搜索引擎上搜索它。 :) 这是 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 平台的世界中) )。对于颜色,它不是相当那么重要,但是当涉及到支持其他多序列转义序列时(例如HomeEndPage UpPage Down 等),那么诅咒就变得更加重要了。

            Tput 示例

            • tput 是一个用于操作光标和文本的命令行实用程序
            • tput 附带 curses 包。如果你想在终端中使用跨终端(ish)应用程序,你应该使用 tput,因为它会解析 terminfo 或任何它需要的东西,并使用一组标准化的命令(如 curses)并返回正确的转义序列。李>
            • 示例:
            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 的信息

            【讨论】:

            • (char) 27 也可以用字符表示(它也可以表示为字符串,因为字符串是字符序列和转义符"\" 以及它后面的内容直到@ 987654518@ 被视为单个字符)"\u001b" 或(正如我在 ubuntuforums.org 上注意到的那样)被字符 "\003" 处理。
            • 在Idea14的Win7上运行
            【解决方案9】:

            这对我有用:

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

            您需要结尾“[37m”将颜色恢复为白色(或您使用的任何颜色)。如果你不这样做,它可能会使后面的所有东西都变成“红色”。

            【讨论】:

            • 酷!你怎么用这种方式做另一种颜色?
            • 其他ANSI代码参考这个问题:stackoverflow.com/questions/5762491/…
            • 对我不起作用...我尝试在 eclipse 中,并从 cmd 调用 jar 文件
            【解决方案10】:

            这在eclipse中工作只是为了把它变成红色,不知道其他地方。

            System.err.println(" BLABLA ");
            

            【讨论】:

            • 操作询问的是 System.out,而不是 System.err。这两个 Stream 可能指向不同的位置。
            • 阅读问题How to color System.out.println output?
            • 它是关于打印不同颜色的字体。错误字体由 java 本身以红色打印。您的回答与问题无关。
            【解决方案11】:

            检查一下:我使用带有转义码的 ANSI 值,它可能无法在 Windows 命令提示符下工作,但在 IDE 和 Unix shell 中工作。 您还可以查看“Jansi”库 here 以获得 Windows 支持。

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

            【讨论】:

            • 虽然此代码可能会回答问题,但提供有关它如何和/或为什么解决问题的额外上下文将提高​​答案的长期价值。请阅读此how-to-answer 以提供高质量的答案。
            【解决方案12】:

            System.err.println("Errorrrrrrr") 它将在控制台上以红色打印文本。

            【讨论】:

              【解决方案13】:

              我编写了一个名为 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));
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2011-01-20
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2017-09-08
                • 1970-01-01
                相关资源
                最近更新 更多