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
{
50 * The current theme colors.
52 private SortedMap
<String
, CellAttributes
> colors
;
55 * Public constructor sets the theme to the default.
58 colors
= new TreeMap
<String
, CellAttributes
>();
63 * Retrieve the CellAttributes for a named theme color.
65 * @param name theme color name, e.g. "twindow.border"
66 * @return color associated with name, e.g. bold yellow on blue
68 public CellAttributes
getColor(final String name
) {
69 CellAttributes attr
= (CellAttributes
) colors
.get(name
);
74 * Retrieve all the names in the theme.
76 * @return a list of names
78 public List
<String
> getColorNames() {
79 Set
<String
> keys
= colors
.keySet();
80 List
<String
> names
= new ArrayList
<String
>(keys
.size());
86 * Set the color for a named theme color.
88 * @param name theme color name, e.g. "twindow.border"
89 * @param color the new color to associate with name, e.g. bold yellow on
92 public void setColor(final String name
, final CellAttributes color
) {
93 colors
.put(name
, color
);
97 * Save the color theme mappings to an ASCII file.
99 * @param filename file to write to
100 * @throws IOException if the I/O fails
102 public void save(final String filename
) throws IOException
{
103 FileWriter file
= new FileWriter(filename
);
104 for (String key
: colors
.keySet()) {
105 CellAttributes color
= getColor(key
);
106 file
.write(String
.format("%s = %s\n", key
, color
));
112 * Read color theme mappings from an ASCII file.
114 * @param filename file to read from
115 * @throws IOException if the I/O fails
117 public void load(final String filename
) throws IOException
{
118 load(new FileReader(filename
));
122 * Read color theme mappings from a Reader. The reader is closed at the
125 * @param reader the reader to read from
126 * @throws IOException if the I/O fails
128 public void load(final Reader reader
) throws IOException
{
129 BufferedReader bufferedReader
= new BufferedReader(reader
);
130 String line
= bufferedReader
.readLine();
131 for (; line
!= null; line
= bufferedReader
.readLine()) {
133 boolean bold
= false;
134 boolean blink
= false;
139 // Look for lines that resemble:
140 // "key = blah on blah"
141 // "key = bold blah on blah"
142 // "key = blink bold blah on blah"
143 // "key = bold blink blah on blah"
144 // "key = blink blah on blah"
145 StringTokenizer tokenizer
= new StringTokenizer(line
);
146 key
= tokenizer
.nextToken();
147 if (!tokenizer
.nextToken().equals("=")) {
151 token
= tokenizer
.nextToken();
152 while (token
.equals("bold") || token
.equals("blink")) {
153 if (token
.equals("bold")) {
155 token
= tokenizer
.nextToken();
157 if (token
.equals("blink")) {
159 token
= tokenizer
.nextToken();
163 // What's left is "blah on blah" or "blah"
164 foreColor
= token
.toLowerCase();
166 if (!tokenizer
.nextToken().toLowerCase().equals("on")) {
170 backColor
= tokenizer
.nextToken().toLowerCase();
172 CellAttributes color
= new CellAttributes();
177 color
.setBlink(true);
179 color
.setForeColor(Color
.getColor(foreColor
));
180 color
.setBackColor(Color
.getColor(backColor
));
181 colors
.put(key
, color
);
184 bufferedReader
.close();
188 * Sets to defaults that resemble the Borland IDE colors.
190 public void setDefaultTheme() {
191 CellAttributes color
;
194 color
= new CellAttributes();
195 color
.setForeColor(Color
.WHITE
);
196 color
.setBackColor(Color
.BLUE
);
198 colors
.put("twindow.border", color
);
200 // TWindow background
201 color
= new CellAttributes();
202 color
.setForeColor(Color
.YELLOW
);
203 color
.setBackColor(Color
.BLUE
);
205 colors
.put("twindow.background", color
);
207 // TWindow border - inactive
208 color
= new CellAttributes();
209 color
.setForeColor(Color
.BLACK
);
210 color
.setBackColor(Color
.BLUE
);
212 colors
.put("twindow.border.inactive", color
);
214 // TWindow background - inactive
215 color
= new CellAttributes();
216 color
.setForeColor(Color
.YELLOW
);
217 color
.setBackColor(Color
.BLUE
);
219 colors
.put("twindow.background.inactive", color
);
221 // TWindow border - modal
222 color
= new CellAttributes();
223 color
.setForeColor(Color
.WHITE
);
224 color
.setBackColor(Color
.WHITE
);
226 colors
.put("twindow.border.modal", color
);
228 // TWindow background - modal
229 color
= new CellAttributes();
230 color
.setForeColor(Color
.BLACK
);
231 color
.setBackColor(Color
.WHITE
);
232 color
.setBold(false);
233 colors
.put("twindow.background.modal", color
);
235 // TWindow border - modal + inactive
236 color
= new CellAttributes();
237 color
.setForeColor(Color
.BLACK
);
238 color
.setBackColor(Color
.WHITE
);
240 colors
.put("twindow.border.modal.inactive", color
);
242 // TWindow background - modal + inactive
243 color
= new CellAttributes();
244 color
.setForeColor(Color
.BLACK
);
245 color
.setBackColor(Color
.WHITE
);
246 color
.setBold(false);
247 colors
.put("twindow.background.modal.inactive", color
);
249 // TWindow border - during window movement - modal
250 color
= new CellAttributes();
251 color
.setForeColor(Color
.GREEN
);
252 color
.setBackColor(Color
.WHITE
);
254 colors
.put("twindow.border.modal.windowmove", color
);
256 // TWindow border - during window movement
257 color
= new CellAttributes();
258 color
.setForeColor(Color
.GREEN
);
259 color
.setBackColor(Color
.BLUE
);
261 colors
.put("twindow.border.windowmove", color
);
263 // TWindow background - during window movement
264 color
= new CellAttributes();
265 color
.setForeColor(Color
.YELLOW
);
266 color
.setBackColor(Color
.BLUE
);
267 color
.setBold(false);
268 colors
.put("twindow.background.windowmove", color
);
270 // TDesktop background
271 color
= new CellAttributes();
272 color
.setForeColor(Color
.BLUE
);
273 color
.setBackColor(Color
.WHITE
);
274 color
.setBold(false);
275 colors
.put("tdesktop.background", color
);
278 color
= new CellAttributes();
279 color
.setForeColor(Color
.BLACK
);
280 color
.setBackColor(Color
.GREEN
);
281 color
.setBold(false);
282 colors
.put("tbutton.inactive", color
);
283 color
= new CellAttributes();
284 color
.setForeColor(Color
.CYAN
);
285 color
.setBackColor(Color
.GREEN
);
287 colors
.put("tbutton.active", color
);
288 color
= new CellAttributes();
289 color
.setForeColor(Color
.BLACK
);
290 color
.setBackColor(Color
.WHITE
);
292 colors
.put("tbutton.disabled", color
);
293 color
= new CellAttributes();
294 color
.setForeColor(Color
.YELLOW
);
295 color
.setBackColor(Color
.GREEN
);
297 colors
.put("tbutton.mnemonic", color
);
298 color
= new CellAttributes();
299 color
.setForeColor(Color
.YELLOW
);
300 color
.setBackColor(Color
.GREEN
);
302 colors
.put("tbutton.mnemonic.highlighted", color
);
305 color
= new CellAttributes();
306 color
.setForeColor(Color
.WHITE
);
307 color
.setBackColor(Color
.BLUE
);
309 colors
.put("tlabel", color
);
312 color
= new CellAttributes();
313 color
.setForeColor(Color
.WHITE
);
314 color
.setBackColor(Color
.BLUE
);
315 color
.setBold(false);
316 colors
.put("ttext", color
);
319 color
= new CellAttributes();
320 color
.setForeColor(Color
.WHITE
);
321 color
.setBackColor(Color
.BLUE
);
322 color
.setBold(false);
323 colors
.put("tfield.inactive", color
);
324 color
= new CellAttributes();
325 color
.setForeColor(Color
.YELLOW
);
326 color
.setBackColor(Color
.BLACK
);
328 colors
.put("tfield.active", color
);
331 color
= new CellAttributes();
332 color
.setForeColor(Color
.WHITE
);
333 color
.setBackColor(Color
.BLUE
);
334 color
.setBold(false);
335 colors
.put("tcheckbox.inactive", color
);
336 color
= new CellAttributes();
337 color
.setForeColor(Color
.YELLOW
);
338 color
.setBackColor(Color
.BLACK
);
340 colors
.put("tcheckbox.active", color
);
343 color
= new CellAttributes();
344 color
.setForeColor(Color
.WHITE
);
345 color
.setBackColor(Color
.BLUE
);
346 color
.setBold(false);
347 colors
.put("tradiobutton.inactive", color
);
348 color
= new CellAttributes();
349 color
.setForeColor(Color
.YELLOW
);
350 color
.setBackColor(Color
.BLACK
);
352 colors
.put("tradiobutton.active", color
);
355 color
= new CellAttributes();
356 color
.setForeColor(Color
.WHITE
);
357 color
.setBackColor(Color
.BLUE
);
358 color
.setBold(false);
359 colors
.put("tradiogroup.inactive", color
);
360 color
= new CellAttributes();
361 color
.setForeColor(Color
.YELLOW
);
362 color
.setBackColor(Color
.BLUE
);
364 colors
.put("tradiogroup.active", color
);
367 color
= new CellAttributes();
368 color
.setForeColor(Color
.BLACK
);
369 color
.setBackColor(Color
.WHITE
);
370 color
.setBold(false);
371 colors
.put("tmenu", color
);
372 color
= new CellAttributes();
373 color
.setForeColor(Color
.BLACK
);
374 color
.setBackColor(Color
.GREEN
);
375 color
.setBold(false);
376 colors
.put("tmenu.highlighted", color
);
377 color
= new CellAttributes();
378 color
.setForeColor(Color
.RED
);
379 color
.setBackColor(Color
.WHITE
);
380 color
.setBold(false);
381 colors
.put("tmenu.mnemonic", color
);
382 color
= new CellAttributes();
383 color
.setForeColor(Color
.RED
);
384 color
.setBackColor(Color
.GREEN
);
385 color
.setBold(false);
386 colors
.put("tmenu.mnemonic.highlighted", color
);
387 color
= new CellAttributes();
388 color
.setForeColor(Color
.BLACK
);
389 color
.setBackColor(Color
.WHITE
);
391 colors
.put("tmenu.disabled", color
);
394 color
= new CellAttributes();
395 color
.setForeColor(Color
.BLUE
);
396 color
.setBackColor(Color
.BLUE
);
398 colors
.put("tprogressbar.complete", color
);
399 color
= new CellAttributes();
400 color
.setForeColor(Color
.WHITE
);
401 color
.setBackColor(Color
.BLUE
);
402 color
.setBold(false);
403 colors
.put("tprogressbar.incomplete", color
);
405 // THScroller / TVScroller
406 color
= new CellAttributes();
407 color
.setForeColor(Color
.CYAN
);
408 color
.setBackColor(Color
.BLUE
);
409 color
.setBold(false);
410 colors
.put("tscroller.bar", color
);
411 color
= new CellAttributes();
412 color
.setForeColor(Color
.BLUE
);
413 color
.setBackColor(Color
.CYAN
);
414 color
.setBold(false);
415 colors
.put("tscroller.arrows", color
);
418 color
= new CellAttributes();
419 color
.setForeColor(Color
.WHITE
);
420 color
.setBackColor(Color
.BLUE
);
421 color
.setBold(false);
422 colors
.put("ttreeview", color
);
423 color
= new CellAttributes();
424 color
.setForeColor(Color
.GREEN
);
425 color
.setBackColor(Color
.BLUE
);
427 colors
.put("ttreeview.expandbutton", color
);
428 color
= new CellAttributes();
429 color
.setForeColor(Color
.BLACK
);
430 color
.setBackColor(Color
.CYAN
);
431 color
.setBold(false);
432 colors
.put("ttreeview.selected", color
);
433 color
= new CellAttributes();
434 color
.setForeColor(Color
.RED
);
435 color
.setBackColor(Color
.BLUE
);
436 color
.setBold(false);
437 colors
.put("ttreeview.unreadable", color
);
438 color
= new CellAttributes();
439 // color.setForeColor(Color.BLACK);
440 // color.setBackColor(Color.BLUE);
441 // color.setBold(true);
442 color
.setForeColor(Color
.WHITE
);
443 color
.setBackColor(Color
.BLUE
);
444 color
.setBold(false);
445 colors
.put("ttreeview.inactive", color
);
448 color
= new CellAttributes();
449 color
.setForeColor(Color
.WHITE
);
450 color
.setBackColor(Color
.BLUE
);
451 color
.setBold(false);
452 colors
.put("tlist", color
);
453 color
= new CellAttributes();
454 color
.setForeColor(Color
.BLACK
);
455 color
.setBackColor(Color
.CYAN
);
456 color
.setBold(false);
457 colors
.put("tlist.selected", color
);
458 color
= new CellAttributes();
459 color
.setForeColor(Color
.BLACK
);
460 color
.setBackColor(Color
.CYAN
);
461 color
.setBold(false);
462 colors
.put("tlist.unreadable", color
);
463 color
= new CellAttributes();
464 // color.setForeColor(Color.BLACK);
465 // color.setBackColor(Color.BLUE);
466 // color.setBold(true);
467 color
.setForeColor(Color
.WHITE
);
468 color
.setBackColor(Color
.BLUE
);
469 color
.setBold(false);
470 colors
.put("tlist.inactive", color
);
473 color
= new CellAttributes();
474 color
.setForeColor(Color
.BLACK
);
475 color
.setBackColor(Color
.WHITE
);
476 color
.setBold(false);
477 colors
.put("tstatusbar.text", color
);
478 color
= new CellAttributes();
479 color
.setForeColor(Color
.RED
);
480 color
.setBackColor(Color
.WHITE
);
481 color
.setBold(false);
482 colors
.put("tstatusbar.button", color
);
483 color
= new CellAttributes();
484 color
.setForeColor(Color
.WHITE
);
485 color
.setBackColor(Color
.BLUE
);
486 color
.setBold(false);
487 colors
.put("tstatusbar.selected", color
);
490 color
= new CellAttributes();
491 color
.setForeColor(Color
.WHITE
);
492 color
.setBackColor(Color
.BLUE
);
493 color
.setBold(false);
494 colors
.put("teditor", color
);