|
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 } |