1/*
2 * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.  Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25package java.awt;
26
27import sun.awt.AWTAccessor;
28
29import java.io.ObjectStreamException;
30
31import java.lang.annotation.Native;
32
33/**
34 * A class to encapsulate symbolic colors representing the color of
35 * native GUI objects on a system.  For systems which support the dynamic
36 * update of the system colors (when the user changes the colors)
37 * the actual RGB values of these symbolic colors will also change
38 * dynamically.  In order to compare the "current" RGB value of a
39 * {@code SystemColor} object with a non-symbolic Color object,
40 * {@code getRGB} should be used rather than {@code equals}.
41 * <p>
42 * Note that the way in which these system colors are applied to GUI objects
43 * may vary slightly from platform to platform since GUI objects may be
44 * rendered differently on each platform.
45 * <p>
46 * System color values may also be available through the {@code getDesktopProperty}
47 * method on {@code java.awt.Toolkit}.
48 *
49 * @see Toolkit#getDesktopProperty
50 *
51 * @author      Carl Quinn
52 * @author      Amy Fowler
53 */
54public final class SystemColor extends Color implements java.io.Serializable {
55
56   /**
57     * The array index for the
58     * {@link #desktop} system color.
59     * @see SystemColor#desktop
60     */
61    @Native public static final int DESKTOP = 0;
62
63    /**
64     * The array index for the
65     * {@link #activeCaption} system color.
66     * @see SystemColor#activeCaption
67     */
68    @Native public static final int ACTIVE_CAPTION = 1;
69
70    /**
71     * The array index for the
72     * {@link #activeCaptionText} system color.
73     * @see SystemColor#activeCaptionText
74     */
75    @Native public static final int ACTIVE_CAPTION_TEXT = 2;
76
77    /**
78     * The array index for the
79     * {@link #activeCaptionBorder} system color.
80     * @see SystemColor#activeCaptionBorder
81     */
82    @Native public static final int ACTIVE_CAPTION_BORDER = 3;
83
84    /**
85     * The array index for the
86     * {@link #inactiveCaption} system color.
87     * @see SystemColor#inactiveCaption
88     */
89    @Native public static final int INACTIVE_CAPTION = 4;
90
91    /**
92     * The array index for the
93     * {@link #inactiveCaptionText} system color.
94     * @see SystemColor#inactiveCaptionText
95     */
96    @Native public static final int INACTIVE_CAPTION_TEXT = 5;
97
98    /**
99     * The array index for the
100     * {@link #inactiveCaptionBorder} system color.
101     * @see SystemColor#inactiveCaptionBorder
102     */
103    @Native public static final int INACTIVE_CAPTION_BORDER = 6;
104
105    /**
106     * The array index for the
107     * {@link #window} system color.
108     * @see SystemColor#window
109     */
110    @Native public static final int WINDOW = 7;
111
112    /**
113     * The array index for the
114     * {@link #windowBorder} system color.
115     * @see SystemColor#windowBorder
116     */
117    @Native public static final int WINDOW_BORDER = 8;
118
119    /**
120     * The array index for the
121     * {@link #windowText} system color.
122     * @see SystemColor#windowText
123     */
124    @Native public static final int WINDOW_TEXT = 9;
125
126    /**
127     * The array index for the
128     * {@link #menu} system color.
129     * @see SystemColor#menu
130     */
131    @Native public static final int MENU = 10;
132
133    /**
134     * The array index for the
135     * {@link #menuText} system color.
136     * @see SystemColor#menuText
137     */
138    @Native public static final int MENU_TEXT = 11;
139
140    /**
141     * The array index for the
142     * {@link #text} system color.
143     * @see SystemColor#text
144     */
145    @Native public static final int TEXT = 12;
146
147    /**
148     * The array index for the
149     * {@link #textText} system color.
150     * @see SystemColor#textText
151     */
152    @Native public static final int TEXT_TEXT = 13;
153
154    /**
155     * The array index for the
156     * {@link #textHighlight} system color.
157     * @see SystemColor#textHighlight
158     */
159    @Native public static final int TEXT_HIGHLIGHT = 14;
160
161    /**
162     * The array index for the
163     * {@link #textHighlightText} system color.
164     * @see SystemColor#textHighlightText
165     */
166    @Native public static final int TEXT_HIGHLIGHT_TEXT = 15;
167
168    /**
169     * The array index for the
170     * {@link #textInactiveText} system color.
171     * @see SystemColor#textInactiveText
172     */
173    @Native public static final int TEXT_INACTIVE_TEXT = 16;
174
175    /**
176     * The array index for the
177     * {@link #control} system color.
178     * @see SystemColor#control
179     */
180    @Native public static final int CONTROL = 17;
181
182    /**
183     * The array index for the
184     * {@link #controlText} system color.
185     * @see SystemColor#controlText
186     */
187    @Native public static final int CONTROL_TEXT = 18;
188
189    /**
190     * The array index for the
191     * {@link #controlHighlight} system color.
192     * @see SystemColor#controlHighlight
193     */
194    @Native public static final int CONTROL_HIGHLIGHT = 19;
195
196    /**
197     * The array index for the
198     * {@link #controlLtHighlight} system color.
199     * @see SystemColor#controlLtHighlight
200     */
201    @Native public static final int CONTROL_LT_HIGHLIGHT = 20;
202
203    /**
204     * The array index for the
205     * {@link #controlShadow} system color.
206     * @see SystemColor#controlShadow
207     */
208    @Native public static final int CONTROL_SHADOW = 21;
209
210    /**
211     * The array index for the
212     * {@link #controlDkShadow} system color.
213     * @see SystemColor#controlDkShadow
214     */
215    @Native public static final int CONTROL_DK_SHADOW = 22;
216
217    /**
218     * The array index for the
219     * {@link #scrollbar} system color.
220     * @see SystemColor#scrollbar
221     */
222    @Native public static final int SCROLLBAR = 23;
223
224    /**
225     * The array index for the
226     * {@link #info} system color.
227     * @see SystemColor#info
228     */
229    @Native public static final int INFO = 24;
230
231    /**
232     * The array index for the
233     * {@link #infoText} system color.
234     * @see SystemColor#infoText
235     */
236    @Native public static final int INFO_TEXT = 25;
237
238    /**
239     * The number of system colors in the array.
240     */
241    @Native public static final int NUM_COLORS = 26;
242
243    /******************************************************************************************/
244
245    /*
246     * System colors with default initial values, overwritten by toolkit if
247     * system values differ and are available.
248     * Should put array initialization above first field that is using
249     * SystemColor constructor to initialize.
250     */
251    private static int[] systemColors = {
252        0xFF005C5C,  // desktop = new Color(0,92,92);
253        0xFF000080,  // activeCaption = new Color(0,0,128);
254        0xFFFFFFFF,  // activeCaptionText = Color.white;
255        0xFFC0C0C0,  // activeCaptionBorder = Color.lightGray;
256        0xFF808080,  // inactiveCaption = Color.gray;
257        0xFFC0C0C0,  // inactiveCaptionText = Color.lightGray;
258        0xFFC0C0C0,  // inactiveCaptionBorder = Color.lightGray;
259        0xFFFFFFFF,  // window = Color.white;
260        0xFF000000,  // windowBorder = Color.black;
261        0xFF000000,  // windowText = Color.black;
262        0xFFC0C0C0,  // menu = Color.lightGray;
263        0xFF000000,  // menuText = Color.black;
264        0xFFC0C0C0,  // text = Color.lightGray;
265        0xFF000000,  // textText = Color.black;
266        0xFF000080,  // textHighlight = new Color(0,0,128);
267        0xFFFFFFFF,  // textHighlightText = Color.white;
268        0xFF808080,  // textInactiveText = Color.gray;
269        0xFFC0C0C0,  // control = Color.lightGray;
270        0xFF000000,  // controlText = Color.black;
271        0xFFFFFFFF,  // controlHighlight = Color.white;
272        0xFFE0E0E0,  // controlLtHighlight = new Color(224,224,224);
273        0xFF808080,  // controlShadow = Color.gray;
274        0xFF000000,  // controlDkShadow = Color.black;
275        0xFFE0E0E0,  // scrollbar = new Color(224,224,224);
276        0xFFE0E000,  // info = new Color(224,224,0);
277        0xFF000000,  // infoText = Color.black;
278    };
279
280   /**
281     * The color rendered for the background of the desktop.
282     */
283    public static final SystemColor desktop = new SystemColor((byte)DESKTOP);
284
285    /**
286     * The color rendered for the window-title background of the currently active window.
287     */
288    public static final SystemColor activeCaption = new SystemColor((byte)ACTIVE_CAPTION);
289
290    /**
291     * The color rendered for the window-title text of the currently active window.
292     */
293    public static final SystemColor activeCaptionText = new SystemColor((byte)ACTIVE_CAPTION_TEXT);
294
295    /**
296     * The color rendered for the border around the currently active window.
297     */
298    public static final SystemColor activeCaptionBorder = new SystemColor((byte)ACTIVE_CAPTION_BORDER);
299
300    /**
301     * The color rendered for the window-title background of inactive windows.
302     */
303    public static final SystemColor inactiveCaption = new SystemColor((byte)INACTIVE_CAPTION);
304
305    /**
306     * The color rendered for the window-title text of inactive windows.
307     */
308    public static final SystemColor inactiveCaptionText = new SystemColor((byte)INACTIVE_CAPTION_TEXT);
309
310    /**
311     * The color rendered for the border around inactive windows.
312     */
313    public static final SystemColor inactiveCaptionBorder = new SystemColor((byte)INACTIVE_CAPTION_BORDER);
314
315    /**
316     * The color rendered for the background of interior regions inside windows.
317     */
318    public static final SystemColor window = new SystemColor((byte)WINDOW);
319
320    /**
321     * The color rendered for the border around interior regions inside windows.
322     */
323    public static final SystemColor windowBorder = new SystemColor((byte)WINDOW_BORDER);
324
325    /**
326     * The color rendered for text of interior regions inside windows.
327     */
328    public static final SystemColor windowText = new SystemColor((byte)WINDOW_TEXT);
329
330    /**
331     * The color rendered for the background of menus.
332     */
333    public static final SystemColor menu = new SystemColor((byte)MENU);
334
335    /**
336     * The color rendered for the text of menus.
337     */
338    public static final SystemColor menuText = new SystemColor((byte)MENU_TEXT);
339
340    /**
341     * The color rendered for the background of text control objects, such as
342     * textfields and comboboxes.
343     */
344    public static final SystemColor text = new SystemColor((byte)TEXT);
345
346    /**
347     * The color rendered for the text of text control objects, such as textfields
348     * and comboboxes.
349     */
350    public static final SystemColor textText = new SystemColor((byte)TEXT_TEXT);
351
352    /**
353     * The color rendered for the background of selected items, such as in menus,
354     * comboboxes, and text.
355     */
356    public static final SystemColor textHighlight = new SystemColor((byte)TEXT_HIGHLIGHT);
357
358    /**
359     * The color rendered for the text of selected items, such as in menus, comboboxes,
360     * and text.
361     */
362    public static final SystemColor textHighlightText = new SystemColor((byte)TEXT_HIGHLIGHT_TEXT);
363
364    /**
365     * The color rendered for the text of inactive items, such as in menus.
366     */
367    public static final SystemColor textInactiveText = new SystemColor((byte)TEXT_INACTIVE_TEXT);
368
369    /**
370     * The color rendered for the background of control panels and control objects,
371     * such as pushbuttons.
372     */
373    public static final SystemColor control = new SystemColor((byte)CONTROL);
374
375    /**
376     * The color rendered for the text of control panels and control objects,
377     * such as pushbuttons.
378     */
379    public static final SystemColor controlText = new SystemColor((byte)CONTROL_TEXT);
380
381    /**
382     * The color rendered for light areas of 3D control objects, such as pushbuttons.
383     * This color is typically derived from the {@code control} background color
384     * to provide a 3D effect.
385     */
386    public static final SystemColor controlHighlight = new SystemColor((byte)CONTROL_HIGHLIGHT);
387
388    /**
389     * The color rendered for highlight areas of 3D control objects, such as pushbuttons.
390     * This color is typically derived from the {@code control} background color
391     * to provide a 3D effect.
392     */
393    public static final SystemColor controlLtHighlight = new SystemColor((byte)CONTROL_LT_HIGHLIGHT);
394
395    /**
396     * The color rendered for shadow areas of 3D control objects, such as pushbuttons.
397     * This color is typically derived from the {@code control} background color
398     * to provide a 3D effect.
399     */
400    public static final SystemColor controlShadow = new SystemColor((byte)CONTROL_SHADOW);
401
402    /**
403     * The color rendered for dark shadow areas on 3D control objects, such as pushbuttons.
404     * This color is typically derived from the {@code control} background color
405     * to provide a 3D effect.
406     */
407    public static final SystemColor controlDkShadow = new SystemColor((byte)CONTROL_DK_SHADOW);
408
409    /**
410     * The color rendered for the background of scrollbars.
411     */
412    public static final SystemColor scrollbar = new SystemColor((byte)SCROLLBAR);
413
414    /**
415     * The color rendered for the background of tooltips or spot help.
416     */
417    public static final SystemColor info = new SystemColor((byte)INFO);
418
419    /**
420     * The color rendered for the text of tooltips or spot help.
421     */
422    public static final SystemColor infoText = new SystemColor((byte)INFO_TEXT);
423
424    /*
425     * JDK 1.1 serialVersionUID.
426     */
427    private static final long serialVersionUID = 4503142729533789064L;
428
429    /*
430     * An index into either array of SystemColor objects or values.
431     */
432    private transient int index;
433
434    private static SystemColor systemColorObjects [] = {
435        SystemColor.desktop,
436        SystemColor.activeCaption,
437        SystemColor.activeCaptionText,
438        SystemColor.activeCaptionBorder,
439        SystemColor.inactiveCaption,
440        SystemColor.inactiveCaptionText,
441        SystemColor.inactiveCaptionBorder,
442        SystemColor.window,
443        SystemColor.windowBorder,
444        SystemColor.windowText,
445        SystemColor.menu,
446        SystemColor.menuText,
447        SystemColor.text,
448        SystemColor.textText,
449        SystemColor.textHighlight,
450        SystemColor.textHighlightText,
451        SystemColor.textInactiveText,
452        SystemColor.control,
453        SystemColor.controlText,
454        SystemColor.controlHighlight,
455        SystemColor.controlLtHighlight,
456        SystemColor.controlShadow,
457        SystemColor.controlDkShadow,
458        SystemColor.scrollbar,
459        SystemColor.info,
460        SystemColor.infoText
461    };
462
463    static {
464        AWTAccessor.setSystemColorAccessor(SystemColor::updateSystemColors);
465        updateSystemColors();
466    }
467
468    /**
469     * Called from {@code <init>} and toolkit to update the above systemColors cache.
470     */
471    private static void updateSystemColors() {
472        if (!GraphicsEnvironment.isHeadless()) {
473            Toolkit.getDefaultToolkit().loadSystemColors(systemColors);
474        }
475        for (int i = 0; i < systemColors.length; i++) {
476            systemColorObjects[i].value = systemColors[i];
477        }
478    }
479
480    /**
481     * Creates a symbolic color that represents an indexed entry into system
482     * color cache. Used by above static system colors.
483     */
484    private SystemColor(byte index) {
485        super(systemColors[index]);
486        this.index = index;
487    }
488
489    /**
490     * Returns a string representation of this {@code Color}'s values.
491     * This method is intended to be used only for debugging purposes,
492     * and the content and format of the returned string may vary between
493     * implementations.
494     * The returned string may be empty but may not be {@code null}.
495     *
496     * @return  a string representation of this {@code Color}
497     */
498    public String toString() {
499        return getClass().getName() + "[i=" + (index) + "]";
500    }
501
502    /**
503     * The design of the {@code SystemColor} class assumes that
504     * the {@code SystemColor} object instances stored in the
505     * static final fields above are the only instances that can
506     * be used by developers.
507     * This method helps maintain those limits on instantiation
508     * by using the index stored in the value field of the
509     * serialized form of the object to replace the serialized
510     * object with the equivalent static object constant field
511     * of {@code SystemColor}.
512     * See the {@link #writeReplace} method for more information
513     * on the serialized form of these objects.
514     * @return one of the {@code SystemColor} static object
515     *         fields that refers to the same system color.
516     */
517    private Object readResolve() {
518        // The instances of SystemColor are tightly controlled and
519        // only the canonical instances appearing above as static
520        // constants are allowed.  The serial form of SystemColor
521        // objects stores the color index as the value.  Here we
522        // map that index back into the canonical instance.
523        return systemColorObjects[value];
524    }
525
526    /**
527     * Returns a specialized version of the {@code SystemColor}
528     * object for writing to the serialized stream.
529     * @serialData
530     * The value field of a serialized {@code SystemColor} object
531     * contains the array index of the system color instead of the
532     * rgb data for the system color.
533     * This index is used by the {@link #readResolve} method to
534     * resolve the deserialized objects back to the original
535     * static constant versions to ensure unique instances of
536     * each {@code SystemColor} object.
537     * @return a proxy {@code SystemColor} object with its value
538     *         replaced by the corresponding system color index.
539     */
540    private Object writeReplace() throws ObjectStreamException
541    {
542        // we put an array index in the SystemColor.value while serialize
543        // to keep compatibility.
544        SystemColor color = new SystemColor((byte)index);
545        color.value = index;
546        return color;
547    }
548}
549