/** * The Terminal class provides methods to interact with the terminal through ANSI * control sequences. This allows us to print to the terminal in color and with * other "fanciness" (like italics or flashing letters). It also allows reading * input without needing the user to press enter first, and reading keys like the * arrow keys or Escape that are not normally accessible. * * There are some caveats to the use of this class: * - this is not portable and is unlikely to work on Windows or under an IDE * - to print a newline, we must now print "\n\r", which means .println() will * not work properly. * - this won't interact with Scanner well, use the provided .getLine() method * to read input instead * - rawMode must be called before any of these methods can be expected to work * properly, and cookedMode should be called just before the program ends (or * your terminal will be wonky after the program quits) */ import java.io.IOException; public class Terminal { private static final String ESC = "\033["; private static final int ESC_CODE = 27; /** * Clears the terminal window and moves the cursor back to the upper left */ public static void clear() { System.out.print(ESC + "H" + ESC + "2J"); System.out.flush(); } /** * Pauses the program for some amount of time * @param seconds the number of seconds to pause, which can be fractional */ public static void pause(double seconds) { try { Thread.sleep((int) (seconds * 1000.0)); } catch (InterruptedException e) {} } /** * Sets the text mode to one of those in the TextMode enumeration * this lasts until setTextMode is called again, or the reset method * is called. * @param mode the mode which will be set */ public static void setTextMode(TextMode mode) { System.out.print(ESC); switch (mode) { case BOLD: System.out.print(1); break; case DIM: System.out.print(2); break; case ITALIC: System.out.print(3); break; case UNDERLINE: System.out.print(4); break; case BLINKING: System.out.print(5); break; case INVERSE: System.out.print(7); break; case INVISIBLE: System.out.print(8); break; case STRIKETHROUGH:System.out.print(9); break; } System.out.print("m"); } /** * Sets the foreground color we print to the terminal with to * one of the eight available options. This lasts until the * setForeground method is called again, or reset is called. * @param color the color to be set */ public static void setForeground(Color color) { System.out.print(ESC); switch (color) { case BLACK: System.out.print(30); break; case RED: System.out.print(31); break; case GREEN: System.out.print(32); break; case YELLOW: System.out.print(33); break; case BLUE: System.out.print(34); break; case MAGENTA:System.out.print(35); break; case CYAN: System.out.print(36); break; case WHITE: System.out.print(37); break; } System.out.print("m"); } /** * Sets the background color we print to the terminal with to * one of the eight available options. This lasts until the * setBackground method is called again, or reset is called. * @param color the color to be set */ public static void setBackground(Color color) { System.out.print(ESC); switch (color) { case BLACK: System.out.print(40); break; case RED: System.out.print(41); break; case GREEN: System.out.print(42); break; case YELLOW: System.out.print(43); break; case BLUE: System.out.print(44); break; case MAGENTA:System.out.print(45); break; case CYAN: System.out.print(46); break; case WHITE: System.out.print(47); break; } System.out.print("m"); } /** * Sets the terminal color and text mode back to the default values * it is not possible to reset only one of these things */ public static void reset() { System.out.print(ESC + "0m"); System.out.flush(); } /** * Moves the cursor to a position on the screen * @param row which row to put the cursor on where 0 is the top of the * screen and we count up down from there * @param col which column to put the cursor on where 0 is the left and * we count up to the right */ public static void warpCursor(int row, int col) { System.out.println(ESC + row + ";" + (col+1) + "H"); } /** * Puts the terminal window into "raw" mode which allows us to read * keys before they are processed allowing for a more interactive game. * This must be called before any of the input methods will work */ public static void rawMode() { String[] cmd = {"/bin/sh", "-c", "stty raw 0) { line = line.substring(0, line.length() - 1); } break; default: // append it to the text char val = (char) next.getCode(); if (val != 0) { line = line + val; } } } // print final string and return it System.out.print(prompt + line + "\n\r"); return line; } }