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()) {
137 // Look for lines that resemble:
138 // "key = blah on blah"
139 // "key = bold blah on blah"
140 StringTokenizer tokenizer
= new StringTokenizer(line
);
141 key
= tokenizer
.nextToken();
142 if (!tokenizer
.nextToken().equals("=")) {
146 bold
= tokenizer
.nextToken();
147 if (!bold
.toLowerCase().equals("bold")) {
148 // "key = blah on blah"
151 // "key = bold blah on blah"
152 foreColor
= tokenizer
.nextToken().toLowerCase();
154 if (!tokenizer
.nextToken().toLowerCase().equals("on")) {
158 backColor
= tokenizer
.nextToken().toLowerCase();
160 CellAttributes color
= new CellAttributes();
161 if (bold
.equals("bold")) {
164 color
.setForeColor(Color
.getColor(foreColor
));
165 color
.setBackColor(Color
.getColor(backColor
));
166 colors
.put(key
, color
);
169 bufferedReader
.close();
173 * Sets to defaults that resemble the Borland IDE colors.
175 public void setDefaultTheme() {
176 CellAttributes color
;
179 color
= new CellAttributes();
180 color
.setForeColor(Color
.WHITE
);
181 color
.setBackColor(Color
.BLUE
);
183 colors
.put("twindow.border", color
);
185 // TWindow background
186 color
= new CellAttributes();
187 color
.setForeColor(Color
.YELLOW
);
188 color
.setBackColor(Color
.BLUE
);
190 colors
.put("twindow.background", color
);
192 // TWindow border - inactive
193 color
= new CellAttributes();
194 color
.setForeColor(Color
.BLACK
);
195 color
.setBackColor(Color
.BLUE
);
197 colors
.put("twindow.border.inactive", color
);
199 // TWindow background - inactive
200 color
= new CellAttributes();
201 color
.setForeColor(Color
.YELLOW
);
202 color
.setBackColor(Color
.BLUE
);
204 colors
.put("twindow.background.inactive", color
);
206 // TWindow border - modal
207 color
= new CellAttributes();
208 color
.setForeColor(Color
.WHITE
);
209 color
.setBackColor(Color
.WHITE
);
211 colors
.put("twindow.border.modal", color
);
213 // TWindow background - modal
214 color
= new CellAttributes();
215 color
.setForeColor(Color
.BLACK
);
216 color
.setBackColor(Color
.WHITE
);
217 color
.setBold(false);
218 colors
.put("twindow.background.modal", color
);
220 // TWindow border - modal + inactive
221 color
= new CellAttributes();
222 color
.setForeColor(Color
.BLACK
);
223 color
.setBackColor(Color
.WHITE
);
225 colors
.put("twindow.border.modal.inactive", color
);
227 // TWindow background - modal + inactive
228 color
= new CellAttributes();
229 color
.setForeColor(Color
.BLACK
);
230 color
.setBackColor(Color
.WHITE
);
231 color
.setBold(false);
232 colors
.put("twindow.background.modal.inactive", color
);
234 // TWindow border - during window movement - modal
235 color
= new CellAttributes();
236 color
.setForeColor(Color
.GREEN
);
237 color
.setBackColor(Color
.WHITE
);
239 colors
.put("twindow.border.modal.windowmove", color
);
241 // TWindow border - during window movement
242 color
= new CellAttributes();
243 color
.setForeColor(Color
.GREEN
);
244 color
.setBackColor(Color
.BLUE
);
246 colors
.put("twindow.border.windowmove", color
);
248 // TWindow background - during window movement
249 color
= new CellAttributes();
250 color
.setForeColor(Color
.YELLOW
);
251 color
.setBackColor(Color
.BLUE
);
252 color
.setBold(false);
253 colors
.put("twindow.background.windowmove", color
);
255 // TDesktop background
256 color
= new CellAttributes();
257 color
.setForeColor(Color
.BLUE
);
258 color
.setBackColor(Color
.WHITE
);
259 color
.setBold(false);
260 colors
.put("tdesktop.background", color
);
263 color
= new CellAttributes();
264 color
.setForeColor(Color
.BLACK
);
265 color
.setBackColor(Color
.GREEN
);
266 color
.setBold(false);
267 colors
.put("tbutton.inactive", color
);
268 color
= new CellAttributes();
269 color
.setForeColor(Color
.CYAN
);
270 color
.setBackColor(Color
.GREEN
);
272 colors
.put("tbutton.active", color
);
273 color
= new CellAttributes();
274 color
.setForeColor(Color
.BLACK
);
275 color
.setBackColor(Color
.WHITE
);
277 colors
.put("tbutton.disabled", color
);
278 color
= new CellAttributes();
279 color
.setForeColor(Color
.YELLOW
);
280 color
.setBackColor(Color
.GREEN
);
282 colors
.put("tbutton.mnemonic", color
);
283 color
= new CellAttributes();
284 color
.setForeColor(Color
.YELLOW
);
285 color
.setBackColor(Color
.GREEN
);
287 colors
.put("tbutton.mnemonic.highlighted", color
);
290 color
= new CellAttributes();
291 color
.setForeColor(Color
.WHITE
);
292 color
.setBackColor(Color
.BLUE
);
294 colors
.put("tlabel", color
);
297 color
= new CellAttributes();
298 color
.setForeColor(Color
.WHITE
);
299 color
.setBackColor(Color
.BLUE
);
300 color
.setBold(false);
301 colors
.put("ttext", color
);
304 color
= new CellAttributes();
305 color
.setForeColor(Color
.WHITE
);
306 color
.setBackColor(Color
.BLUE
);
307 color
.setBold(false);
308 colors
.put("tfield.inactive", color
);
309 color
= new CellAttributes();
310 color
.setForeColor(Color
.YELLOW
);
311 color
.setBackColor(Color
.BLACK
);
313 colors
.put("tfield.active", color
);
316 color
= new CellAttributes();
317 color
.setForeColor(Color
.WHITE
);
318 color
.setBackColor(Color
.BLUE
);
319 color
.setBold(false);
320 colors
.put("tcheckbox.inactive", color
);
321 color
= new CellAttributes();
322 color
.setForeColor(Color
.YELLOW
);
323 color
.setBackColor(Color
.BLACK
);
325 colors
.put("tcheckbox.active", color
);
329 color
= new CellAttributes();
330 color
.setForeColor(Color
.WHITE
);
331 color
.setBackColor(Color
.BLUE
);
332 color
.setBold(false);
333 colors
.put("tradiobutton.inactive", color
);
334 color
= new CellAttributes();
335 color
.setForeColor(Color
.YELLOW
);
336 color
.setBackColor(Color
.BLACK
);
338 colors
.put("tradiobutton.active", color
);
341 color
= new CellAttributes();
342 color
.setForeColor(Color
.WHITE
);
343 color
.setBackColor(Color
.BLUE
);
344 color
.setBold(false);
345 colors
.put("tradiogroup.inactive", color
);
346 color
= new CellAttributes();
347 color
.setForeColor(Color
.YELLOW
);
348 color
.setBackColor(Color
.BLUE
);
350 colors
.put("tradiogroup.active", color
);
353 color
= new CellAttributes();
354 color
.setForeColor(Color
.BLACK
);
355 color
.setBackColor(Color
.WHITE
);
356 color
.setBold(false);
357 colors
.put("tmenu", color
);
358 color
= new CellAttributes();
359 color
.setForeColor(Color
.BLACK
);
360 color
.setBackColor(Color
.GREEN
);
361 color
.setBold(false);
362 colors
.put("tmenu.highlighted", color
);
363 color
= new CellAttributes();
364 color
.setForeColor(Color
.RED
);
365 color
.setBackColor(Color
.WHITE
);
366 color
.setBold(false);
367 colors
.put("tmenu.mnemonic", color
);
368 color
= new CellAttributes();
369 color
.setForeColor(Color
.RED
);
370 color
.setBackColor(Color
.GREEN
);
371 color
.setBold(false);
372 colors
.put("tmenu.mnemonic.highlighted", color
);
373 color
= new CellAttributes();
374 color
.setForeColor(Color
.BLACK
);
375 color
.setBackColor(Color
.WHITE
);
377 colors
.put("tmenu.disabled", color
);
380 color
= new CellAttributes();
381 color
.setForeColor(Color
.BLUE
);
382 color
.setBackColor(Color
.BLUE
);
384 colors
.put("tprogressbar.complete", color
);
385 color
= new CellAttributes();
386 color
.setForeColor(Color
.WHITE
);
387 color
.setBackColor(Color
.BLUE
);
388 color
.setBold(false);
389 colors
.put("tprogressbar.incomplete", color
);
391 // THScroller / TVScroller
392 color
= new CellAttributes();
393 color
.setForeColor(Color
.CYAN
);
394 color
.setBackColor(Color
.BLUE
);
395 color
.setBold(false);
396 colors
.put("tscroller.bar", color
);
397 color
= new CellAttributes();
398 color
.setForeColor(Color
.BLUE
);
399 color
.setBackColor(Color
.CYAN
);
400 color
.setBold(false);
401 colors
.put("tscroller.arrows", color
);
404 color
= new CellAttributes();
405 color
.setForeColor(Color
.WHITE
);
406 color
.setBackColor(Color
.BLUE
);
407 color
.setBold(false);
408 colors
.put("ttreeview", color
);
409 color
= new CellAttributes();
410 color
.setForeColor(Color
.GREEN
);
411 color
.setBackColor(Color
.BLUE
);
413 colors
.put("ttreeview.expandbutton", color
);
414 color
= new CellAttributes();
415 color
.setForeColor(Color
.BLACK
);
416 color
.setBackColor(Color
.CYAN
);
417 color
.setBold(false);
418 colors
.put("ttreeview.selected", color
);
419 color
= new CellAttributes();
420 color
.setForeColor(Color
.RED
);
421 color
.setBackColor(Color
.BLUE
);
422 color
.setBold(false);
423 colors
.put("ttreeview.unreadable", color
);
424 color
= new CellAttributes();
425 color
.setForeColor(Color
.BLACK
);
426 color
.setBackColor(Color
.BLUE
);
428 colors
.put("ttreeview.inactive", color
);
431 color
= new CellAttributes();
432 color
.setForeColor(Color
.WHITE
);
433 color
.setBackColor(Color
.BLUE
);
434 color
.setBold(false);
435 colors
.put("tlist", color
);
436 color
= new CellAttributes();
437 color
.setForeColor(Color
.BLACK
);
438 color
.setBackColor(Color
.CYAN
);
439 color
.setBold(false);
440 colors
.put("tlist.selected", color
);
441 color
= new CellAttributes();
442 color
.setForeColor(Color
.BLACK
);
443 color
.setBackColor(Color
.CYAN
);
444 color
.setBold(false);
445 colors
.put("tlist.unreadable", color
);
446 color
= new CellAttributes();
447 color
.setForeColor(Color
.BLACK
);
448 color
.setBackColor(Color
.BLUE
);
450 colors
.put("tlist.inactive", color
);
453 color
= new CellAttributes();
454 color
.setForeColor(Color
.BLACK
);
455 color
.setBackColor(Color
.WHITE
);
456 color
.setBold(false);
457 colors
.put("tstatusbar.text", color
);
458 color
= new CellAttributes();
459 color
.setForeColor(Color
.RED
);
460 color
.setBackColor(Color
.WHITE
);
461 color
.setBold(false);
462 colors
.put("tstatusbar.button", color
);
463 color
= new CellAttributes();
464 color
.setForeColor(Color
.WHITE
);
465 color
.setBackColor(Color
.BLUE
);
466 color
.setBold(false);
467 colors
.put("tstatusbar.selected", color
);
470 color
= new CellAttributes();
471 color
.setForeColor(Color
.WHITE
);
472 color
.setBackColor(Color
.BLUE
);
473 color
.setBold(false);
474 colors
.put("teditor", color
);