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