Terminals are not limited to printing text line by line. Using ANSI escape sequences, applications can control where text appears on the screen and dynamically update content.
This capability is the foundation for building interactive terminal applications, dashboards, and progress indicators.
By controlling the cursor position and clearing parts of the screen, programs can update information in place instead of continuously printing new lines.
Libraries such as Jansi make it easy to send these control sequences from Java applications.
1. Moving the Cursor
One of the most useful ANSI capabilities is moving the cursor to a specific position on the terminal screen.
The escape sequence for cursor positioning is: ESC[row;columnH
Here:
· row → vertical position (top to bottom)
· column → horizontal position (left to right)
Example
ESC[10;5H
Above statement move the cursor to row 10, column 5. When the program prints text after this command, it will appear at that exact location.
Example With Java
System.out.print("\u001B[10;5HHello");
This technique allows programs to build structured terminal layouts, such as tables, dashboards, and menus.
Experiment with following application to understand the cursor movement.
CursorPositionPrinter.java
package com.sample.app; import org.fusesource.jansi.AnsiConsole; import java.util.Scanner; public class CursorPositionPrinter { private static final String EXIT_COMMAND = "exit"; public static void main(String[] args) { AnsiConsole.systemInstall(); Scanner scanner = new Scanner(System.in); System.out.println("===================================="); System.out.println(" Cursor Position Printer"); System.out.println("===================================="); System.out.println("Enter row, column, and message."); System.out.println("Type 'exit' anytime to quit.\n"); while (true) { System.out.print("Row (or 'exit'): "); String rowInput = scanner.nextLine(); if (isExit(rowInput)) break; System.out.print("Column (or 'exit'): "); String colInput = scanner.nextLine(); if (isExit(colInput)) break; System.out.print("Message (or 'exit'): "); String message = scanner.nextLine(); if (isExit(message)) break; try { int row = Integer.parseInt(rowInput); int col = Integer.parseInt(colInput); // Clear the screen System.out.print("\u001B[2J"); // Move cursor String cursorMove = "\u001B[" + row + ";" + col + "H"; System.out.print(cursorMove + message); System.out.flush(); // Move cursor below output for next input System.out.print("\u001B[" + (row + 2) + ";1H"); } catch (NumberFormatException e) { System.out.println("Invalid row/column value. Please enter numbers only."); } } System.out.println("\nExiting program..."); scanner.close(); AnsiConsole.systemUninstall(); } private static boolean isExit(String input) { return EXIT_COMMAND.equalsIgnoreCase(input.trim()); } }
2. Clearing Lines
When building dynamic terminal interfaces, programs often need to remove previously printed text before displaying updated information. ANSI escape codes provide commands that allow applications to clear either individual lines or the entire screen.
This prevents the terminal from filling up with repeated messages and enables applications to create clean, continuously updating output.
Typical use cases include:
· progress indicators
· download status updates
· live counters
· interactive terminal dashboards
2.1 Clearing the Current Line
The most common command used to clear a line is: ESC[2K
It clear the entire current line where the cursor is located.
In code, the escape character is often written as: \u001B[2K
FileDownloadDemo.java
package com.sample.app; import org.fusesource.jansi.AnsiConsole; public class FileDownloadDemo { public static void main(String[] args) throws Exception { AnsiConsole.systemInstall(); System.out.println("Downloading file: report-data.zip\n"); for (int progress = 0; progress <= 100; progress++) { // Move cursor to beginning of line System.out.print("\r"); // Clear the entire line System.out.print("\u001B[2K"); // Print updated progress System.out.print("Downloading... " + progress + "%"); System.out.flush(); Thread.sleep(100); } // Clear line one last time System.out.print("\r\u001B[2K"); System.out.println("Download complete ✓"); AnsiConsole.systemUninstall(); } }
2.2 Clearing the Entire Screen
Another related command is: ESC[2J, it is used to clear the entire screen. However, this command does not automatically reposition the cursor. After clearing the screen, programs typically move the cursor back to the top-left corner using ESC[H.
So a common sequence for clearing and resetting the screen is: ESC[2J ESC[H.
This sequence:
· Clears the screen
· Moves the cursor to the home position (row 1, column 1)
SystemMonitorDemo.java
package com.sample.app; import org.fusesource.jansi.AnsiConsole; import java.lang.management.ManagementFactory; import java.lang.management.OperatingSystemMXBean; import java.util.Random; public class SystemMonitorDemo { public static void main(String[] args) throws Exception { AnsiConsole.systemInstall(); OperatingSystemMXBean osBean = ManagementFactory.getOperatingSystemMXBean(); Runtime runtime = Runtime.getRuntime(); Random random = new Random(); while (true) { // Clear entire screen System.out.print("\u001B[2J"); // Move cursor to home position System.out.print("\u001B[H"); System.out.println("====================================="); System.out.println(" TERMINAL SYSTEM DASHBOARD "); System.out.println("=====================================\n"); // CPU usage (simulated or load average) double cpuLoad = osBean.getSystemLoadAverage(); System.out.println("CPU Load Average : " + cpuLoad); // Memory usage long totalMemory = runtime.totalMemory() / (1024 * 1024); long freeMemory = runtime.freeMemory() / (1024 * 1024); long usedMemory = totalMemory - freeMemory; System.out.println("Total Memory : " + totalMemory + " MB"); System.out.println("Used Memory : " + usedMemory + " MB"); System.out.println("Free Memory : " + freeMemory + " MB"); // Simulated Disk usage int diskUsage = random.nextInt(100); System.out.println("Disk Usage : " + diskUsage + "%"); System.out.println("\n-------------------------------------"); System.out.println("Refreshing every 2 seconds..."); System.out.println("Press Ctrl+C to exit"); System.out.flush(); Thread.sleep(2000); } } }
Following table summarizes the escape codes.
|
Escape Code |
Action |
|
ESC[2K |
Clear the current line |
|
ESC[K |
Clear from cursor to end of line |
|
ESC[1K |
Clear from start of line to cursor |
|
ESC[2J |
Clear the entire screen |
|
ESC[H |
Move cursor to home position |
3. Updating Specific Screen Regions
By combining cursor movement and line clearing, applications can update only specific parts of the screen.
For example:
· Move cursor to a location
· Clear the line
· Print new data
Example:
System.out.print("\u001B[5;1H"); // Move cursor System.out.print("\u001B[2K"); // Clear line System.out.println("CPU Usage: 72%");
This technique allows programs to create live dashboards that update in place.
Each line can be updated independently without redrawing the whole screen. Many terminal monitoring tools use this approach to refresh information several times per second.
4. Cursor Hiding and Showing
When building dynamic terminal interfaces, the blinking cursor can become distracting. ANSI escape sequences allow applications to hide and show the cursor.
Hide cursor: ESC[?25l
Show cursor again: ESC[?25h
CursorHideDemo.java
package com.sample.app; import org.fusesource.jansi.AnsiConsole; public class CursorHideDemo { public static void main(String[] args) throws Exception { AnsiConsole.systemInstall(); // Hide cursor System.out.print("\u001B[?25l"); String[] spinner = {"|", "/", "-", "\\"}; System.out.println("Processing data..."); for (int i = 0; i < 40; i++) { // Move cursor to beginning of line System.out.print("\r"); // Display animated spinner System.out.print("Working " + spinner[i % spinner.length]); System.out.flush(); Thread.sleep(150); } // Move to new line System.out.print("\r"); System.out.println("Task completed successfully ✓"); // Show cursor again System.out.print("\u001B[?25h"); AnsiConsole.systemUninstall(); } }
5. How Dynamic Terminal Interfaces Work?
Modern terminal applications rely heavily on these techniques:
· cursor movement
· line clearing
· selective screen updates
· cursor visibility control
Together, these capabilities allow developers to build rich text-based user interfaces directly in the terminal. Tools like htop, btop use the same techniques to display live system statistics and interactive dashboards.
Previous Next Home
No comments:
Post a Comment