写点什么

控制台彩色输出

作者:FunTester
  • 2021 年 12 月 07 日
  • 本文字数:2290 字

    阅读完需:约 8 分钟

今天在看另外一个优秀框架的源码的过程中,我发现了一个奇怪的现象,框架输出的内容居然自带颜色,这引起了我极大的好奇心。


追根溯源,终于找到了 Jansi。Jansi 是一个小型的 ASL 2.0 许可的 Java 库,它允许您使用 ANSI 转义序列来格式化您的控制台输出。


下面分享一下 Jansi 的简单使用和我自己封装方法,以及随机输出颜色的文本的方法封装(这个我又强行一行代码实现了),先来一张效果图


依赖

  • Gradle


    // https://mvnrepository.com/artifact/org.fusesource.jansi/jansi    implementation group: 'org.fusesource.jansi', name: 'jansi', version: '2.4.0'
复制代码


  • Maven


<!-- https://mvnrepository.com/artifact/org.fusesource.jansi/jansi --><dependency>    <groupId>org.fusesource.jansi</groupId>    <artifactId>jansi</artifactId>    <version>2.4.0</version></dependency>
复制代码

Demo

根据官方的最佳实践,的确啥也没找到,只有 API Docs,只是简单列罗列,还不如写在源码中。下面是我找到的几个成功的例子:


import com.funtester.frame.SourceCode;import org.fusesource.jansi.Ansi;
public class Jnst extends SourceCode {
public static void main(String[] args) {
String blue = Ansi.ansi().fg(Ansi.Color.BLUE).a("蓝色FunTester").reset().toString(); output(blue); String red = Ansi.ansi().fgRed().a("红色FunTester").reset().toString(); output(red);
String red1 = Ansi.ansi().fgBrightRed().a("红色FunTester").fgYellow().a("黄色FunTester").fgBrightGreen().a("绿色FunTester").reset().toString(); output(red1);
Ansi ansi = Ansi.ansi(); Ansi a = ansi.fgRed().a("红色FunTester").fgBrightGreen().a("绿色FunTester"); output(ansi); output("会打印绿色字符"); ansi.reset(); output(a); output("会打印正常颜色字符"); }
}
复制代码


三种设置颜色和内容的方法,大家去翻源码本质上也是各种封装。这里每一个 ansi 对象都有一个 private final StringBuilder builder;,如果大家想复用一个 ansi 对象,只要重置这个 private final StringBuilder builder;属性即可,重置的思路可以借助 Java 反射,言至于此,改天有机会再分享具体实现。


其中 Jansi 支持的几种颜色如下:


        BLACK(0, "BLACK"),        RED(1, "RED"),        GREEN(2, "GREEN"),        YELLOW(3, "YELLOW"),        BLUE(4, "BLUE"),        MAGENTA(5, "MAGENTA"),        CYAN(6, "CYAN"),        WHITE(7, "WHITE"),        DEFAULT(9, "DEFAULT");
复制代码

封装

下面是我的封装方法,比较简单,就是为了少些几行代码。我放弃了复用 ansi 对象的思路,因为反射执行效率太差了。


    public static String color(Ansi.Color color, Object o) {        return ansi().fg(color).a(o.toString()).reset().toString();    }
public static void black(String str) { System.out.println(ansi().fgBlack().a(str)); }
public static void blue(Object o) { output(color(Ansi.Color.BLUE, o)); }
public static void red(Object o) { output(color(Ansi.Color.RED, o)); }
public static void green(Object o) { output(color(Ansi.Color.GREEN, o)); }
public static void yellow(Object o) { output(color(Ansi.Color.YELLOW, o)); }
public static void white(Object o) { output(color(Ansi.Color.WHITE, o)); }
public static void black(Object o) { output(color(Ansi.Color.BLACK, o)); }
public static void gyan(Object o) { output(color(Ansi.Color.CYAN, o)); }
public static void magenta(Object o) { output(color(Ansi.Color.MAGENTA, o)); }
复制代码

拓展

我拓展了一个将字符串里面的字符随机设置颜色(排除黑色,因为我常用的黑色背景)的方法,总体思路就是讲字符串拆成字符数组,然后逐个转换拼接。


第一种方法:


    public static String rgb(String str) {        char[] array = str.toCharArray();        List<Ansi.Color> collect = Stream.of(Ansi.Color.values()).filter(v -> v != Ansi.Color.BLACK).collect(Collectors.toList());        Ansi ansi = ansi();        for (int i = 0; i < array.length; i++) {            ansi.fg(random(collect)).a(array[i]);        }        return ansi.reset().toString();    }
复制代码


当然我们也可以强行将这些代码写成一行:


    public static String rgb(String str) {        return Stream.of(ArrayUtils.toObject(str.toCharArray())).map(f -> color(random(Stream.of(Ansi.Color.values()).filter(v -> v != Ansi.Color.BLACK).collect(Collectors.toList())), f)).collect(Collectors.joining());    }
复制代码


用到不少 Lambda 语法,有兴趣的小伙伴可以看看 Lambda 语法,能省不少代码。

欢迎关注 FunTester,Have Fun ~ Tester !

发布于: 2 小时前阅读数: 8
用户头像

FunTester

关注

公众号:FunTester,650+原创,欢迎关注 2020.10.20 加入

Have Fun,Tester! 公众号FunTester,坚持原创文章的测试人。 FunTester测试框架作者,DCS_FunTester分布式性能测试框架作者。

评论

发布
暂无评论
控制台彩色输出