Skip to content

Instantly share code, notes, and snippets.

@coderodde
Last active July 7, 2026 11:48
Show Gist options
  • Select an option

  • Save coderodde/f424ed8792313c148184a3852eaa6177 to your computer and use it in GitHub Desktop.

Select an option

Save coderodde/f424ed8792313c148184a3852eaa6177 to your computer and use it in GitHub Desktop.
DualTextProgressBar.java - a text UI for the progress bar in terminal enironments.
package io.github.coderodde.textui.components;
import java.io.IOException;
import org.jline.terminal.Terminal;
import org.jline.terminal.TerminalBuilder;
/**
* This class implements a simple text UI progress bar.
*/
public final class DualTextProgressBar {
/**
* Used for computing the progress percentage.
*/
private static final int HUNDRED_PERCENT = 100;
/**
* How many characters are needed for representing everything else but the
* actual progress bar consisting of a number of <code>#</code> or
* <code>.</code> characters.
*/
private static final int CHARACTER_QUOTA = 7;
/**
* The number of progress tokens.
*/
private final int width;
/**
* The progress percentage. 0 is zero progress, 1 is the full progress.
*/
private float progress = 0.0f;
public DualTextProgressBar() throws IOException {
Terminal terminal = TerminalBuilder.builder().system(true).build();
int terminalWidth = terminal.getColumns();
this.width = terminalWidth - CHARACTER_QUOTA;
}
public void setProgress(float p) {
checkNotNaN(p);
progress = Math.clamp(p, 0f, 1f);
clearBar();
System.out.print((getBar()));
System.out.flush();
}
private void checkNotNaN(float f) {
if (Float.isNaN(f)) {
throw new IllegalArgumentException("The argument float is NaN.");
}
}
private void clearBar() {
for (int i = 0; i < width + CHARACTER_QUOTA; ++i) {
System.out.print("\b");
}
}
public static void main(String[] args) throws IOException {
DualTextProgressBar bar = new DualTextProgressBar();
for (float f = 0.0f; f <= 1.005f; f += 0.01f) {
bar.setProgress(f);
try {
Thread.sleep(100L);
} catch (InterruptedException ignored) {
}
}
}
private String getBar() {
int nFilled = (int)(progress * width);
int nFilledRight = nFilled / 2;
int nFilledLeft = nFilled - nFilledRight;
int nNonFilled = width - nFilled;
StringBuilder sb =
new StringBuilder(width + CHARACTER_QUOTA).append("[");
sb.append(String.format("%3d%% ", (int) (HUNDRED_PERCENT * progress)));
for (int i = 0; i < nFilledLeft; ++i) {
sb.append("#");
}
for (int i = 0; i < nNonFilled; ++i) {
sb.append(".");
}
for (int i = 0; i < nFilledRight; ++i) {
sb.append("#");
}
return sb.append("]").toString();
}
}
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>io.github.coderodde.textui.components</groupId>
<artifactId>DualTextProgressBar.java</artifactId>
<version>1.0</version>
<packaging>jar</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.release>21</maven.compiler.release>
<exec.mainClass>io.github.coderodde.textui.components.DualTextProgressBar</exec.mainClass>
</properties>
<name>DualTextProgressBar.java</name>
<dependencies>
<dependency>
<groupId>org.jline</groupId>
<artifactId>jline</artifactId>
<version>4.2.1</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.4.2</version>
<configuration>
<archive>
<manifest>
<mainClass>
io.github.coderodde.textui.components.DualTextProgressBar
</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.6.2</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>io.github.coderodde.textui.components.DualTextProgressBar</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment