franta-hg@31: /** franta-hg@31: * SQL-DK franta-hg@31: * Copyright © 2013 František Kučera (frantovo.cz) franta-hg@31: * franta-hg@31: * This program is free software: you can redistribute it and/or modify franta-hg@31: * it under the terms of the GNU General Public License as published by franta-hg@31: * the Free Software Foundation, either version 3 of the License, or franta-hg@31: * (at your option) any later version. franta-hg@31: * franta-hg@31: * This program is distributed in the hope that it will be useful, franta-hg@31: * but WITHOUT ANY WARRANTY; without even the implied warranty of franta-hg@31: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the franta-hg@31: * GNU General Public License for more details. franta-hg@31: * franta-hg@31: * You should have received a copy of the GNU General Public License franta-hg@31: * along with this program. If not, see . franta-hg@31: */ franta-hg@31: package info.globalcode.sql.dk; franta-hg@31: franta-hg@31: import java.io.File; franta-hg@31: import java.io.FileNotFoundException; franta-hg@31: import java.io.OutputStream; franta-hg@31: import java.io.PrintWriter; franta-hg@31: import java.io.UnsupportedEncodingException; franta-hg@31: import java.io.Writer; franta-hg@31: import java.util.EnumSet; franta-hg@31: franta-hg@31: /** franta-hg@155: * PrintWriter with convenience methods for printing color and formatted text. franta-hg@155: * franta-hg@155: * Uses ANSI Escape Sequences. franta-hg@155: * See: http://www.tldp.org/HOWTO/Bash-Prompt-HOWTO/x329.html franta-hg@31: * franta-hg@31: * @author Ing. František Kučera (frantovo.cz) franta-hg@31: */ franta-hg@31: public class ColorfulPrintWriter extends PrintWriter { franta-hg@31: franta-hg@31: public enum TerminalColor { franta-hg@31: franta-hg@31: Black(30, 40), franta-hg@31: Red(31, 41), franta-hg@31: Green(32, 42), franta-hg@31: Yellow(33, 43), franta-hg@31: Blue(34, 44), franta-hg@31: Magenta(35, 45), franta-hg@31: Cyan(36, 46), franta-hg@31: White(37, 47); franta-hg@31: private final int foregroundCode; franta-hg@31: private final int backgroundCode; franta-hg@31: franta-hg@31: private TerminalColor(int foregroundCode, int backgroundCode) { franta-hg@31: this.foregroundCode = foregroundCode; franta-hg@31: this.backgroundCode = backgroundCode; franta-hg@31: } franta-hg@31: franta-hg@31: public int getForegroundCode() { franta-hg@31: return foregroundCode; franta-hg@31: } franta-hg@31: franta-hg@31: public int getBackgroundCode() { franta-hg@31: return backgroundCode; franta-hg@31: } franta-hg@31: } franta-hg@31: franta-hg@31: public enum TerminalStyle { franta-hg@31: franta-hg@31: Reset(0), franta-hg@31: Bright(1), franta-hg@31: Dim(2), franta-hg@31: Underscore(4), franta-hg@31: Blink(5), franta-hg@31: Reverse(7), franta-hg@31: Hidden(8); franta-hg@31: private int code; franta-hg@31: franta-hg@31: private TerminalStyle(int code) { franta-hg@31: this.code = code; franta-hg@31: } franta-hg@31: franta-hg@31: public int getCode() { franta-hg@31: return code; franta-hg@31: } franta-hg@31: } franta-hg@126: private final boolean COLOR_ENABLED; franta-hg@31: private boolean colorful = true; franta-hg@31: franta-hg@59: public void setStyle(TerminalStyle style) { franta-hg@59: setStyle(EnumSet.of(style)); franta-hg@59: } franta-hg@59: franta-hg@31: public void setStyle(EnumSet styles) { franta-hg@31: printCodes(getStyleCodes(styles)); franta-hg@31: } franta-hg@31: franta-hg@31: private static int[] getStyleCodes(EnumSet styles) { franta-hg@31: int[] array = new int[styles.size()]; franta-hg@31: int i = 0; franta-hg@31: for (TerminalStyle s : styles) { franta-hg@31: array[i++] = s.getCode(); franta-hg@31: } franta-hg@31: return array; franta-hg@31: } franta-hg@31: franta-hg@40: /** franta-hg@40: * Print (usually audible) bell code (\007, \a, ^G) franta-hg@40: */ franta-hg@40: public void bell() { franta-hg@40: print("\007"); franta-hg@40: } franta-hg@40: franta-hg@40: /** franta-hg@40: * Eat the last character franta-hg@40: */ franta-hg@40: public void backspace() { franta-hg@40: print("\b"); franta-hg@40: } franta-hg@40: franta-hg@40: /** franta-hg@40: * Eat n last characters franta-hg@40: * franta-hg@40: * @param count n franta-hg@40: */ franta-hg@40: public void backspace(int count) { franta-hg@40: for (int i = 0; i < count; i++) { franta-hg@40: backspace(); franta-hg@40: } franta-hg@40: } franta-hg@40: franta-hg@40: /** franta-hg@40: * With 100 ms delay and all colors. franta-hg@40: * franta-hg@40: * @see #printRainbow(java.lang.String, int, franta-hg@40: * info.globalcode.sql.dk.ColorfulPrintWriter.TerminalColor[]) franta-hg@40: */ franta-hg@40: public void printRainbow(String string) { franta-hg@40: printRainbow(string, 100); franta-hg@40: } franta-hg@40: franta-hg@40: /** franta-hg@40: * With all colors. franta-hg@40: * franta-hg@40: * @see #printRainbow(java.lang.String, int, franta-hg@40: * info.globalcode.sql.dk.ColorfulPrintWriter.TerminalColor[]) franta-hg@40: */ franta-hg@40: public void printRainbow(String string, int delay) { franta-hg@40: printRainbow(string, delay, TerminalColor.values()); franta-hg@40: } franta-hg@40: franta-hg@40: /** franta-hg@40: * Prints rainbow text – (re)writes same text subsequently in given colors and then in default franta-hg@40: * color. franta-hg@40: * franta-hg@40: * @param string text to be printed, should not contain \n new line (then rainbow does not work franta-hg@40: * – use println() after printRainbow() instead) franta-hg@40: * @param delay delay between rewrites franta-hg@40: * @param colors list of colors to be used franta-hg@40: */ franta-hg@40: public void printRainbow(String string, int delay, TerminalColor... colors) { franta-hg@40: for (TerminalColor c : colors) { franta-hg@40: print(c, string); franta-hg@40: try { franta-hg@40: Thread.sleep(delay); franta-hg@40: } catch (InterruptedException e) { franta-hg@40: // no time to sleep franta-hg@40: break; franta-hg@40: } franta-hg@40: backspace(string.length()); franta-hg@40: flush(); franta-hg@40: } franta-hg@40: print(string); franta-hg@40: } franta-hg@40: franta-hg@31: public void setForegroundColor(TerminalColor color) { franta-hg@31: printCodes(color.getForegroundCode()); franta-hg@31: } franta-hg@31: franta-hg@31: public void setBackgroundColor(TerminalColor color) { franta-hg@31: printCodes(color.getBackgroundCode()); franta-hg@31: } franta-hg@31: franta-hg@31: public void print(TerminalColor foregroundColor, String string) { franta-hg@31: setForegroundColor(foregroundColor); franta-hg@31: print(string); franta-hg@31: resetAll(); franta-hg@31: } franta-hg@31: franta-hg@31: public void println(TerminalColor foregroundColor, String string) { franta-hg@31: print(foregroundColor, string); franta-hg@31: println(); franta-hg@31: } franta-hg@31: franta-hg@31: public void print(TerminalColor foregroundColor, TerminalColor backgroundColor, String string) { franta-hg@31: setForegroundColor(foregroundColor); franta-hg@31: setBackgroundColor(backgroundColor); franta-hg@31: print(string); franta-hg@31: resetAll(); franta-hg@31: } franta-hg@31: franta-hg@31: public void println(TerminalColor foregroundColor, TerminalColor backgroundColor, String string) { franta-hg@31: print(foregroundColor, backgroundColor, string); franta-hg@31: println(); franta-hg@31: } franta-hg@31: franta-hg@31: public void print(TerminalColor foregroundColor, TerminalColor backgroundColor, EnumSet styles, String string) { franta-hg@31: setForegroundColor(foregroundColor); franta-hg@31: setBackgroundColor(backgroundColor); franta-hg@31: setStyle(styles); franta-hg@31: print(string); franta-hg@31: resetAll(); franta-hg@31: } franta-hg@31: franta-hg@31: public void println(TerminalColor foregroundColor, TerminalColor backgroundColor, EnumSet styles, String string) { franta-hg@31: print(foregroundColor, backgroundColor, styles, string); franta-hg@31: println(); franta-hg@31: } franta-hg@31: franta-hg@31: public void print(TerminalColor foregroundColor, TerminalColor backgroundColor, TerminalStyle style, String string) { franta-hg@31: print(foregroundColor, backgroundColor, EnumSet.of(style), string); franta-hg@31: } franta-hg@31: franta-hg@31: public void println(TerminalColor foregroundColor, TerminalColor backgroundColor, TerminalStyle style, String string) { franta-hg@31: print(foregroundColor, backgroundColor, style, string); franta-hg@31: println(); franta-hg@31: } franta-hg@31: franta-hg@31: public void print(TerminalColor foregroundColor, EnumSet styles, String string) { franta-hg@31: setForegroundColor(foregroundColor); franta-hg@31: setStyle(styles); franta-hg@31: print(string); franta-hg@31: resetAll(); franta-hg@31: } franta-hg@31: franta-hg@31: public void println(TerminalColor foregroundColor, EnumSet styles, String string) { franta-hg@31: print(foregroundColor, styles, string); franta-hg@31: println(); franta-hg@31: } franta-hg@31: franta-hg@31: public void print(TerminalColor foregroundColor, TerminalStyle style, String string) { franta-hg@31: print(foregroundColor, EnumSet.of(style), string); franta-hg@31: } franta-hg@31: franta-hg@31: public void println(TerminalColor foregroundColor, TerminalStyle style, String string) { franta-hg@31: print(foregroundColor, style, string); franta-hg@31: println(); franta-hg@31: } franta-hg@31: franta-hg@37: public void print(EnumSet styles, String string) { franta-hg@37: setStyle(styles); franta-hg@37: print(string); franta-hg@37: resetAll(); franta-hg@37: } franta-hg@37: franta-hg@37: public void println(EnumSet styles, String string) { franta-hg@37: print(styles, string); franta-hg@37: println(); franta-hg@37: } franta-hg@37: franta-hg@37: public void print(TerminalStyle style, String string) { franta-hg@37: print(EnumSet.of(style), string); franta-hg@37: } franta-hg@37: franta-hg@37: public void println(TerminalStyle style, String string) { franta-hg@37: print(style, string); franta-hg@37: println(); franta-hg@37: } franta-hg@37: franta-hg@31: public void resetAll() { franta-hg@55: printCodes(TerminalStyle.Reset.code); franta-hg@31: } franta-hg@31: franta-hg@31: private void printCodes(int... codes) { franta-hg@126: if (COLOR_ENABLED && colorful) { franta-hg@31: print("\033["); franta-hg@31: for (int i = 0; i < codes.length; i++) { franta-hg@31: print(codes[i]); franta-hg@31: if (i < codes.length - 1 && codes.length > 1) { franta-hg@31: print(";"); franta-hg@31: } franta-hg@31: } franta-hg@31: print("m"); franta-hg@31: } franta-hg@31: } franta-hg@31: franta-hg@126: /** franta-hg@126: * Colors can be switched on/off during usage of this writer. franta-hg@126: * franta-hg@126: * @return whether colors are currently turned on franta-hg@126: * @see #isColorEnabled() franta-hg@126: */ franta-hg@31: public boolean isColorful() { franta-hg@31: return colorful; franta-hg@31: } franta-hg@31: franta-hg@126: /** franta-hg@126: * Collors might be definitively disabled in constructor. If not, they can be turned on/off franta-hg@126: * during usage of this writer by {@linkplain #setColorful(boolean)} franta-hg@126: * franta-hg@126: * @return whether colors are allowed for this instance of this class franta-hg@126: * @see #isColorful() franta-hg@126: */ franta-hg@126: public boolean isColorEnabled() { franta-hg@126: return COLOR_ENABLED; franta-hg@126: } franta-hg@126: franta-hg@126: /** franta-hg@126: * @see #isColorful() franta-hg@126: * @see #isColorEnabled() franta-hg@126: */ franta-hg@31: public void setColorful(boolean colorful) { franta-hg@31: this.colorful = colorful; franta-hg@31: } franta-hg@31: franta-hg@31: public ColorfulPrintWriter(File file) throws FileNotFoundException { franta-hg@31: super(file); franta-hg@126: COLOR_ENABLED = true; franta-hg@31: } franta-hg@31: franta-hg@31: public ColorfulPrintWriter(OutputStream out) { franta-hg@31: super(out); franta-hg@126: COLOR_ENABLED = true; franta-hg@31: } franta-hg@31: franta-hg@31: public ColorfulPrintWriter(String fileName) throws FileNotFoundException { franta-hg@31: super(fileName); franta-hg@126: COLOR_ENABLED = true; franta-hg@31: } franta-hg@31: franta-hg@31: public ColorfulPrintWriter(Writer out) { franta-hg@31: super(out); franta-hg@126: COLOR_ENABLED = true; franta-hg@31: } franta-hg@31: franta-hg@31: public ColorfulPrintWriter(File file, String csn) throws FileNotFoundException, UnsupportedEncodingException { franta-hg@31: super(file, csn); franta-hg@126: COLOR_ENABLED = true; franta-hg@31: } franta-hg@31: franta-hg@126: /** franta-hg@126: * @param colorEnabled colors might be definitively disabled by this option – this might be more franta-hg@126: * optimalizable than dynamic turning off colors by {@linkplain #setColorful(boolean)} which is franta-hg@126: * not definitive (colors can be turned on during live of this instance). This might be useful franta-hg@126: * if you need an instance of this class but don't need colors at all. franta-hg@126: */ franta-hg@126: public ColorfulPrintWriter(OutputStream out, boolean autoFlush, boolean colorEnabled) { franta-hg@31: super(out, autoFlush); franta-hg@126: COLOR_ENABLED = colorEnabled; franta-hg@31: } franta-hg@31: franta-hg@31: public ColorfulPrintWriter(String fileName, String csn) throws FileNotFoundException, UnsupportedEncodingException { franta-hg@31: super(fileName, csn); franta-hg@126: COLOR_ENABLED = true; franta-hg@31: } franta-hg@31: franta-hg@31: public ColorfulPrintWriter(Writer out, boolean autoFlush) { franta-hg@31: super(out, autoFlush); franta-hg@126: COLOR_ENABLED = true; franta-hg@31: } franta-hg@31: }