2 * Jexer - Java Text User Interface
4 * The MIT License (MIT)
6 * Copyright (C) 2017 Kevin Lamonte
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24 * DEALINGS IN THE SOFTWARE.
26 * @author Kevin Lamonte [kevin.lamonte@gmail.com]
31 import java
.io
.BufferedReader
;
32 import java
.io
.FileReader
;
33 import java
.io
.FileWriter
;
34 import java
.io
.IOException
;
35 import java
.io
.Reader
;
36 import java
.util
.ArrayList
;
37 import java
.util
.List
;
39 import java
.util
.SortedMap
;
40 import java
.util
.StringTokenizer
;
41 import java
.util
.TreeMap
;
44 * ColorTheme is a collection of colors keyed by string. A default theme is
45 * also provided that matches the blue-and-white theme used by Turbo Vision.
47 public final class ColorTheme
{
49 // ------------------------------------------------------------------------
50 // Variables --------------------------------------------------------------
51 // ------------------------------------------------------------------------
54 * The current theme colors.
56 private SortedMap
<String
, CellAttributes
> colors
;
58 // ------------------------------------------------------------------------
59 // Constructors -----------------------------------------------------------
60 // ------------------------------------------------------------------------
63 * Public constructor sets the theme to the default.
66 colors
= new TreeMap
<String
, CellAttributes
>();
70 // ------------------------------------------------------------------------
71 // ColorTheme -------------------------------------------------------------
72 // ------------------------------------------------------------------------
75 * Retrieve the CellAttributes for a named theme color.
77 * @param name theme color name, e.g. "twindow.border"
78 * @return color associated with name, e.g. bold yellow on blue
80 public CellAttributes
getColor(final String name
) {
81 CellAttributes attr
= (CellAttributes
) colors
.get(name
);
86 * Retrieve all the names in the theme.
88 * @return a list of names
90 public List
<String
> getColorNames() {
91 Set
<String
> keys
= colors
.keySet();
92 List
<String
> names
= new ArrayList
<String
>(keys
.size());
98 * Set the color for a named theme color.
100 * @param name theme color name, e.g. "twindow.border"
101 * @param color the new color to associate with name, e.g. bold yellow on
104 public void setColor(final String name
, final CellAttributes color
) {
105 colors
.put(name
, color
);
109 * Save the color theme mappings to an ASCII file.
111 * @param filename file to write to
112 * @throws IOException if the I/O fails
114 public void save(final String filename
) throws IOException
{
115 FileWriter file
= new FileWriter(filename
);
116 for (String key
: colors
.keySet()) {
117 CellAttributes color
= getColor(key
);
118 file
.write(String
.format("%s = %s\n", key
, color
));
124 * Read color theme mappings from an ASCII file.
126 * @param filename file to read from
127 * @throws IOException if the I/O fails
129 public void load(final String filename
) throws IOException
{
130 load(new FileReader(filename
));
134 * Set a color based on a text string. Color text string is of the form:
135 * <code>[ bold ] [ blink ] { foreground on background }</code>
137 * @param key the color key string
138 * @param text the text string
140 public void setColorFromString(final String key
, final String text
) {
141 boolean bold
= false;
142 boolean blink
= false;
147 StringTokenizer tokenizer
= new StringTokenizer(text
);
148 token
= tokenizer
.nextToken();
149 while (token
.equals("bold") || token
.equals("blink")) {
150 if (token
.equals("bold")) {
152 token
= tokenizer
.nextToken();
154 if (token
.equals("blink")) {
156 token
= tokenizer
.nextToken();
160 // What's left is "blah on blah"
161 foreColor
= token
.toLowerCase();
163 if (!tokenizer
.nextToken().toLowerCase().equals("on")) {
167 backColor
= tokenizer
.nextToken().toLowerCase();
169 CellAttributes color
= new CellAttributes();
174 color
.setBlink(true);
176 color
.setForeColor(Color
.getColor(foreColor
));
177 color
.setBackColor(Color
.getColor(backColor
));
178 colors
.put(key
, color
);
182 * Read color theme mappings from a Reader. The reader is closed at the
185 * @param reader the reader to read from
186 * @throws IOException if the I/O fails
188 public void load(final Reader reader
) throws IOException
{
189 BufferedReader bufferedReader
= new BufferedReader(reader
);
190 String line
= bufferedReader
.readLine();
191 for (; line
!= null; line
= bufferedReader
.readLine()) {
192 // Look for lines that resemble:
193 // "key = blah on blah"
194 // "key = bold blah on blah"
195 // "key = blink bold blah on blah"
196 // "key = bold blink blah on blah"
197 // "key = blink blah on blah"
198 if (line
.indexOf('=') == -1) {
202 String key
= line
.substring(0, line
.indexOf(':')).trim();
203 String text
= line
.substring(line
.indexOf(':') + 1);
204 setColorFromString(key
, text
);
207 bufferedReader
.close();
211 * Sets to defaults that resemble the Borland IDE colors.
213 public void setDefaultTheme() {
214 CellAttributes color
;
217 color
= new CellAttributes();
218 color
.setForeColor(Color
.WHITE
);
219 color
.setBackColor(Color
.BLUE
);
221 colors
.put("twindow.border", color
);
223 // TWindow background
224 color
= new CellAttributes();
225 color
.setForeColor(Color
.YELLOW
);
226 color
.setBackColor(Color
.BLUE
);
228 colors
.put("twindow.background", color
);
230 // TWindow border - inactive
231 color
= new CellAttributes();
232 color
.setForeColor(Color
.BLACK
);
233 color
.setBackColor(Color
.BLUE
);
235 colors
.put("twindow.border.inactive", color
);
237 // TWindow background - inactive
238 color
= new CellAttributes();
239 color
.setForeColor(Color
.YELLOW
);
240 color
.setBackColor(Color
.BLUE
);
242 colors
.put("twindow.background.inactive", color
);
244 // TWindow border - modal
245 color
= new CellAttributes();
246 color
.setForeColor(Color
.WHITE
);
247 color
.setBackColor(Color
.WHITE
);
249 colors
.put("twindow.border.modal", color
);
251 // TWindow background - modal
252 color
= new CellAttributes();
253 color
.setForeColor(Color
.BLACK
);
254 color
.setBackColor(Color
.WHITE
);
255 color
.setBold(false);
256 colors
.put("twindow.background.modal", color
);
258 // TWindow border - modal + inactive
259 color
= new CellAttributes();
260 color
.setForeColor(Color
.BLACK
);
261 color
.setBackColor(Color
.WHITE
);
263 colors
.put("twindow.border.modal.inactive", color
);
265 // TWindow background - modal + inactive
266 color
= new CellAttributes();
267 color
.setForeColor(Color
.BLACK
);
268 color
.setBackColor(Color
.WHITE
);
269 color
.setBold(false);
270 colors
.put("twindow.background.modal.inactive", color
);
272 // TWindow border - during window movement - modal
273 color
= new CellAttributes();
274 color
.setForeColor(Color
.GREEN
);
275 color
.setBackColor(Color
.WHITE
);
277 colors
.put("twindow.border.modal.windowmove", color
);
279 // TWindow border - during window movement
280 color
= new CellAttributes();
281 color
.setForeColor(Color
.GREEN
);
282 color
.setBackColor(Color
.BLUE
);
284 colors
.put("twindow.border.windowmove", color
);
286 // TWindow background - during window movement
287 color
= new CellAttributes();
288 color
.setForeColor(Color
.YELLOW
);
289 color
.setBackColor(Color
.BLUE
);
290 color
.setBold(false);
291 colors
.put("twindow.background.windowmove", color
);
293 // TDesktop background
294 color
= new CellAttributes();
295 color
.setForeColor(Color
.BLUE
);
296 color
.setBackColor(Color
.WHITE
);
297 color
.setBold(false);
298 colors
.put("tdesktop.background", color
);
301 color
= new CellAttributes();
302 color
.setForeColor(Color
.BLACK
);
303 color
.setBackColor(Color
.GREEN
);
304 color
.setBold(false);
305 colors
.put("tbutton.inactive", color
);
306 color
= new CellAttributes();
307 color
.setForeColor(Color
.CYAN
);
308 color
.setBackColor(Color
.GREEN
);
310 colors
.put("tbutton.active", color
);
311 color
= new CellAttributes();
312 color
.setForeColor(Color
.BLACK
);
313 color
.setBackColor(Color
.WHITE
);
315 colors
.put("tbutton.disabled", color
);
316 color
= new CellAttributes();
317 color
.setForeColor(Color
.YELLOW
);
318 color
.setBackColor(Color
.GREEN
);
320 colors
.put("tbutton.mnemonic", color
);
321 color
= new CellAttributes();
322 color
.setForeColor(Color
.YELLOW
);
323 color
.setBackColor(Color
.GREEN
);
325 colors
.put("tbutton.mnemonic.highlighted", color
);
328 color
= new CellAttributes();
329 color
.setForeColor(Color
.WHITE
);
330 color
.setBackColor(Color
.BLUE
);
332 colors
.put("tlabel", color
);
335 color
= new CellAttributes();
336 color
.setForeColor(Color
.WHITE
);
337 color
.setBackColor(Color
.BLUE
);
338 color
.setBold(false);
339 colors
.put("ttext", color
);
342 color
= new CellAttributes();
343 color
.setForeColor(Color
.WHITE
);
344 color
.setBackColor(Color
.BLUE
);
345 color
.setBold(false);
346 colors
.put("tfield.inactive", color
);
347 color
= new CellAttributes();
348 color
.setForeColor(Color
.YELLOW
);
349 color
.setBackColor(Color
.BLACK
);
351 colors
.put("tfield.active", color
);
354 color
= new CellAttributes();
355 color
.setForeColor(Color
.WHITE
);
356 color
.setBackColor(Color
.BLUE
);
357 color
.setBold(false);
358 colors
.put("tcheckbox.inactive", color
);
359 color
= new CellAttributes();
360 color
.setForeColor(Color
.YELLOW
);
361 color
.setBackColor(Color
.BLACK
);
363 colors
.put("tcheckbox.active", color
);
366 color
= new CellAttributes();
367 color
.setForeColor(Color
.WHITE
);
368 color
.setBackColor(Color
.BLUE
);
369 color
.setBold(false);
370 colors
.put("tradiobutton.inactive", color
);
371 color
= new CellAttributes();
372 color
.setForeColor(Color
.YELLOW
);
373 color
.setBackColor(Color
.BLACK
);
375 colors
.put("tradiobutton.active", color
);
378 color
= new CellAttributes();
379 color
.setForeColor(Color
.WHITE
);
380 color
.setBackColor(Color
.BLUE
);
381 color
.setBold(false);
382 colors
.put("tradiogroup.inactive", color
);
383 color
= new CellAttributes();
384 color
.setForeColor(Color
.YELLOW
);
385 color
.setBackColor(Color
.BLUE
);
387 colors
.put("tradiogroup.active", color
);
390 color
= new CellAttributes();
391 color
.setForeColor(Color
.BLACK
);
392 color
.setBackColor(Color
.WHITE
);
393 color
.setBold(false);
394 colors
.put("tmenu", color
);
395 color
= new CellAttributes();
396 color
.setForeColor(Color
.BLACK
);
397 color
.setBackColor(Color
.GREEN
);
398 color
.setBold(false);
399 colors
.put("tmenu.highlighted", color
);
400 color
= new CellAttributes();
401 color
.setForeColor(Color
.RED
);
402 color
.setBackColor(Color
.WHITE
);
403 color
.setBold(false);
404 colors
.put("tmenu.mnemonic", color
);
405 color
= new CellAttributes();
406 color
.setForeColor(Color
.RED
);
407 color
.setBackColor(Color
.GREEN
);
408 color
.setBold(false);
409 colors
.put("tmenu.mnemonic.highlighted", color
);
410 color
= new CellAttributes();
411 color
.setForeColor(Color
.BLACK
);
412 color
.setBackColor(Color
.WHITE
);
414 colors
.put("tmenu.disabled", color
);
417 color
= new CellAttributes();
418 color
.setForeColor(Color
.BLUE
);
419 color
.setBackColor(Color
.BLUE
);
421 colors
.put("tprogressbar.complete", color
);
422 color
= new CellAttributes();
423 color
.setForeColor(Color
.WHITE
);
424 color
.setBackColor(Color
.BLUE
);
425 color
.setBold(false);
426 colors
.put("tprogressbar.incomplete", color
);
428 // THScroller / TVScroller
429 color
= new CellAttributes();
430 color
.setForeColor(Color
.CYAN
);
431 color
.setBackColor(Color
.BLUE
);
432 color
.setBold(false);
433 colors
.put("tscroller.bar", color
);
434 color
= new CellAttributes();
435 color
.setForeColor(Color
.BLUE
);
436 color
.setBackColor(Color
.CYAN
);
437 color
.setBold(false);
438 colors
.put("tscroller.arrows", color
);
441 color
= new CellAttributes();
442 color
.setForeColor(Color
.WHITE
);
443 color
.setBackColor(Color
.BLUE
);
444 color
.setBold(false);
445 colors
.put("ttreeview", color
);
446 color
= new CellAttributes();
447 color
.setForeColor(Color
.GREEN
);
448 color
.setBackColor(Color
.BLUE
);
450 colors
.put("ttreeview.expandbutton", color
);
451 color
= new CellAttributes();
452 color
.setForeColor(Color
.BLACK
);
453 color
.setBackColor(Color
.CYAN
);
454 color
.setBold(false);
455 colors
.put("ttreeview.selected", color
);
456 color
= new CellAttributes();
457 color
.setForeColor(Color
.RED
);
458 color
.setBackColor(Color
.BLUE
);
459 color
.setBold(false);
460 colors
.put("ttreeview.unreadable", color
);
461 color
= new CellAttributes();
462 // color.setForeColor(Color.BLACK);
463 // color.setBackColor(Color.BLUE);
464 // color.setBold(true);
465 color
.setForeColor(Color
.WHITE
);
466 color
.setBackColor(Color
.BLUE
);
467 color
.setBold(false);
468 colors
.put("ttreeview.inactive", color
);
469 color
= new CellAttributes();
470 color
.setForeColor(Color
.BLACK
);
471 color
.setBackColor(Color
.WHITE
);
472 color
.setBold(false);
473 colors
.put("ttreeview.selected.inactive", color
);
476 color
= new CellAttributes();
477 color
.setForeColor(Color
.WHITE
);
478 color
.setBackColor(Color
.BLUE
);
479 color
.setBold(false);
480 colors
.put("tlist", color
);
481 color
= new CellAttributes();
482 color
.setForeColor(Color
.BLACK
);
483 color
.setBackColor(Color
.CYAN
);
484 color
.setBold(false);
485 colors
.put("tlist.selected", color
);
486 color
= new CellAttributes();
487 color
.setForeColor(Color
.BLACK
);
488 color
.setBackColor(Color
.CYAN
);
489 color
.setBold(false);
490 colors
.put("tlist.unreadable", color
);
491 color
= new CellAttributes();
492 // color.setForeColor(Color.BLACK);
493 // color.setBackColor(Color.BLUE);
494 // color.setBold(true);
495 color
.setForeColor(Color
.WHITE
);
496 color
.setBackColor(Color
.BLUE
);
497 color
.setBold(false);
498 colors
.put("tlist.inactive", color
);
499 color
= new CellAttributes();
500 color
.setForeColor(Color
.BLACK
);
501 color
.setBackColor(Color
.WHITE
);
502 color
.setBold(false);
503 colors
.put("tlist.selected.inactive", color
);
506 color
= new CellAttributes();
507 color
.setForeColor(Color
.BLACK
);
508 color
.setBackColor(Color
.WHITE
);
509 color
.setBold(false);
510 colors
.put("tstatusbar.text", color
);
511 color
= new CellAttributes();
512 color
.setForeColor(Color
.RED
);
513 color
.setBackColor(Color
.WHITE
);
514 color
.setBold(false);
515 colors
.put("tstatusbar.button", color
);
516 color
= new CellAttributes();
517 color
.setForeColor(Color
.WHITE
);
518 color
.setBackColor(Color
.BLUE
);
519 color
.setBold(false);
520 colors
.put("tstatusbar.selected", color
);
523 color
= new CellAttributes();
524 color
.setForeColor(Color
.WHITE
);
525 color
.setBackColor(Color
.BLUE
);
526 color
.setBold(false);
527 colors
.put("teditor", color
);
532 * Make human-readable description of this Cell.
534 * @return displayable String
537 public String
toString() {
538 return colors
.toString();