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