自定义输入内容样式
前言
好久没来园子写文章了!😂,现在博客迁移到 github blog了,所以没怎么在这里写了。
思路来源
最近体验了下blade ,一个轻量级MVC框架,看源码时候看到一个比较有意思的类 com.hellokaton.blade.kit.Ansi
package com.hellokaton.blade.kit;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import static com.hellokaton.blade.kit.SystemKit.isWindows;
/**
*
* @author dain
*/
public final class Ansi {
// Color code strings from:
// http://www.topmudsites.com/forums/mud-coding/413-java-ansi.html
public static final String SANE = "\u001B[0m";
public static final String HIGH_INTENSITY = "\u001B[1m";
public static final String LOW_INTENSITY = "\u001B[2m";
public static final String ITALIC = "\u001B[3m";
public static final String UNDERLINE = "\u001B[4m";
public static final String BLINK = "\u001B[5m";
public static final String RAPID_BLINK = "\u001B[6m";
public static final String REVERSE_VIDEO = "\u001B[7m";
public static final String INVISIBLE_TEXT = "\u001B[8m";
public static final String BLACK = "\u001B[30m";
public static final String RED = "\u001B[31m";
public static final String GREEN = "\u001B[32m";
public static final String YELLOW = "\u001B[33m";
public static final String BLUE = "\u001B[34m";
public static final String MAGENTA = "\u001B[35m";
public static final String CYAN = "\u001B[36m";
public static final String WHITE = "\u001B[37m";
public static final String BACKGROUND_BLACK = "\u001B[40m";
public static final String BACKGROUND_RED = "\u001B[41m";
public static final String BACKGROUND_GREEN = "\u001B[42m";
public static final String BACKGROUND_YELLOW = "\u001B[43m";
public static final String BACKGROUND_BLUE = "\u001B[44m";
public static final String BACKGROUND_MAGENTA = "\u001B[45m";
public static final String BACKGROUND_CYAN = "\u001B[46m";
public static final String BACKGROUND_WHITE = "\u001B[47m";
public static final Ansi HighIntensity = new Ansi(HIGH_INTENSITY);
public static final Ansi Bold = HighIntensity;
public static final Ansi LowIntensity = new Ansi(LOW_INTENSITY);
public static final Ansi Normal = LowIntensity;
public static final Ansi Italic = new Ansi(ITALIC);
public static final Ansi Underline = new Ansi(UNDERLINE);
public static final Ansi Blink = new Ansi(BLINK);
public static final Ansi RapidBlink = new Ansi(RAPID_BLINK);
public static final Ansi Black = new Ansi(BLACK);
public static final Ansi Red = new Ansi(RED);
public static final Ansi Green = new Ansi(GREEN);
public static final Ansi Yellow = new Ansi(YELLOW);
public static final Ansi Blue = new Ansi(BLUE);
public static final Ansi Magenta = new Ansi(MAGENTA);
public static final Ansi Cyan = new Ansi(CYAN);
public static final Ansi White = new Ansi(WHITE);
public static final Ansi BgBlack = new Ansi(BACKGROUND_BLACK);
public static final Ansi BgRed = new Ansi(BACKGROUND_RED);
public static final Ansi BgGreen = new Ansi(BACKGROUND_GREEN);
public static final Ansi BgYellow = new Ansi(BACKGROUND_YELLOW);
public static final Ansi BgBlue = new Ansi(BACKGROUND_BLUE);
public static final Ansi BgMagenta = new Ansi(BACKGROUND_MAGENTA);
public static final Ansi BgCyan = new Ansi(BACKGROUND_CYAN);
public static final Ansi BgWhite = new Ansi(BACKGROUND_WHITE);
final private String[] codes;
final private String codes_str;
public Ansi(String... codes) {
this.codes = codes;
String _codes_str = "";
for (String code : codes) {
_codes_str += code;
}
codes_str = _codes_str;
}
public Ansi and(Ansi other) {
List<String> both = new ArrayList<String>();
Collections.addAll(both, codes);
Collections.addAll(both, other.codes);
return new Ansi(both.toArray(new String[]{}));
}
public String colorize(String original) {
return codes_str + original + SANE;
}
public String format(String template, Object... args) {
if (isWindows()) {
if (null == args || args.length == 0) {
return template;
}
return String.format(template, args);
}
String text = (null == args || args.length == 0) ? template : String.format(template, args);
return colorize(text);
}
}
没错,就是这个类,能控制输出字体颜色,但是没有自定义简单颜色类型,我很好奇这样就能自定义输出内容背景
和 字体样式
?测试了下,的确可以,本着搞清楚原因去看了源码中
给出的链接地址 http://www.topmudsites.com/forums/mud-coding/413-java-ansi.html
自定义控制台输出颜色
Java自带两种输出流输出的颜色
System.out.println(System.getProperty("java.version"));
System.err.println(System.getProperty("java.version"));
浏览器中输出不同颜色
console.log(window.navigator.appVersion)
console.warn(window.navigator.appVersion)
console.info(window.navigator.appVersion)
console.error(window.navigator.appVersion)
当然浏览器console
对象支持自定义背景色,
console.log("%c%s","background-color:teal;color:#fff;padding:3px;font-size:50px;font-family:'宋体',","Hello world")
但是Java不支持这种写法,但是可以通过ANSI
转码方式控制输出样式
Java简单封装自定义输出颜色
参考blade
中源码,发现其中样式还是不够灵活,查了下ANSI
表现形式,
发现不局限于语言,意思就是任何语言都支持这种写法。因此就十分有必要了解下了。
package com.wuxin;
/**
* @author: wuxin0011
* @Description:
*/
public class CustomColor {
public static void main(String[] args) throws Exception {
testColor();
}
public static void testColor() throws Exception {
for (int i = 0; i < 10; i++) {
Thread.sleep(200);
System.out.println(backgroundColor("java.version=", System.getProperty("java.version")));
}
System.out.println("==========================");
for (int i = 0; i < 10; i++) {
Thread.sleep(200);
System.out.println(fontColor("java.version=", System.getProperty("java.version")));
}
System.out.println("==========================");
for (int i = 0; i < 10; i++) {
Thread.sleep(200);
System.out.println(colorTemplate(new MyColor(), new MyColor(), "java.version=", System.getProperty("java.version")));
}
Thread.sleep(200);
System.out.println("==============custom color ============");
System.out.println(colorTemplate(new MyColor(0, 0, 0), new MyColor(255, 255, 255), "java.version=", System.getProperty("java.version")));
}
private static final int RGB_VALUE_MAX = 255;
private static final int BACKGROUND_COLOR = 48;
private static final int FONT_COLOR = 38;
private static final String CLEAR_COLOR = "\u001B[0m";
public static class MyColor {
public int R;
public int G;
public int L;
public MyColor(int r, int g, int l) {
this.R = r;
this.G = g;
this.L = l;
}
public MyColor() {
this.R = randomColorValue();
this.G = randomColorValue();
this.L = randomColorValue();
}
}
public static int randomColorValue() {
return (int) Math.floor(Math.random() * RGB_VALUE_MAX);
}
public static String fontColor(String... content) {
int R = randomColorValue();
int G = randomColorValue();
int L = randomColorValue();
return fontColor(R, G, L, content);
}
public static String fontColor(MyColor myColor, String... content) {
return fontColor(myColor.R, myColor.G, myColor.L, content);
}
public static String fontColor(int R, int G, int L, String... content) {
return colorTemplate(FONT_COLOR, R, G, L, content);
}
public static String backgroundColor(String... content) {
int R = randomColorValue();
int G = randomColorValue();
int L = randomColorValue();
return backgroundColor(R, G, L, content);
}
public static String backgroundColor(MyColor myColor, String... content) {
return backgroundColor(myColor.R, myColor.G, myColor.L, content);
}
public static String backgroundColor(int R, int G, int L, String... content) {
return colorTemplate(BACKGROUND_COLOR, R, G, L, content);
}
public static String colorTemplate(int type, int R, int G, int L, String... content) {
valid(R, G, L);
StringBuilder s = new StringBuilder();
for (String s1 : content) {
s.append(s1);
}
return String.format("\u001B[%d;2;%d;%d;%dm%s\u001B[0m", type, R, G, L, s.toString());
}
public static String colorTemplate(int R1, int G1, int L1, int R2, int G2, int L2, String... content) {
valid(R1, G1, L1, R2, G2, L2);
StringBuilder s = new StringBuilder();
for (String s1 : content) {
s.append(s1);
}
return String.format("\u001B[%s;2;%d;%d;%dm\u001B[%s;2;%d;%d;%dm%s\u001B[0m", BACKGROUND_COLOR, R1, G1, L1, FONT_COLOR, R2, G2, L2, s.toString());
}
public static String colorTemplate(MyColor bc, MyColor fc, String... content) {
return colorTemplate(bc.R, bc.G, bc.L, fc.R, fc.G, fc.L, content);
}
public static void valid(MyColor... myColors) {
for (MyColor myColor : myColors) {
valid(myColor.R, myColor.G, myColor.L);
}
}
public static void valid(int... ints) {
for (int result : ints) {
if (result > RGB_VALUE_MAX) {
throw new RuntimeException("color value max is " + RGB_VALUE_MAX);
}
}
}
}
关于\u001B[%s;2;%d;%d;%dm%s\u001B[0m
含义
-
\u001B[
开启颜色模式 -
%s
表示是字体颜色(38)还是背景颜色(48) -
2 是启用
rgb
模式,用5表示启用#000
这种形式颜色,上面没有封装#xxx
这种形式 -
三个
%d
分别对应rgb
三个位置数值 -
%s
表示输出内容,就是你传入字符串 -
\u001B[0m
表示还原,这样就不影响后续输出了
执行测试结果
将编译好文件上传到Linux环境中测试
JS简单封装自定义输出颜色
function backgroundColor(...str){
function colorRandom(l=255){
return Math.floor(Math.random()*l)
}
let r = colorRandom();
let g = colorRandom();
let l = colorRandom();
let printColor = (...m)=>console.log(`\u001B[48;2;${r};${g};${l}m ${m} \u001B[0m`)
printColor(str)
}
function fontColor(...str){
function colorRandom(l=255){
return Math.floor(Math.random()*l)
}
let r = colorRandom();
let g = colorRandom();
let l = colorRandom();
let printColor = (...m)=>console.log(`\u001B[38;2;${r};${g};${l}m ${m} \u001B[0m`)
printColor(str)
}
Array.from({length:10}).forEach(()=>{
fontColor("hello world")
console.log('=============================')
backgroundColor("hello world")
})
这里只是简单写了下,意思到了就行,就是说明可以自定义。
在浏览器中执行就是代码测试
执行测试结果
测试浏览器是Edge浏览器
经测试在firefox
中测试无效!说明兼容性不是很好
简单处理下兼容性问题
function isFirefox() {
// 顺便兼容下node环境
try {
if (typeof window !== undefined) {
return window.navigator.userAgent.indexOf("Firefox") !== -1;
}
} catch (error) {
// ignore
}
return false
}
function backgroundColor(...str) {
function colorRandom(l = 255) {
return Math.floor(Math.random() * l)
}
let r = colorRandom();
let g = colorRandom();
let l = colorRandom();
let printColor = (...m) => {
if (isFirefox()) {
console.log(`%c${m}`, `background-color: rgb(${r}, ${g}, ${l})`)
}
else {
console.log(`\u001B[48;2;${r};${g};${l}m ${m} \u001B[0m`)
}
}
printColor(str)
}
function fontColor(...str) {
function colorRandom(l = 255) {
return Math.floor(Math.random() * l)
}
let r = colorRandom();
let g = colorRandom();
let l = colorRandom();
let printColor = (...m) => {
if (isFirefox()) {
console.log(`%c${m}`, `color: rgb(${r}, ${g}, ${l})`)
} else {
console.log(`\u001B[38;2;${r};${g};${l}m ${m} \u001B[0m`)
}
}
return printColor(str)
}
Array.from({ length: 10 }).forEach(() => {
fontColor("hello world")
console.log('=============================')
backgroundColor("hello world")
})
node 中执行
C封装
作为万物起源,C当然也支持了!
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define COLOR_MAX 255
#define COLOR_BACKGROUND 48
#define COLOR_FONT 38
/*define */
typedef struct CustomColor
{
int R;
int G;
int L;
}CustomColor;
void backgroundColorPrint(int R,int G,int L,char* ch);
void colorPrintTemplate(int type ,int R,int G,int L,char* ch);
void fontColorAndBackgroundTemplate(int R,int G,int L,int R1,int G1,int L1,char* ch);
void backgroundColorPrint(int R,int G,int L,char* ch);
void fontColorPrint(int R,int G,int L,char* ch);
int randomValue();
bool valid(int c);
CustomColor genCustomColor(int R,int G,int L);
void printRGL(int R,int G,int L);
void warning(char* ch);
void info(char* ch);
void error(char* ch);
void success(char* ch);
/******************************************************************************************/
int main(){
char ch[] = "c language print color !";
warning(ch);
info(ch);
error(ch);
success(ch);
for(int i = 0;i<30;i++){
int R = randomValue();
int G = randomValue();
int L = randomValue();
int R1 = randomValue();
int G1 = randomValue();
int L1 = randomValue();
// printRGL(R,G,L);
backgroundColorPrint(R,G,L,ch);
fontColorPrint(R1,G1,L1,ch);
}
return 0;
}
int randomValue(){
return rand() % COLOR_MAX;
}
bool valid(int c){
return 0<=c && c<=COLOR_MAX;
}
void colorPrintTemplate(int type ,int R,int G,int L,char* ch){
if( !(valid(R) && valid(G) && valid(L))){
// if valid fail use default print
printf("%s\n",ch);
return;
}
printf("\u001B[%d;2;%d;%d;%dm %s\u001B[0m\n",type,R,G,L,ch);
}
void fontColorAndBackgroundTemplate(int R,int G,int L,int R1,int G1,int L1,char* ch){
if( !(valid(R) && valid(G) && valid(L) && valid(R1) && valid(G1) && valid(L1))){
// if valid fail use default print
printf("%s\n",ch);
return;
}
printf("\u001B[%d;2;%d;%d;%dm\u001B[%d;2;%d;%d;%dm%s\u001B[0m\n",COLOR_BACKGROUND,R,G,L,COLOR_FONT,R1,G1,L1,ch);
}
void backgroundColorPrint(int R,int G,int L,char* ch){
colorPrintTemplate(COLOR_BACKGROUND,R,G,L,ch);
}
void fontColorPrint(int R,int G,int L,char* ch){
colorPrintTemplate(COLOR_FONT,R,G,L,ch);
}
void printRGL(int R,int G,int L){
printf("R = %d,G = %d,L = %d\n",R,G,L);
}
CustomColor genCustomColor(int R,int G,int L){
CustomColor cs = {R,G,L};
return cs;
}
void warning(char* ch){
fontColorAndBackgroundTemplate(51, 43, 0,181, 157, 38,ch);
}
void error(char* ch){
fontColorAndBackgroundTemplate(41, 0, 0,255, 128, 95,ch);
}
void info(char* ch){
fontColorAndBackgroundTemplate(0,0,0,255,255,255,ch);
}
void success(char* ch){
fontColorAndBackgroundTemplate(68, 144, 54,255,255,255,ch);
}
测试结果
color 命令
在 window cmd
控制台中有这样一个命令 color
当然也可以通过属性调整
可以通过这种方式手动控制CMD控制台颜色,不过这种方式不太推荐。