通過控制檯輸出各種顏色的字元——ANSIConsole、JANSI
預設的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/