java/sql-dk/src/main/java/info/globalcode/sql/dk/ColorfulPrintWriter.java
author František Kučera <franta-hg@frantovo.cz>
Thu, 24 Oct 2019 21:43:08 +0200
branchv_0
changeset 250 aae5009bd0af
parent 238 4a1864c3e867
permissions -rw-r--r--
fix license version: GNU GPLv3
     1 /**
     2  * SQL-DK
     3  * Copyright © 2013 František Kučera (frantovo.cz)
     4  *
     5  * This program is free software: you can redistribute it and/or modify
     6  * it under the terms of the GNU General Public License as published by
     7  * the Free Software Foundation, version 3 of the License.
     8  *
     9  * This program is distributed in the hope that it will be useful,
    10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  * GNU General Public License for more details.
    13  *
    14  * You should have received a copy of the GNU General Public License
    15  * along with this program. If not, see <http://www.gnu.org/licenses/>.
    16  */
    17 package info.globalcode.sql.dk;
    18 
    19 import java.io.File;
    20 import java.io.FileNotFoundException;
    21 import java.io.OutputStream;
    22 import java.io.PrintWriter;
    23 import java.io.UnsupportedEncodingException;
    24 import java.io.Writer;
    25 import java.util.EnumSet;
    26 
    27 /**
    28  * PrintWriter with convenience methods for printing color and formatted text.
    29  *
    30  * Uses ANSI Escape Sequences.
    31  * See: http://www.tldp.org/HOWTO/Bash-Prompt-HOWTO/x329.html
    32  *
    33  * @author Ing. František Kučera (frantovo.cz)
    34  */
    35 public class ColorfulPrintWriter extends PrintWriter {
    36 
    37 	public enum TerminalColor {
    38 
    39 		Black(30, 40),
    40 		Red(31, 41),
    41 		Green(32, 42),
    42 		Yellow(33, 43),
    43 		Blue(34, 44),
    44 		Magenta(35, 45),
    45 		Cyan(36, 46),
    46 		White(37, 47);
    47 		private final int foregroundCode;
    48 		private final int backgroundCode;
    49 
    50 		private TerminalColor(int foregroundCode, int backgroundCode) {
    51 			this.foregroundCode = foregroundCode;
    52 			this.backgroundCode = backgroundCode;
    53 		}
    54 
    55 		public int getForegroundCode() {
    56 			return foregroundCode;
    57 		}
    58 
    59 		public int getBackgroundCode() {
    60 			return backgroundCode;
    61 		}
    62 	}
    63 
    64 	public enum TerminalStyle {
    65 
    66 		Reset(0),
    67 		Bright(1),
    68 		Dim(2),
    69 		Underscore(4),
    70 		Blink(5),
    71 		Reverse(7),
    72 		Hidden(8);
    73 		private int code;
    74 
    75 		private TerminalStyle(int code) {
    76 			this.code = code;
    77 		}
    78 
    79 		public int getCode() {
    80 			return code;
    81 		}
    82 	}
    83 	private final boolean COLOR_ENABLED;
    84 	private boolean colorful = true;
    85 
    86 	public void setStyle(TerminalStyle style) {
    87 		setStyle(EnumSet.of(style));
    88 	}
    89 
    90 	public void setStyle(EnumSet<TerminalStyle> styles) {
    91 		printCodes(getStyleCodes(styles));
    92 	}
    93 
    94 	private static int[] getStyleCodes(EnumSet<TerminalStyle> styles) {
    95 		int[] array = new int[styles.size()];
    96 		int i = 0;
    97 		for (TerminalStyle s : styles) {
    98 			array[i++] = s.getCode();
    99 		}
   100 		return array;
   101 	}
   102 
   103 	/**
   104 	 * Print (usually audible) bell code (\007, \a, ^G)
   105 	 */
   106 	public void bell() {
   107 		print("\007");
   108 	}
   109 
   110 	/**
   111 	 * Eat the last character
   112 	 */
   113 	public void backspace() {
   114 		print("\b");
   115 	}
   116 
   117 	/**
   118 	 * Eat n last characters
   119 	 *
   120 	 * @param count n
   121 	 */
   122 	public void backspace(int count) {
   123 		for (int i = 0; i < count; i++) {
   124 			backspace();
   125 		}
   126 	}
   127 
   128 	/**
   129 	 * With 100 ms delay and all colors.
   130 	 *
   131 	 * @see #printRainbow(java.lang.String, int,
   132 	 * info.globalcode.sql.dk.ColorfulPrintWriter.TerminalColor[])
   133 	 */
   134 	public void printRainbow(String string) {
   135 		printRainbow(string, 100);
   136 	}
   137 
   138 	/**
   139 	 * With all colors.
   140 	 *
   141 	 * @see #printRainbow(java.lang.String, int,
   142 	 * info.globalcode.sql.dk.ColorfulPrintWriter.TerminalColor[])
   143 	 */
   144 	public void printRainbow(String string, int delay) {
   145 		printRainbow(string, delay, TerminalColor.values());
   146 	}
   147 
   148 	/**
   149 	 * Prints rainbow text – (re)writes same text subsequently in given colors and then in default
   150 	 * color.
   151 	 *
   152 	 * @param string text to be printed, should not contain \n new line (then rainbow does not work
   153 	 * – use println() after printRainbow() instead)
   154 	 * @param delay delay between rewrites
   155 	 * @param colors list of colors to be used
   156 	 */
   157 	public void printRainbow(String string, int delay, TerminalColor... colors) {
   158 		for (TerminalColor c : colors) {
   159 			print(c, string);
   160 			try {
   161 				Thread.sleep(delay);
   162 			} catch (InterruptedException e) {
   163 				// no time to sleep
   164 				break;
   165 			}
   166 			backspace(string.length());
   167 			flush();
   168 		}
   169 		print(string);
   170 	}
   171 
   172 	public void setForegroundColor(TerminalColor color) {
   173 		printCodes(color.getForegroundCode());
   174 	}
   175 
   176 	public void setBackgroundColor(TerminalColor color) {
   177 		printCodes(color.getBackgroundCode());
   178 	}
   179 
   180 	public void print(TerminalColor foregroundColor, String string) {
   181 		setForegroundColor(foregroundColor);
   182 		print(string);
   183 		resetAll();
   184 	}
   185 
   186 	public void println(TerminalColor foregroundColor, String string) {
   187 		print(foregroundColor, string);
   188 		println();
   189 	}
   190 
   191 	public void print(TerminalColor foregroundColor, TerminalColor backgroundColor, String string) {
   192 		setForegroundColor(foregroundColor);
   193 		setBackgroundColor(backgroundColor);
   194 		print(string);
   195 		resetAll();
   196 	}
   197 
   198 	public void println(TerminalColor foregroundColor, TerminalColor backgroundColor, String string) {
   199 		print(foregroundColor, backgroundColor, string);
   200 		println();
   201 	}
   202 
   203 	public void print(TerminalColor foregroundColor, TerminalColor backgroundColor, EnumSet<TerminalStyle> styles, String string) {
   204 		setForegroundColor(foregroundColor);
   205 		setBackgroundColor(backgroundColor);
   206 		setStyle(styles);
   207 		print(string);
   208 		resetAll();
   209 	}
   210 
   211 	public void println(TerminalColor foregroundColor, TerminalColor backgroundColor, EnumSet<TerminalStyle> styles, String string) {
   212 		print(foregroundColor, backgroundColor, styles, string);
   213 		println();
   214 	}
   215 
   216 	public void print(TerminalColor foregroundColor, TerminalColor backgroundColor, TerminalStyle style, String string) {
   217 		print(foregroundColor, backgroundColor, EnumSet.of(style), string);
   218 	}
   219 
   220 	public void println(TerminalColor foregroundColor, TerminalColor backgroundColor, TerminalStyle style, String string) {
   221 		print(foregroundColor, backgroundColor, style, string);
   222 		println();
   223 	}
   224 
   225 	public void print(TerminalColor foregroundColor, EnumSet<TerminalStyle> styles, String string) {
   226 		setForegroundColor(foregroundColor);
   227 		setStyle(styles);
   228 		print(string);
   229 		resetAll();
   230 	}
   231 
   232 	public void println(TerminalColor foregroundColor, EnumSet<TerminalStyle> styles, String string) {
   233 		print(foregroundColor, styles, string);
   234 		println();
   235 	}
   236 
   237 	public void print(TerminalColor foregroundColor, TerminalStyle style, String string) {
   238 		print(foregroundColor, EnumSet.of(style), string);
   239 	}
   240 
   241 	public void println(TerminalColor foregroundColor, TerminalStyle style, String string) {
   242 		print(foregroundColor, style, string);
   243 		println();
   244 	}
   245 
   246 	public void print(EnumSet<TerminalStyle> styles, String string) {
   247 		setStyle(styles);
   248 		print(string);
   249 		resetAll();
   250 	}
   251 
   252 	public void println(EnumSet<TerminalStyle> styles, String string) {
   253 		print(styles, string);
   254 		println();
   255 	}
   256 
   257 	public void print(TerminalStyle style, String string) {
   258 		print(EnumSet.of(style), string);
   259 	}
   260 
   261 	public void println(TerminalStyle style, String string) {
   262 		print(style, string);
   263 		println();
   264 	}
   265 
   266 	public void resetAll() {
   267 		printCodes(TerminalStyle.Reset.code);
   268 	}
   269 
   270 	private void printCodes(int... codes) {
   271 		if (COLOR_ENABLED && colorful) {
   272 			print("\033[");
   273 			for (int i = 0; i < codes.length; i++) {
   274 				print(codes[i]);
   275 				if (i < codes.length - 1 && codes.length > 1) {
   276 					print(";");
   277 				}
   278 			}
   279 			print("m");
   280 		}
   281 	}
   282 
   283 	/**
   284 	 * Colors can be switched on/off during usage of this writer.
   285 	 *
   286 	 * @return whether colors are currently turned on
   287 	 * @see #isColorEnabled()
   288 	 */
   289 	public boolean isColorful() {
   290 		return colorful;
   291 	}
   292 
   293 	/**
   294 	 * Collors might be definitively disabled in constructor. If not, they can be turned on/off
   295 	 * during usage of this writer by {@linkplain #setColorful(boolean)}
   296 	 *
   297 	 * @return whether colors are allowed for this instance of this class
   298 	 * @see #isColorful()
   299 	 */
   300 	public boolean isColorEnabled() {
   301 		return COLOR_ENABLED;
   302 	}
   303 
   304 	/**
   305 	 * @see #isColorful()
   306 	 * @see #isColorEnabled()
   307 	 */
   308 	public void setColorful(boolean colorful) {
   309 		this.colorful = colorful;
   310 	}
   311 
   312 	public ColorfulPrintWriter(File file) throws FileNotFoundException {
   313 		super(file);
   314 		COLOR_ENABLED = true;
   315 	}
   316 
   317 	public ColorfulPrintWriter(OutputStream out) {
   318 		super(out);
   319 		COLOR_ENABLED = true;
   320 	}
   321 
   322 	public ColorfulPrintWriter(String fileName) throws FileNotFoundException {
   323 		super(fileName);
   324 		COLOR_ENABLED = true;
   325 	}
   326 
   327 	public ColorfulPrintWriter(Writer out) {
   328 		super(out);
   329 		COLOR_ENABLED = true;
   330 	}
   331 
   332 	public ColorfulPrintWriter(File file, String csn) throws FileNotFoundException, UnsupportedEncodingException {
   333 		super(file, csn);
   334 		COLOR_ENABLED = true;
   335 	}
   336 
   337 	/**
   338 	 * @param colorEnabled colors might be definitively disabled by this option – this might be more
   339 	 * optimalizable than dynamic turning off colors by {@linkplain #setColorful(boolean)} which is
   340 	 * not definitive (colors can be turned on during live of this instance). This might be useful
   341 	 * if you need an instance of this class but don't need colors at all.
   342 	 */
   343 	public ColorfulPrintWriter(OutputStream out, boolean autoFlush, boolean colorEnabled) {
   344 		super(out, autoFlush);
   345 		COLOR_ENABLED = colorEnabled;
   346 	}
   347 
   348 	public ColorfulPrintWriter(String fileName, String csn) throws FileNotFoundException, UnsupportedEncodingException {
   349 		super(fileName, csn);
   350 		COLOR_ENABLED = true;
   351 	}
   352 
   353 	public ColorfulPrintWriter(Writer out, boolean autoFlush) {
   354 		super(out, autoFlush);
   355 		COLOR_ENABLED = true;
   356 	}
   357 }