默认的jdk控制台只能跟随系统而定,在eclipse中可以定义各种来源的输出颜色,但是如果你想按照的app输出内容到控制台,只能按照前两者来定,而且默认只有黑和err的红,有时候开发中输出的日志信息较多,仅有这两种根本不能解决问题,因此如果可以让我们随心所欲的控制app输出的字符的颜色就最好不过了。
目前有两种办法实现,一种是使用JANSI类库,一种是使用eclipse的ANSIconsole,前者可以实现在cmd中改变颜色,后者可以在eclipse的控制台中改变颜色甚至样式排版。
ANSI(escape sequences)
先说说什么是ANSI escape sequences(ANSI转义序列),因为上述的都是以它为实现的。
ANSI转义序列是带随路信令控制视频文本终端上光标位置、颜色和其他选项的标准,这些序列代码是由ANSI编码字符构定义的,某些字节序列,大多数是从ESC和“O”开始的,嵌入到文本中,终端将查找并解释为命令,而不是字符代码。 如我们最常用到的就是\n \t等转义字符。
ANSI转义序列从上世纪80年代开始使用,要知道当时可没有什么windows界面,为了解决排版和一些光标问题,就使用了该转义序列,通过它不仅可以改变终端的输出,还可以绘制一些图案,非常实用。尽管现在文本终端越来越少见,但是在开发中还是常用的,如win32控制台,或者IDE的控制台。
当我们通过控制台操作mysql或者oracle的时候,输出到ESC c的时候会清屏,这也是个转义符。
Sequence | C1 | Name |
ESC N | 0x8e | SS2 – Single Shift Two |
ESC O | 0x8f | SS3 – Single Shift Three |
ESC P | 0x90 | DCS – Device Control String |
ESC [ | 0x9b | CSI - Control Sequence Introducer |
ESC \ | 0x9c | ST – String Terminator |
ESC ] | 0x9d | OSC – Operating System Command |
ESC X | 0x98 | SOS – Start of String |
ESC ^ | 0x9e | PM – Privacy Message |
ESC _ | 0x9f | APC – Application Program Command |
ESC c | RIS – Reset to Initial State |
不同的硬件或终端有些转义符是不相同的不通用的。这里不再多说。关键的是SGR (Select Graphic Rendition) parameters,选择图形再现参数。就是靠它来定义控制台输出的字符样式。主要通过上面的ESC [ 来引入。
Code | Effect | Note |
0 | Reset / Normal | all attributes off |
1 | Bold or increased intensity | |
2 | Faint (decreased intensity) | Not widely supported. |
3 | Italic | Not widely supported. Sometimes treated as inverse. |
4 | Underline | |
5 | Slow Blink | less than 150 per minute |
6 | Rapid Blink | MS-DOS ANSI.SYS; 150+ per minute; not widely supported |
7 | swap foreground and background colors | |
8 | Conceal | Not widely supported. |
9 | Crossed-out | Characters legible, but marked for deletion. Not widely supported. |
10 | Primary(default) font | |
11–19 | Alternative font | Select alternative font n − 10 {\displaystyle n-10} |
20 | hardly ever supported | |
21 | Bold off or Double Underline | Bold off not widely supported; double underline hardly ever supported. |
22 | Normal color or intensity | Neither bold nor faint |
23 | Not italic, not Fraktur | |
24 | Underline off | Not singly or doubly underlined |
25 | Blink off | |
27 | Inverse off | |
28 | Reveal | conceal off |
29 | Not crossed out | |
30–37 | Set foreground color | See color table below |
38 | Set foreground color | Next arguments are 5;n or 2;r;g;b, see below |
39 | Default foreground color | implementation defined (according to standard) |
40–47 | Set background color | See color table below |
48 | Set background color | Next arguments are 5;n or 2;r;g;b, see below |
49 | Default background color | implementation defined (according to standard) |
51 | Framed | |
52 | Encircled | |
53 | Overlined | |
54 | Not framed or encircled | |
55 | Not overlined | |
60 | ideogram underline or right side line | hardly ever supported |
61 | ideogram double underline or | |
62 | ideogram overline or left side line | |
63 | ideogram double overline or | |
64 | ideogram stress marking | |
65 | ideogram attributes off | reset the effects of all of 60–64 |
90–97 | Set bright foreground color | aixterm (not in standard) |
100–107 | Set bright background color | aixterm (not in standard) |
可以看到,上面的参数表里面,30-40+的代码可以控制输出的字符和背景颜色。而其他的代码用途也很多,如控制光标,等等。
字体颜色:30:黑 31:红 32:绿 33:黄 34:蓝色 35:紫色 36:深绿 37:白色 背景:40:黑 41:深红 42:绿 43:黄色 44:蓝色 45:紫色 46:深绿 47:白色。
例如:我们想让某个字符变为黄色,那么ESC [33m something。
使用ecliose ANSIconsole插件
说到这里我们开始在eclipse中使用吧,需要安装ansiconsole才能解析这些转义字符。该插件在线安装地址:http://www.mihai-nita.net/eclipse Git:https://github.com/mihnita/ansi-econsole
安装好之后在选项里面去启用即可:
现在我们可以输出有各种颜色的内容到控制台了:
System.out.println("Hello \u001b[31m red world!");
输出了红色的red字,\u001b是ESC的转义,31m代表红色,如果重复2遍你会发现有所不同:
System.out.println("Hello \u001b[31m red world!");
System.out.println("Hello \u001b[31m red world!");
显然,这个颜色的转义在你下一次向控制台打印的时候,会在一开始生效。怎么办?
System.out.println("Hello \u001b[31m red \u001b[0m world!");
System.out.println("Hello \u001b[31m red world!");
使用[0m或者[39;49重置,后者有些终端可能不支持。
搭配使用其他操作代码实现更多效果,例如下面显示更为高亮的红色[1;31m
System.out.println("Hello \u001b[31m red \u001b[0m world!");
System.out.println("Hello \u001b[1;31m red world!");
背景颜色:
System.out.println("Hello \u001b[1;42m red world!");
以上的颜色都是默认使用3/4 bit颜色,也就是只有8种颜色,而这8中颜色不同的终端会使用不同的256-color(8bit)来对应,所以不同的设备终端可能有色差。现在设备几乎都支持8BIT,因此我们使用256如何:
System.out.println("Hello \u001b[38;5;6m 前端颜色!");
System.out.println("Hello \u001b[48;5;6m 后端颜色!");
38;5代表设置字体,48;5代表背景,后面的数字就是颜色,1-7是原来的8种,8-15是原来的高亮,其余的就是256的颜色。232-255: grayscale from black to white in 24 steps ——24灰度。
System.out.println("Hello \u001b[38;5;166m 前端颜色! \u001b[0m");
System.out.println("Hello \u001b[48;5;186m 后端颜色!");
还有24bit真彩色:
System.out.println("Hello \u001b[38;5;66;66;166m 前端颜色! \u001b[0m");
System.out.println("Hello \u001b[48;5;186;187;188m 后端颜色!");
将该选项启用,即可看到转义的代码:
以下是eclipse控制台支持的操作:
0 – Reset / Normal
1 – Bold: treated as intensity under Windows console, user option in this plugin)
2 – Intensity faint: “kind of” supported :-) It resets the intensity to normal.
3 – Italic: on (treated as inverse under Windows console, user option in this plugin)
4 – Underline
7 – Negative
8 – Conceal
9 – Crossed-out
21 – Double underline
22 – Bold off (normal intensity)
23 – Italic off
24 – Underline off
27 – Negative off
28 – Conceal off
29 – Crossed-out off
30-37 – Set text color
38 – Set xterm-256 text color
39 – Default text color
40 – 47 – Set background color
48 – Set xterm-256 background color
49 – Default background color
51 – Framed
54 – Framed off
90-97 – Set foreground color, high intensity
100-107 – Set background color, high intensity
使用JANSI类库
上面说使用ansi插件的方式输出,但是如果使用jansi会更方便一些,不用需记忆和书写那些转义字符。前提是在eclipse中要配合ansiconsole使用。
下载jansi-1.4.jar,加入应用类库即可,接着使用:
System.out.println( Ansi.ansi().eraseScreen().fg(Color.RED).a("Hello").fg(Color.GREEN).a(" World").reset() );
Color是类库的一个颜色枚举,fg就是字体颜色,reset就是恢复默认。这个跟上面的转义字符应该很好对应把。不过颜色少,只有原来的8种。
最后就是,在最近的windows版本中的控制台直接输出,JANSI似乎不管用。。。
参考资料:https://en.wikipedia.org/wiki/ANSI_escape_code
https://mihai-nita.net/2013/06/03/eclipse-plugin-ansi-in-console/