前言

最近在写一个命令行中的下载工具,既然是下载文件用的,那么实时显示下载进度是非常有必要的。因此,就有了这里对进度条的实现尝试。

预览图

还是先预览下效果图吧。 这里是cmd里面的效果,总体看着还行,不足之处就是可以看到前面的游标在闪烁。

Gif

这里是IDEA里面运行的效果图,由于字符间距都比较大,所以这里看着效果不怎么好。

Gif

原理

这里关键是用到了这个函数

System.out.print("\b");

其中转义符**\b**的作用就是删除游标前面的一个字符。

这里举个栗子:

System.out.print("hello,world!");
System.out.print("\b\b");

执行完第一行后是输出了

hello,world!

注意这里都用的都是print函数,而不是println函数。 执行到第二行后,输出就变为了

hello,worl

因为有两个**\b**,所以删除两个字符,因此删掉了d和!,还剩下hello,worl 原理懂了之后,剩下的效果实现应该是非常简单了。下面直接上代码吧。

代码

Talk is cheap,show me the code! ------ 屁话少说,放码过来!


public class ProgressBar {

    private int index = 0;
    private String finish;
    private String unFinish;


    // 进度条粒度
    private final int PROGRESS_SIZE = 50;
    private int BITE = 2;

    private String getNChar(int num, char ch){
        StringBuilder builder = new StringBuilder();
        for(int i = 0; i < num; i++){
            builder.append(ch);
        }
        return builder.toString();
    }

    public void printProgress() throws InterruptedException {
        System.out.print("Progress:");

        finish = getNChar(index / BITE, '█');
        unFinish = getNChar(PROGRESS_SIZE - index / BITE, '─');
        String target = String.format("%3d%%[%s%s]", index, finish, unFinish);
        System.out.print(target);

        while (index <= 100){
            finish = getNChar(index / BITE, '█');
            unFinish = getNChar(PROGRESS_SIZE - index / BITE, '─');

            target = String.format("%3d%%├%s%s┤", index, finish, unFinish);
            System.out.print(getNChar(PROGRESS_SIZE + 6, '\b'));
            System.out.print(target);

            Thread.sleep(50);
            index++;
        }
    }
}