Last active
July 7, 2026 11:48
-
-
Save coderodde/f424ed8792313c148184a3852eaa6177 to your computer and use it in GitHub Desktop.
DualTextProgressBar.java - a text UI for the progress bar in terminal enironments.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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(); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?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