1 /*
   2  * Copyright (c) 1996, 2018, 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  */
  25 package java.awt;
  26 
  27 import sun.awt.AWTAccessor;
  28 
  29 import java.io.ObjectStreamException;
  30 
  31 import 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  */
  54 public 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 }