1 /*
   2  * Copyright (c) 1998, 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  */
  25 
  26 package javax.swing.plaf.metal;
  27 
  28 import java.awt.*;
  29 import java.beans.PropertyChangeEvent;
  30 import java.beans.PropertyChangeListener;
  31 import javax.swing.plaf.*;
  32 import javax.swing.*;
  33 import javax.swing.plaf.basic.*;
  34 import javax.swing.text.DefaultEditorKit;
  35 
  36 import java.awt.Color;
  37 import java.awt.event.KeyEvent;
  38 import java.lang.reflect.*;
  39 import java.lang.ref.ReferenceQueue;
  40 import java.lang.ref.WeakReference;
  41 
  42 import java.security.AccessController;
  43 import java.security.PrivilegedAction;
  44 
  45 import sun.awt.*;
  46 import sun.security.action.GetPropertyAction;
  47 import sun.swing.DefaultLayoutStyle;
  48 import static javax.swing.UIDefaults.LazyValue;
  49 import sun.swing.SwingUtilities2;
  50 
  51 /**
  52  * The Java Look and Feel, otherwise known as Metal.
  53  * <p>
  54  * Each of the {@code ComponentUI}s provided by {@code
  55  * MetalLookAndFeel} derives its behavior from the defaults
  56  * table. Unless otherwise noted each of the {@code ComponentUI}
  57  * implementations in this package document the set of defaults they
  58  * use. Unless otherwise noted the defaults are installed at the time
  59  * {@code installUI} is invoked, and follow the recommendations
  60  * outlined in {@code LookAndFeel} for installing defaults.
  61  * <p>
  62  * {@code MetalLookAndFeel} derives it's color palette and fonts from
  63  * {@code MetalTheme}. The default theme is {@code OceanTheme}. The theme
  64  * can be changed using the {@code setCurrentTheme} method, refer to it
  65  * for details on changing the theme. Prior to 1.5 the default
  66  * theme was {@code DefaultMetalTheme}. The system property
  67  * {@code "swing.metalTheme"} can be set to {@code "steel"} to indicate
  68  * the default should be {@code DefaultMetalTheme}.
  69  * <p>
  70  * <strong>Warning:</strong>
  71  * Serialized objects of this class will not be compatible with
  72  * future Swing releases. The current serialization support is
  73  * appropriate for short term storage or RMI between applications running
  74  * the same version of Swing.  As of 1.4, support for long term storage
  75  * of all JavaBeans&trade;
  76  * has been added to the <code>java.beans</code> package.
  77  * Please see {@link java.beans.XMLEncoder}.
  78  *
  79  * @see MetalTheme
  80  * @see DefaultMetalTheme
  81  * @see OceanTheme
  82  *
  83  * @author Steve Wilson
  84  */
  85 @SuppressWarnings("serial") // Same-version serialization only
  86 public class MetalLookAndFeel extends BasicLookAndFeel
  87 {
  88 
  89     private static boolean METAL_LOOK_AND_FEEL_INITED = false;
  90 
  91 
  92     /**
  93      * True if checked for windows yet.
  94      */
  95     private static boolean checkedWindows;
  96     /**
  97      * True if running on Windows.
  98      */
  99     private static boolean isWindows;
 100 
 101     /**
 102      * Set to true first time we've checked swing.useSystemFontSettings.
 103      */
 104     private static boolean checkedSystemFontSettings;
 105 
 106     /**
 107      * True indicates we should use system fonts, unless the developer has
 108      * specified otherwise with Application.useSystemFontSettings.
 109      */
 110     private static boolean useSystemFonts;
 111 
 112 
 113     /**
 114      * Returns true if running on Windows.
 115      */
 116     static boolean isWindows() {
 117         if (!checkedWindows) {
 118             OSInfo.OSType osType = AccessController.doPrivileged(OSInfo.getOSTypeAction());
 119             if (osType == OSInfo.OSType.WINDOWS) {
 120                 isWindows = true;
 121                 String systemFonts = AccessController.doPrivileged(
 122                     new GetPropertyAction("swing.useSystemFontSettings"));
 123                 useSystemFonts = (systemFonts != null &&
 124                                (Boolean.valueOf(systemFonts).booleanValue()));
 125             }
 126             checkedWindows = true;
 127         }
 128         return isWindows;
 129     }
 130 
 131     /**
 132      * Returns true if system fonts should be used, this is only useful
 133      * for windows.
 134      */
 135     static boolean useSystemFonts() {
 136         if (isWindows() && useSystemFonts) {
 137             if (METAL_LOOK_AND_FEEL_INITED) {
 138                 Object value = UIManager.get(
 139                                  "Application.useSystemFontSettings");
 140 
 141                 return (value == null || Boolean.TRUE.equals(value));
 142             }
 143             // If an instanceof MetalLookAndFeel hasn't been inited yet, we
 144             // don't want to trigger loading of a UI by asking the UIManager
 145             // for a property, assume the user wants system fonts. This will
 146             // be properly adjusted when install is invoked on the
 147             // MetalTheme
 148             return true;
 149         }
 150         return false;
 151     }
 152 
 153     /**
 154      * Returns true if the high contrast theme should be used as the default
 155      * theme.
 156      */
 157     private static boolean useHighContrastTheme() {
 158         if (isWindows() && useSystemFonts()) {
 159             Boolean highContrast = (Boolean)Toolkit.getDefaultToolkit().
 160                                   getDesktopProperty("win.highContrast.on");
 161 
 162             return (highContrast == null) ? false : highContrast.
 163                                             booleanValue();
 164         }
 165         return false;
 166     }
 167 
 168     /**
 169      * Returns true if we're using the Ocean Theme.
 170      */
 171     static boolean usingOcean() {
 172         return (getCurrentTheme() instanceof OceanTheme);
 173     }
 174 
 175     /**
 176      * Returns the name of this look and feel. This returns
 177      * {@code "Metal"}.
 178      *
 179      * @return the name of this look and feel
 180      */
 181     public String getName() {
 182         return "Metal";
 183     }
 184 
 185     /**
 186      * Returns an identifier for this look and feel. This returns
 187      * {@code "Metal"}.
 188      *
 189      * @return the identifier of this look and feel
 190      */
 191     public String getID() {
 192         return "Metal";
 193     }
 194 
 195     /**
 196      * Returns a short description of this look and feel. This returns
 197      * {@code "The Java(tm) Look and Feel"}.
 198 
 199      * @return a short description for the look and feel
 200      */
 201     public String getDescription() {
 202         return "The Java(tm) Look and Feel";
 203     }
 204 
 205     /**
 206      * Returns {@code false}; {@code MetalLookAndFeel} is not a native
 207      * look and feel.
 208      *
 209      * @return {@code false}
 210      */
 211     public boolean isNativeLookAndFeel() {
 212         return false;
 213     }
 214 
 215     /**
 216      * Returns {@code true}; {@code MetalLookAndFeel} can be run on
 217      * any platform.
 218      *
 219      * @return {@code true}
 220      */
 221     public boolean isSupportedLookAndFeel() {
 222         return true;
 223     }
 224 
 225     /**
 226      * Returns {@code true}; metal can provide {@code Window}
 227      * decorations.
 228      *
 229      * @return {@code true}
 230      *
 231      * @see JDialog#setDefaultLookAndFeelDecorated
 232      * @see JFrame#setDefaultLookAndFeelDecorated
 233      * @see JRootPane#setWindowDecorationStyle
 234      * @since 1.4
 235      */
 236     public boolean getSupportsWindowDecorations() {
 237         return true;
 238     }
 239 
 240     /**
 241      * Populates {@code table} with mappings from {@code uiClassID} to
 242      * the fully qualified name of the ui class. {@code
 243      * MetalLookAndFeel} registers an entry for each of the classes in
 244      * the package {@code javax.swing.plaf.metal} that are named
 245      * MetalXXXUI. The string {@code XXX} is one of Swing's uiClassIDs. For
 246      * the {@code uiClassIDs} that do not have a class in metal, the
 247      * corresponding class in {@code javax.swing.plaf.basic} is
 248      * used. For example, metal does not have a class named {@code
 249      * "MetalColorChooserUI"}, as such, {@code
 250      * javax.swing.plaf.basic.BasicColorChooserUI} is used.
 251      *
 252      * @param table the {@code UIDefaults} instance the entries are
 253      *        added to
 254      * @throws NullPointerException if {@code table} is {@code null}
 255      *
 256      * @see javax.swing.plaf.basic.BasicLookAndFeel#initClassDefaults
 257      */
 258     protected void initClassDefaults(UIDefaults table)
 259     {
 260         super.initClassDefaults(table);
 261         final String metalPackageName = "javax.swing.plaf.metal.";
 262 
 263         Object[] uiDefaults = {
 264                    "ButtonUI", metalPackageName + "MetalButtonUI",
 265                  "CheckBoxUI", metalPackageName + "MetalCheckBoxUI",
 266                  "ComboBoxUI", metalPackageName + "MetalComboBoxUI",
 267               "DesktopIconUI", metalPackageName + "MetalDesktopIconUI",
 268               "FileChooserUI", metalPackageName + "MetalFileChooserUI",
 269             "InternalFrameUI", metalPackageName + "MetalInternalFrameUI",
 270                     "LabelUI", metalPackageName + "MetalLabelUI",
 271        "PopupMenuSeparatorUI", metalPackageName + "MetalPopupMenuSeparatorUI",
 272               "ProgressBarUI", metalPackageName + "MetalProgressBarUI",
 273               "RadioButtonUI", metalPackageName + "MetalRadioButtonUI",
 274                 "ScrollBarUI", metalPackageName + "MetalScrollBarUI",
 275                "ScrollPaneUI", metalPackageName + "MetalScrollPaneUI",
 276                 "SeparatorUI", metalPackageName + "MetalSeparatorUI",
 277                    "SliderUI", metalPackageName + "MetalSliderUI",
 278                 "SplitPaneUI", metalPackageName + "MetalSplitPaneUI",
 279                "TabbedPaneUI", metalPackageName + "MetalTabbedPaneUI",
 280                 "TextFieldUI", metalPackageName + "MetalTextFieldUI",
 281              "ToggleButtonUI", metalPackageName + "MetalToggleButtonUI",
 282                   "ToolBarUI", metalPackageName + "MetalToolBarUI",
 283                   "ToolTipUI", metalPackageName + "MetalToolTipUI",
 284                      "TreeUI", metalPackageName + "MetalTreeUI",
 285                  "RootPaneUI", metalPackageName + "MetalRootPaneUI",
 286         };
 287 
 288         table.putDefaults(uiDefaults);
 289     }
 290 
 291     /**
 292      * Populates {@code table} with system colors. The following values are
 293      * added to {@code table}:
 294      * <table border="1" cellpadding="1" cellspacing="0"
 295      *         summary="Metal's system color mapping">
 296      *  <tr valign="top"  align="left">
 297      *    <th style="background-color:#CCCCFF" align="left">Key
 298      *    <th style="background-color:#CCCCFF" align="left">Value
 299      *  <tr valign="top"  align="left">
 300      *    <td>"desktop"
 301      *    <td>{@code theme.getDesktopColor()}
 302      *  <tr valign="top"  align="left">
 303      *    <td>"activeCaption"
 304      *    <td>{@code theme.getWindowTitleBackground()}
 305      *  <tr valign="top"  align="left">
 306      *    <td>"activeCaptionText"
 307      *    <td>{@code theme.getWindowTitleForeground()}
 308      *  <tr valign="top"  align="left">
 309      *    <td>"activeCaptionBorder"
 310      *    <td>{@code theme.getPrimaryControlShadow()}
 311      *  <tr valign="top"  align="left">
 312      *    <td>"inactiveCaption"
 313      *    <td>{@code theme.getWindowTitleInactiveBackground()}
 314      *  <tr valign="top"  align="left">
 315      *    <td>"inactiveCaptionText"
 316      *    <td>{@code theme.getWindowTitleInactiveForeground()}
 317      *  <tr valign="top"  align="left">
 318      *    <td>"inactiveCaptionBorder"
 319      *    <td>{@code theme.getControlShadow()}
 320      *  <tr valign="top"  align="left">
 321      *    <td>"window"
 322      *    <td>{@code theme.getWindowBackground()}
 323      *  <tr valign="top"  align="left">
 324      *    <td>"windowBorder"
 325      *    <td>{@code theme.getControl()}
 326      *  <tr valign="top"  align="left">
 327      *    <td>"windowText"
 328      *    <td>{@code theme.getUserTextColor()}
 329      *  <tr valign="top"  align="left">
 330      *    <td>"menu"
 331      *    <td>{@code theme.getMenuBackground()}
 332      *  <tr valign="top"  align="left">
 333      *    <td>"menuText"
 334      *    <td>{@code theme.getMenuForeground()}
 335      *  <tr valign="top"  align="left">
 336      *    <td>"text"
 337      *    <td>{@code theme.getWindowBackground()}
 338      *  <tr valign="top"  align="left">
 339      *    <td>"textText"
 340      *    <td>{@code theme.getUserTextColor()}
 341      *  <tr valign="top"  align="left">
 342      *    <td>"textHighlight"
 343      *    <td>{@code theme.getTextHighlightColor()}
 344      *  <tr valign="top"  align="left">
 345      *    <td>"textHighlightText"
 346      *    <td>{@code theme.getHighlightedTextColor()}
 347      *  <tr valign="top"  align="left">
 348      *    <td>"textInactiveText"
 349      *    <td>{@code theme.getInactiveSystemTextColor()}
 350      *  <tr valign="top"  align="left">
 351      *    <td>"control"
 352      *    <td>{@code theme.getControl()}
 353      *  <tr valign="top"  align="left">
 354      *    <td>"controlText"
 355      *    <td>{@code theme.getControlTextColor()}
 356      *  <tr valign="top"  align="left">
 357      *    <td>"controlHighlight"
 358      *    <td>{@code theme.getControlHighlight()}
 359      *  <tr valign="top"  align="left">
 360      *    <td>"controlLtHighlight"
 361      *    <td>{@code theme.getControlHighlight()}
 362      *  <tr valign="top"  align="left">
 363      *    <td>"controlShadow"
 364      *    <td>{@code theme.getControlShadow()}
 365      *  <tr valign="top"  align="left">
 366      *    <td>"controlDkShadow"
 367      *    <td>{@code theme.getControlDarkShadow()}
 368      *  <tr valign="top"  align="left">
 369      *    <td>"scrollbar"
 370      *    <td>{@code theme.getControl()}
 371      *  <tr valign="top"  align="left">
 372      *    <td>"info"
 373      *    <td>{@code theme.getPrimaryControl()}
 374      *  <tr valign="top"  align="left">
 375      *    <td>"infoText"
 376      *    <td>{@code theme.getPrimaryControlInfo()}
 377      * </table>
 378      * The value {@code theme} corresponds to the current {@code MetalTheme}.
 379      *
 380      * @param table the {@code UIDefaults} object the values are added to
 381      * @throws NullPointerException if {@code table} is {@code null}
 382      */
 383     protected void initSystemColorDefaults(UIDefaults table)
 384     {
 385         MetalTheme theme = getCurrentTheme();
 386         Color control = theme.getControl();
 387         Object[] systemColors = {
 388                 "desktop", theme.getDesktopColor(), /* Color of the desktop background */
 389           "activeCaption", theme.getWindowTitleBackground(), /* Color for captions (title bars) when they are active. */
 390       "activeCaptionText", theme.getWindowTitleForeground(), /* Text color for text in captions (title bars). */
 391     "activeCaptionBorder", theme.getPrimaryControlShadow(), /* Border color for caption (title bar) window borders. */
 392         "inactiveCaption", theme.getWindowTitleInactiveBackground(), /* Color for captions (title bars) when not active. */
 393     "inactiveCaptionText", theme.getWindowTitleInactiveForeground(), /* Text color for text in inactive captions (title bars). */
 394   "inactiveCaptionBorder", theme.getControlShadow(), /* Border color for inactive caption (title bar) window borders. */
 395                  "window", theme.getWindowBackground(), /* Default color for the interior of windows */
 396            "windowBorder", control, /* ??? */
 397              "windowText", theme.getUserTextColor(), /* ??? */
 398                    "menu", theme.getMenuBackground(), /* Background color for menus */
 399                "menuText", theme.getMenuForeground(), /* Text color for menus  */
 400                    "text", theme.getWindowBackground(), /* Text background color */
 401                "textText", theme.getUserTextColor(), /* Text foreground color */
 402           "textHighlight", theme.getTextHighlightColor(), /* Text background color when selected */
 403       "textHighlightText", theme.getHighlightedTextColor(), /* Text color when selected */
 404        "textInactiveText", theme.getInactiveSystemTextColor(), /* Text color when disabled */
 405                 "control", control, /* Default color for controls (buttons, sliders, etc) */
 406             "controlText", theme.getControlTextColor(), /* Default color for text in controls */
 407        "controlHighlight", theme.getControlHighlight(), /* Specular highlight (opposite of the shadow) */
 408      "controlLtHighlight", theme.getControlHighlight(), /* Highlight color for controls */
 409           "controlShadow", theme.getControlShadow(), /* Shadow color for controls */
 410         "controlDkShadow", theme.getControlDarkShadow(), /* Dark shadow color for controls */
 411               "scrollbar", control, /* Scrollbar background (usually the "track") */
 412                    "info", theme.getPrimaryControl(), /* ToolTip Background */
 413                "infoText", theme.getPrimaryControlInfo()  /* ToolTip Text */
 414         };
 415 
 416         table.putDefaults(systemColors);
 417     }
 418 
 419     /**
 420      * Initialize the defaults table with the name of the ResourceBundle
 421      * used for getting localized defaults.
 422      */
 423     private void initResourceBundle(UIDefaults table) {
 424         table.addResourceBundle( "com.sun.swing.internal.plaf.metal.resources.metal" );
 425     }
 426 
 427     /**
 428      * Populates {@code table} with the defaults for metal.
 429      *
 430      * @param table the {@code UIDefaults} to add the values to
 431      * @throws NullPointerException if {@code table} is {@code null}
 432      */
 433     protected void initComponentDefaults(UIDefaults table) {
 434         super.initComponentDefaults( table );
 435 
 436         initResourceBundle(table);
 437 
 438         Color acceleratorForeground = getAcceleratorForeground();
 439         Color acceleratorSelectedForeground = getAcceleratorSelectedForeground();
 440         Color control = getControl();
 441         Color controlHighlight = getControlHighlight();
 442         Color controlShadow = getControlShadow();
 443         Color controlDarkShadow = getControlDarkShadow();
 444         Color controlTextColor = getControlTextColor();
 445         Color focusColor = getFocusColor();
 446         Color inactiveControlTextColor = getInactiveControlTextColor();
 447         Color menuBackground = getMenuBackground();
 448         Color menuSelectedBackground = getMenuSelectedBackground();
 449         Color menuDisabledForeground = getMenuDisabledForeground();
 450         Color menuSelectedForeground = getMenuSelectedForeground();
 451         Color primaryControl = getPrimaryControl();
 452         Color primaryControlDarkShadow = getPrimaryControlDarkShadow();
 453         Color primaryControlShadow = getPrimaryControlShadow();
 454         Color systemTextColor = getSystemTextColor();
 455 
 456         Insets zeroInsets = new InsetsUIResource(0, 0, 0, 0);
 457 
 458         Integer zero = Integer.valueOf(0);
 459 
 460         LazyValue textFieldBorder =
 461             t -> MetalBorders.getTextFieldBorder();
 462 
 463         Object dialogBorder = new MetalLazyValue(
 464                           "javax.swing.plaf.metal.MetalBorders$DialogBorder");
 465 
 466         Object questionDialogBorder = new MetalLazyValue(
 467                   "javax.swing.plaf.metal.MetalBorders$QuestionDialogBorder");
 468 
 469         Object fieldInputMap = new UIDefaults.LazyInputMap(new Object[] {
 470                            "ctrl C", DefaultEditorKit.copyAction,
 471                            "ctrl V", DefaultEditorKit.pasteAction,
 472                            "ctrl X", DefaultEditorKit.cutAction,
 473                              "COPY", DefaultEditorKit.copyAction,
 474                             "PASTE", DefaultEditorKit.pasteAction,
 475                               "CUT", DefaultEditorKit.cutAction,
 476                    "control INSERT", DefaultEditorKit.copyAction,
 477                      "shift INSERT", DefaultEditorKit.pasteAction,
 478                      "shift DELETE", DefaultEditorKit.cutAction,
 479                        "shift LEFT", DefaultEditorKit.selectionBackwardAction,
 480                     "shift KP_LEFT", DefaultEditorKit.selectionBackwardAction,
 481                       "shift RIGHT", DefaultEditorKit.selectionForwardAction,
 482                    "shift KP_RIGHT", DefaultEditorKit.selectionForwardAction,
 483                         "ctrl LEFT", DefaultEditorKit.previousWordAction,
 484                      "ctrl KP_LEFT", DefaultEditorKit.previousWordAction,
 485                        "ctrl RIGHT", DefaultEditorKit.nextWordAction,
 486                     "ctrl KP_RIGHT", DefaultEditorKit.nextWordAction,
 487                   "ctrl shift LEFT", DefaultEditorKit.selectionPreviousWordAction,
 488                "ctrl shift KP_LEFT", DefaultEditorKit.selectionPreviousWordAction,
 489                  "ctrl shift RIGHT", DefaultEditorKit.selectionNextWordAction,
 490               "ctrl shift KP_RIGHT", DefaultEditorKit.selectionNextWordAction,
 491                            "ctrl A", DefaultEditorKit.selectAllAction,
 492                              "HOME", DefaultEditorKit.beginLineAction,
 493                               "END", DefaultEditorKit.endLineAction,
 494                        "shift HOME", DefaultEditorKit.selectionBeginLineAction,
 495                         "shift END", DefaultEditorKit.selectionEndLineAction,
 496                        "BACK_SPACE", DefaultEditorKit.deletePrevCharAction,
 497                  "shift BACK_SPACE", DefaultEditorKit.deletePrevCharAction,
 498                            "ctrl H", DefaultEditorKit.deletePrevCharAction,
 499                            "DELETE", DefaultEditorKit.deleteNextCharAction,
 500                       "ctrl DELETE", DefaultEditorKit.deleteNextWordAction,
 501                   "ctrl BACK_SPACE", DefaultEditorKit.deletePrevWordAction,
 502                             "RIGHT", DefaultEditorKit.forwardAction,
 503                              "LEFT", DefaultEditorKit.backwardAction,
 504                          "KP_RIGHT", DefaultEditorKit.forwardAction,
 505                           "KP_LEFT", DefaultEditorKit.backwardAction,
 506                             "ENTER", JTextField.notifyAction,
 507                   "ctrl BACK_SLASH", "unselect"/*DefaultEditorKit.unselectAction*/,
 508                    "control shift O", "toggle-componentOrientation"/*DefaultEditorKit.toggleComponentOrientation*/
 509         });
 510 
 511         Object passwordInputMap = new UIDefaults.LazyInputMap(new Object[] {
 512                            "ctrl C", DefaultEditorKit.copyAction,
 513                            "ctrl V", DefaultEditorKit.pasteAction,
 514                            "ctrl X", DefaultEditorKit.cutAction,
 515                              "COPY", DefaultEditorKit.copyAction,
 516                             "PASTE", DefaultEditorKit.pasteAction,
 517                               "CUT", DefaultEditorKit.cutAction,
 518                    "control INSERT", DefaultEditorKit.copyAction,
 519                      "shift INSERT", DefaultEditorKit.pasteAction,
 520                      "shift DELETE", DefaultEditorKit.cutAction,
 521                        "shift LEFT", DefaultEditorKit.selectionBackwardAction,
 522                     "shift KP_LEFT", DefaultEditorKit.selectionBackwardAction,
 523                       "shift RIGHT", DefaultEditorKit.selectionForwardAction,
 524                    "shift KP_RIGHT", DefaultEditorKit.selectionForwardAction,
 525                         "ctrl LEFT", DefaultEditorKit.beginLineAction,
 526                      "ctrl KP_LEFT", DefaultEditorKit.beginLineAction,
 527                        "ctrl RIGHT", DefaultEditorKit.endLineAction,
 528                     "ctrl KP_RIGHT", DefaultEditorKit.endLineAction,
 529                   "ctrl shift LEFT", DefaultEditorKit.selectionBeginLineAction,
 530                "ctrl shift KP_LEFT", DefaultEditorKit.selectionBeginLineAction,
 531                  "ctrl shift RIGHT", DefaultEditorKit.selectionEndLineAction,
 532               "ctrl shift KP_RIGHT", DefaultEditorKit.selectionEndLineAction,
 533                            "ctrl A", DefaultEditorKit.selectAllAction,
 534                              "HOME", DefaultEditorKit.beginLineAction,
 535                               "END", DefaultEditorKit.endLineAction,
 536                        "shift HOME", DefaultEditorKit.selectionBeginLineAction,
 537                         "shift END", DefaultEditorKit.selectionEndLineAction,
 538                        "BACK_SPACE", DefaultEditorKit.deletePrevCharAction,
 539                  "shift BACK_SPACE", DefaultEditorKit.deletePrevCharAction,
 540                            "ctrl H", DefaultEditorKit.deletePrevCharAction,
 541                            "DELETE", DefaultEditorKit.deleteNextCharAction,
 542                             "RIGHT", DefaultEditorKit.forwardAction,
 543                              "LEFT", DefaultEditorKit.backwardAction,
 544                          "KP_RIGHT", DefaultEditorKit.forwardAction,
 545                           "KP_LEFT", DefaultEditorKit.backwardAction,
 546                             "ENTER", JTextField.notifyAction,
 547                   "ctrl BACK_SLASH", "unselect"/*DefaultEditorKit.unselectAction*/,
 548                    "control shift O", "toggle-componentOrientation"/*DefaultEditorKit.toggleComponentOrientation*/
 549         });
 550 
 551         Object multilineInputMap = new UIDefaults.LazyInputMap(new Object[] {
 552                            "ctrl C", DefaultEditorKit.copyAction,
 553                            "ctrl V", DefaultEditorKit.pasteAction,
 554                            "ctrl X", DefaultEditorKit.cutAction,
 555                              "COPY", DefaultEditorKit.copyAction,
 556                             "PASTE", DefaultEditorKit.pasteAction,
 557                               "CUT", DefaultEditorKit.cutAction,
 558                    "control INSERT", DefaultEditorKit.copyAction,
 559                      "shift INSERT", DefaultEditorKit.pasteAction,
 560                      "shift DELETE", DefaultEditorKit.cutAction,
 561                        "shift LEFT", DefaultEditorKit.selectionBackwardAction,
 562                     "shift KP_LEFT", DefaultEditorKit.selectionBackwardAction,
 563                       "shift RIGHT", DefaultEditorKit.selectionForwardAction,
 564                    "shift KP_RIGHT", DefaultEditorKit.selectionForwardAction,
 565                         "ctrl LEFT", DefaultEditorKit.previousWordAction,
 566                      "ctrl KP_LEFT", DefaultEditorKit.previousWordAction,
 567                        "ctrl RIGHT", DefaultEditorKit.nextWordAction,
 568                     "ctrl KP_RIGHT", DefaultEditorKit.nextWordAction,
 569                   "ctrl shift LEFT", DefaultEditorKit.selectionPreviousWordAction,
 570                "ctrl shift KP_LEFT", DefaultEditorKit.selectionPreviousWordAction,
 571                  "ctrl shift RIGHT", DefaultEditorKit.selectionNextWordAction,
 572               "ctrl shift KP_RIGHT", DefaultEditorKit.selectionNextWordAction,
 573                            "ctrl A", DefaultEditorKit.selectAllAction,
 574                              "HOME", DefaultEditorKit.beginLineAction,
 575                               "END", DefaultEditorKit.endLineAction,
 576                        "shift HOME", DefaultEditorKit.selectionBeginLineAction,
 577                         "shift END", DefaultEditorKit.selectionEndLineAction,
 578 
 579                                "UP", DefaultEditorKit.upAction,
 580                             "KP_UP", DefaultEditorKit.upAction,
 581                              "DOWN", DefaultEditorKit.downAction,
 582                           "KP_DOWN", DefaultEditorKit.downAction,
 583                           "PAGE_UP", DefaultEditorKit.pageUpAction,
 584                         "PAGE_DOWN", DefaultEditorKit.pageDownAction,
 585                     "shift PAGE_UP", "selection-page-up",
 586                   "shift PAGE_DOWN", "selection-page-down",
 587                "ctrl shift PAGE_UP", "selection-page-left",
 588              "ctrl shift PAGE_DOWN", "selection-page-right",
 589                          "shift UP", DefaultEditorKit.selectionUpAction,
 590                       "shift KP_UP", DefaultEditorKit.selectionUpAction,
 591                        "shift DOWN", DefaultEditorKit.selectionDownAction,
 592                     "shift KP_DOWN", DefaultEditorKit.selectionDownAction,
 593                             "ENTER", DefaultEditorKit.insertBreakAction,
 594                        "BACK_SPACE", DefaultEditorKit.deletePrevCharAction,
 595                  "shift BACK_SPACE", DefaultEditorKit.deletePrevCharAction,
 596                            "ctrl H", DefaultEditorKit.deletePrevCharAction,
 597                            "DELETE", DefaultEditorKit.deleteNextCharAction,
 598                       "ctrl DELETE", DefaultEditorKit.deleteNextWordAction,
 599                   "ctrl BACK_SPACE", DefaultEditorKit.deletePrevWordAction,
 600                             "RIGHT", DefaultEditorKit.forwardAction,
 601                              "LEFT", DefaultEditorKit.backwardAction,
 602                          "KP_RIGHT", DefaultEditorKit.forwardAction,
 603                           "KP_LEFT", DefaultEditorKit.backwardAction,
 604                               "TAB", DefaultEditorKit.insertTabAction,
 605                   "ctrl BACK_SLASH", "unselect"/*DefaultEditorKit.unselectAction*/,
 606                         "ctrl HOME", DefaultEditorKit.beginAction,
 607                          "ctrl END", DefaultEditorKit.endAction,
 608                   "ctrl shift HOME", DefaultEditorKit.selectionBeginAction,
 609                    "ctrl shift END", DefaultEditorKit.selectionEndAction,
 610                            "ctrl T", "next-link-action",
 611                      "ctrl shift T", "previous-link-action",
 612                        "ctrl SPACE", "activate-link-action",
 613                    "control shift O", "toggle-componentOrientation"/*DefaultEditorKit.toggleComponentOrientation*/
 614         });
 615 
 616         LazyValue scrollPaneBorder = t -> new MetalBorders.ScrollPaneBorder();
 617         LazyValue buttonBorder =
 618             t -> MetalBorders.getButtonBorder();
 619 
 620         LazyValue toggleButtonBorder =
 621             t -> MetalBorders.getToggleButtonBorder();
 622 
 623         LazyValue titledBorderBorder =
 624             t -> new BorderUIResource.LineBorderUIResource(controlShadow);
 625 
 626         LazyValue desktopIconBorder =
 627             t -> MetalBorders.getDesktopIconBorder();
 628 
 629         LazyValue menuBarBorder =
 630             t -> new MetalBorders.MenuBarBorder();
 631 
 632         LazyValue popupMenuBorder =
 633             t -> new MetalBorders.PopupMenuBorder();
 634         LazyValue menuItemBorder =
 635             t -> new MetalBorders.MenuItemBorder();
 636 
 637         Object menuItemAcceleratorDelimiter = "-";
 638         LazyValue toolBarBorder = t -> new MetalBorders.ToolBarBorder();
 639 
 640         LazyValue progressBarBorder = t ->
 641             new BorderUIResource.LineBorderUIResource(controlDarkShadow, new Integer(1));
 642 
 643         LazyValue toolTipBorder = t ->
 644             new BorderUIResource.LineBorderUIResource(primaryControlDarkShadow);
 645 
 646         LazyValue toolTipBorderInactive = t ->
 647             new BorderUIResource.LineBorderUIResource(controlDarkShadow);
 648 
 649         LazyValue focusCellHighlightBorder = t ->
 650             new BorderUIResource.LineBorderUIResource(focusColor);
 651 
 652         Object tabbedPaneTabAreaInsets = new InsetsUIResource(4, 2, 0, 6);
 653 
 654         Object tabbedPaneTabInsets = new InsetsUIResource(0, 9, 1, 9);
 655 
 656         int internalFrameIconSize = 16;
 657 
 658         Object[] defaultCueList = new Object[] {
 659                 "OptionPane.errorSound",
 660                 "OptionPane.informationSound",
 661                 "OptionPane.questionSound",
 662                 "OptionPane.warningSound" };
 663 
 664         MetalTheme theme = getCurrentTheme();
 665         Object menuTextValue = new FontActiveValue(theme,
 666                                                    MetalTheme.MENU_TEXT_FONT);
 667         Object controlTextValue = new FontActiveValue(theme,
 668                                MetalTheme.CONTROL_TEXT_FONT);
 669         Object userTextValue = new FontActiveValue(theme,
 670                                                    MetalTheme.USER_TEXT_FONT);
 671         Object windowTitleValue = new FontActiveValue(theme,
 672                                MetalTheme.WINDOW_TITLE_FONT);
 673         Object subTextValue = new FontActiveValue(theme,
 674                                                   MetalTheme.SUB_TEXT_FONT);
 675         Object systemTextValue = new FontActiveValue(theme,
 676                                                  MetalTheme.SYSTEM_TEXT_FONT);
 677         //
 678         // DEFAULTS TABLE
 679         //
 680 
 681         Object[] defaults = {
 682             // *** Auditory Feedback
 683             "AuditoryCues.defaultCueList", defaultCueList,
 684             // this key defines which of the various cues to render
 685             // This is disabled until sound bugs can be resolved.
 686             "AuditoryCues.playList", null, // defaultCueList,
 687 
 688             // Text (Note: many are inherited)
 689             "TextField.border", textFieldBorder,
 690             "TextField.font", userTextValue,
 691 
 692             "PasswordField.border", textFieldBorder,
 693             // passwordField.font should actually map to
 694             // win.ansiFixed.font.height on windows.
 695             "PasswordField.font", userTextValue,
 696             "PasswordField.echoChar", (char)0x2022,
 697 
 698             // TextArea.font should actually map to win.ansiFixed.font.height
 699             // on windows.
 700             "TextArea.font", userTextValue,
 701 
 702             "TextPane.background", table.get("window"),
 703             "TextPane.font", userTextValue,
 704 
 705             "EditorPane.background", table.get("window"),
 706             "EditorPane.font", userTextValue,
 707 
 708             "TextField.focusInputMap", fieldInputMap,
 709             "PasswordField.focusInputMap", passwordInputMap,
 710             "TextArea.focusInputMap", multilineInputMap,
 711             "TextPane.focusInputMap", multilineInputMap,
 712             "EditorPane.focusInputMap", multilineInputMap,
 713 
 714             // FormattedTextFields
 715             "FormattedTextField.border", textFieldBorder,
 716             "FormattedTextField.font", userTextValue,
 717             "FormattedTextField.focusInputMap",
 718               new UIDefaults.LazyInputMap(new Object[] {
 719                            "ctrl C", DefaultEditorKit.copyAction,
 720                            "ctrl V", DefaultEditorKit.pasteAction,
 721                            "ctrl X", DefaultEditorKit.cutAction,
 722                              "COPY", DefaultEditorKit.copyAction,
 723                             "PASTE", DefaultEditorKit.pasteAction,
 724                               "CUT", DefaultEditorKit.cutAction,
 725                    "control INSERT", DefaultEditorKit.copyAction,
 726                      "shift INSERT", DefaultEditorKit.pasteAction,
 727                      "shift DELETE", DefaultEditorKit.cutAction,
 728                        "shift LEFT", DefaultEditorKit.selectionBackwardAction,
 729                     "shift KP_LEFT", DefaultEditorKit.selectionBackwardAction,
 730                       "shift RIGHT", DefaultEditorKit.selectionForwardAction,
 731                    "shift KP_RIGHT", DefaultEditorKit.selectionForwardAction,
 732                         "ctrl LEFT", DefaultEditorKit.previousWordAction,
 733                      "ctrl KP_LEFT", DefaultEditorKit.previousWordAction,
 734                        "ctrl RIGHT", DefaultEditorKit.nextWordAction,
 735                     "ctrl KP_RIGHT", DefaultEditorKit.nextWordAction,
 736                   "ctrl shift LEFT", DefaultEditorKit.selectionPreviousWordAction,
 737                "ctrl shift KP_LEFT", DefaultEditorKit.selectionPreviousWordAction,
 738                  "ctrl shift RIGHT", DefaultEditorKit.selectionNextWordAction,
 739               "ctrl shift KP_RIGHT", DefaultEditorKit.selectionNextWordAction,
 740                            "ctrl A", DefaultEditorKit.selectAllAction,
 741                              "HOME", DefaultEditorKit.beginLineAction,
 742                               "END", DefaultEditorKit.endLineAction,
 743                        "shift HOME", DefaultEditorKit.selectionBeginLineAction,
 744                         "shift END", DefaultEditorKit.selectionEndLineAction,
 745                        "BACK_SPACE", DefaultEditorKit.deletePrevCharAction,
 746                  "shift BACK_SPACE", DefaultEditorKit.deletePrevCharAction,
 747                            "ctrl H", DefaultEditorKit.deletePrevCharAction,
 748                            "DELETE", DefaultEditorKit.deleteNextCharAction,
 749                       "ctrl DELETE", DefaultEditorKit.deleteNextWordAction,
 750                   "ctrl BACK_SPACE", DefaultEditorKit.deletePrevWordAction,
 751                             "RIGHT", DefaultEditorKit.forwardAction,
 752                              "LEFT", DefaultEditorKit.backwardAction,
 753                          "KP_RIGHT", DefaultEditorKit.forwardAction,
 754                           "KP_LEFT", DefaultEditorKit.backwardAction,
 755                             "ENTER", JTextField.notifyAction,
 756                   "ctrl BACK_SLASH", "unselect",
 757                    "control shift O", "toggle-componentOrientation",
 758                            "ESCAPE", "reset-field-edit",
 759                                "UP", "increment",
 760                             "KP_UP", "increment",
 761                              "DOWN", "decrement",
 762                           "KP_DOWN", "decrement",
 763               }),
 764 
 765 
 766             // Buttons
 767             "Button.defaultButtonFollowsFocus", Boolean.FALSE,
 768             "Button.disabledText", inactiveControlTextColor,
 769             "Button.select", controlShadow,
 770             "Button.border", buttonBorder,
 771             "Button.font", controlTextValue,
 772             "Button.focus", focusColor,
 773             "Button.focusInputMap", new UIDefaults.LazyInputMap(new Object[] {
 774                           "SPACE", "pressed",
 775                  "released SPACE", "released"
 776               }),
 777 
 778             "CheckBox.disabledText", inactiveControlTextColor,
 779             "Checkbox.select", controlShadow,
 780             "CheckBox.font", controlTextValue,
 781             "CheckBox.focus", focusColor,
 782             "CheckBox.icon",(LazyValue) t -> MetalIconFactory.getCheckBoxIcon(),
 783             "CheckBox.focusInputMap",
 784                new UIDefaults.LazyInputMap(new Object[] {
 785                             "SPACE", "pressed",
 786                    "released SPACE", "released"
 787                  }),
 788             // margin is 2 all the way around, BasicBorders.RadioButtonBorder
 789             // (checkbox uses RadioButtonBorder) is 2 all the way around too.
 790             "CheckBox.totalInsets", new Insets(4, 4, 4, 4),
 791 
 792             "RadioButton.disabledText", inactiveControlTextColor,
 793             "RadioButton.select", controlShadow,
 794             "RadioButton.icon",(LazyValue) t -> MetalIconFactory.getRadioButtonIcon(),
 795             "RadioButton.font", controlTextValue,
 796             "RadioButton.focus", focusColor,
 797             "RadioButton.focusInputMap",
 798                new UIDefaults.LazyInputMap(new Object[] {
 799                           "SPACE", "pressed",
 800                  "released SPACE", "released"
 801               }),
 802             // margin is 2 all the way around, BasicBorders.RadioButtonBorder
 803             // is 2 all the way around too.
 804             "RadioButton.totalInsets", new Insets(4, 4, 4, 4),
 805 
 806             "ToggleButton.select", controlShadow,
 807             "ToggleButton.disabledText", inactiveControlTextColor,
 808             "ToggleButton.focus", focusColor,
 809             "ToggleButton.border", toggleButtonBorder,
 810             "ToggleButton.font", controlTextValue,
 811             "ToggleButton.focusInputMap",
 812               new UIDefaults.LazyInputMap(new Object[] {
 813                             "SPACE", "pressed",
 814                    "released SPACE", "released"
 815                 }),
 816 
 817 
 818             // File View
 819             "FileView.directoryIcon",(LazyValue) t -> MetalIconFactory.getTreeFolderIcon(),
 820             "FileView.fileIcon",(LazyValue) t -> MetalIconFactory.getTreeLeafIcon(),
 821             "FileView.computerIcon",(LazyValue) t -> MetalIconFactory.getTreeComputerIcon(),
 822             "FileView.hardDriveIcon",(LazyValue) t -> MetalIconFactory.getTreeHardDriveIcon(),
 823             "FileView.floppyDriveIcon",(LazyValue) t -> MetalIconFactory.getTreeFloppyDriveIcon(),
 824 
 825             // File Chooser
 826             "FileChooser.detailsViewIcon",(LazyValue) t -> MetalIconFactory.getFileChooserDetailViewIcon(),
 827             "FileChooser.homeFolderIcon",(LazyValue) t -> MetalIconFactory.getFileChooserHomeFolderIcon(),
 828             "FileChooser.listViewIcon",(LazyValue) t -> MetalIconFactory.getFileChooserListViewIcon(),
 829             "FileChooser.newFolderIcon",(LazyValue) t -> MetalIconFactory.getFileChooserNewFolderIcon(),
 830             "FileChooser.upFolderIcon",(LazyValue) t -> MetalIconFactory.getFileChooserUpFolderIcon(),
 831 
 832             "FileChooser.usesSingleFilePane", Boolean.TRUE,
 833             "FileChooser.ancestorInputMap",
 834                new UIDefaults.LazyInputMap(new Object[] {
 835                      "ESCAPE", "cancelSelection",
 836                      "F2", "editFileName",
 837                      "F5", "refresh",
 838                      "BACK_SPACE", "Go Up"
 839                  }),
 840 
 841 
 842             // ToolTip
 843             "ToolTip.font", systemTextValue,
 844             "ToolTip.border", toolTipBorder,
 845             "ToolTip.borderInactive", toolTipBorderInactive,
 846             "ToolTip.backgroundInactive", control,
 847             "ToolTip.foregroundInactive", controlDarkShadow,
 848             "ToolTip.hideAccelerator", Boolean.FALSE,
 849 
 850             // ToolTipManager
 851             "ToolTipManager.enableToolTipMode", "activeApplication",
 852 
 853             // Slider Defaults
 854             "Slider.font", controlTextValue,
 855             "Slider.border", null,
 856             "Slider.foreground", primaryControlShadow,
 857             "Slider.focus", focusColor,
 858             "Slider.focusInsets", zeroInsets,
 859             "Slider.trackWidth", new Integer( 7 ),
 860             "Slider.majorTickLength", new Integer( 6 ),
 861             "Slider.horizontalThumbIcon",(LazyValue) t -> MetalIconFactory.getHorizontalSliderThumbIcon(),
 862             "Slider.verticalThumbIcon",(LazyValue) t -> MetalIconFactory.getVerticalSliderThumbIcon(),
 863             "Slider.focusInputMap",
 864                new UIDefaults.LazyInputMap(new Object[] {
 865                        "RIGHT", "positiveUnitIncrement",
 866                     "KP_RIGHT", "positiveUnitIncrement",
 867                         "DOWN", "negativeUnitIncrement",
 868                      "KP_DOWN", "negativeUnitIncrement",
 869                    "PAGE_DOWN", "negativeBlockIncrement",
 870               "ctrl PAGE_DOWN", "negativeBlockIncrement",
 871                         "LEFT", "negativeUnitIncrement",
 872                      "KP_LEFT", "negativeUnitIncrement",
 873                           "UP", "positiveUnitIncrement",
 874                        "KP_UP", "positiveUnitIncrement",
 875                      "PAGE_UP", "positiveBlockIncrement",
 876                 "ctrl PAGE_UP", "positiveBlockIncrement",
 877                         "HOME", "minScroll",
 878                          "END", "maxScroll"
 879                  }),
 880 
 881             // Progress Bar
 882             "ProgressBar.font", controlTextValue,
 883             "ProgressBar.foreground", primaryControlShadow,
 884             "ProgressBar.selectionBackground", primaryControlDarkShadow,
 885             "ProgressBar.border", progressBarBorder,
 886             "ProgressBar.cellSpacing", zero,
 887             "ProgressBar.cellLength", Integer.valueOf(1),
 888 
 889             // Combo Box
 890             "ComboBox.background", control,
 891             "ComboBox.foreground", controlTextColor,
 892             "ComboBox.selectionBackground", primaryControlShadow,
 893             "ComboBox.selectionForeground", controlTextColor,
 894             "ComboBox.font", controlTextValue,
 895             "ComboBox.ancestorInputMap", new UIDefaults.LazyInputMap(new Object[] {
 896                      "ESCAPE", "hidePopup",
 897                     "PAGE_UP", "pageUpPassThrough",
 898                   "PAGE_DOWN", "pageDownPassThrough",
 899                        "HOME", "homePassThrough",
 900                         "END", "endPassThrough",
 901                        "DOWN", "selectNext",
 902                     "KP_DOWN", "selectNext",
 903                    "alt DOWN", "togglePopup",
 904                 "alt KP_DOWN", "togglePopup",
 905                      "alt UP", "togglePopup",
 906                   "alt KP_UP", "togglePopup",
 907                       "SPACE", "spacePopup",
 908                      "ENTER", "enterPressed",
 909                          "UP", "selectPrevious",
 910                       "KP_UP", "selectPrevious"
 911               }),
 912 
 913             // Internal Frame Defaults
 914             "InternalFrame.icon",(LazyValue) t ->
 915                     MetalIconFactory.getInternalFrameDefaultMenuIcon(),
 916             "InternalFrame.border",(LazyValue) t ->
 917                     new MetalBorders.InternalFrameBorder(),
 918             "InternalFrame.optionDialogBorder",(LazyValue) t ->
 919                     new MetalBorders.OptionDialogBorder(),
 920             "InternalFrame.paletteBorder",(LazyValue) t ->
 921                     new MetalBorders.PaletteBorder(),
 922             "InternalFrame.paletteTitleHeight", new Integer(11),
 923             "InternalFrame.paletteCloseIcon",(LazyValue) t ->
 924                     new MetalIconFactory.PaletteCloseIcon(),
 925             "InternalFrame.closeIcon",
 926                (LazyValue) t -> MetalIconFactory.
 927                        getInternalFrameCloseIcon(internalFrameIconSize),
 928             "InternalFrame.maximizeIcon",
 929                (LazyValue) t -> MetalIconFactory.
 930                        getInternalFrameMaximizeIcon(internalFrameIconSize),
 931             "InternalFrame.iconifyIcon",
 932                (LazyValue) t -> MetalIconFactory.
 933                        getInternalFrameMinimizeIcon(internalFrameIconSize),
 934             "InternalFrame.minimizeIcon",
 935                (LazyValue) t -> MetalIconFactory.
 936                        getInternalFrameAltMaximizeIcon(internalFrameIconSize),
 937             "InternalFrame.titleFont",  windowTitleValue,
 938             "InternalFrame.windowBindings", null,
 939             // Internal Frame Auditory Cue Mappings
 940             "InternalFrame.closeSound", "sounds/FrameClose.wav",
 941             "InternalFrame.maximizeSound", "sounds/FrameMaximize.wav",
 942             "InternalFrame.minimizeSound", "sounds/FrameMinimize.wav",
 943             "InternalFrame.restoreDownSound", "sounds/FrameRestoreDown.wav",
 944             "InternalFrame.restoreUpSound", "sounds/FrameRestoreUp.wav",
 945 
 946             // Desktop Icon
 947             "DesktopIcon.border", desktopIconBorder,
 948             "DesktopIcon.font", controlTextValue,
 949             "DesktopIcon.foreground", controlTextColor,
 950             "DesktopIcon.background", control,
 951             "DesktopIcon.width", Integer.valueOf(160),
 952 
 953             "Desktop.ancestorInputMap",
 954                new UIDefaults.LazyInputMap(new Object[] {
 955                  "ctrl F5", "restore",
 956                  "ctrl F4", "close",
 957                  "ctrl F7", "move",
 958                  "ctrl F8", "resize",
 959                    "RIGHT", "right",
 960                 "KP_RIGHT", "right",
 961              "shift RIGHT", "shrinkRight",
 962           "shift KP_RIGHT", "shrinkRight",
 963                     "LEFT", "left",
 964                  "KP_LEFT", "left",
 965               "shift LEFT", "shrinkLeft",
 966            "shift KP_LEFT", "shrinkLeft",
 967                       "UP", "up",
 968                    "KP_UP", "up",
 969                 "shift UP", "shrinkUp",
 970              "shift KP_UP", "shrinkUp",
 971                     "DOWN", "down",
 972                  "KP_DOWN", "down",
 973               "shift DOWN", "shrinkDown",
 974            "shift KP_DOWN", "shrinkDown",
 975                   "ESCAPE", "escape",
 976                  "ctrl F9", "minimize",
 977                 "ctrl F10", "maximize",
 978                  "ctrl F6", "selectNextFrame",
 979                 "ctrl TAB", "selectNextFrame",
 980              "ctrl alt F6", "selectNextFrame",
 981        "shift ctrl alt F6", "selectPreviousFrame",
 982                 "ctrl F12", "navigateNext",
 983            "shift ctrl F12", "navigatePrevious"
 984               }),
 985 
 986             // Titled Border
 987             "TitledBorder.font", controlTextValue,
 988             "TitledBorder.titleColor", systemTextColor,
 989             "TitledBorder.border", titledBorderBorder,
 990 
 991             // Label
 992             "Label.font", controlTextValue,
 993             "Label.foreground", systemTextColor,
 994             "Label.disabledForeground", getInactiveSystemTextColor(),
 995 
 996             // List
 997             "List.font", controlTextValue,
 998             "List.focusCellHighlightBorder", focusCellHighlightBorder,
 999             "List.focusInputMap",
1000                new UIDefaults.LazyInputMap(new Object[] {
1001                            "ctrl C", "copy",
1002                            "ctrl V", "paste",
1003                            "ctrl X", "cut",
1004                              "COPY", "copy",
1005                             "PASTE", "paste",
1006                               "CUT", "cut",
1007                    "control INSERT", "copy",
1008                      "shift INSERT", "paste",
1009                      "shift DELETE", "cut",
1010                                "UP", "selectPreviousRow",
1011                             "KP_UP", "selectPreviousRow",
1012                          "shift UP", "selectPreviousRowExtendSelection",
1013                       "shift KP_UP", "selectPreviousRowExtendSelection",
1014                     "ctrl shift UP", "selectPreviousRowExtendSelection",
1015                  "ctrl shift KP_UP", "selectPreviousRowExtendSelection",
1016                           "ctrl UP", "selectPreviousRowChangeLead",
1017                        "ctrl KP_UP", "selectPreviousRowChangeLead",
1018                              "DOWN", "selectNextRow",
1019                           "KP_DOWN", "selectNextRow",
1020                        "shift DOWN", "selectNextRowExtendSelection",
1021                     "shift KP_DOWN", "selectNextRowExtendSelection",
1022                   "ctrl shift DOWN", "selectNextRowExtendSelection",
1023                "ctrl shift KP_DOWN", "selectNextRowExtendSelection",
1024                         "ctrl DOWN", "selectNextRowChangeLead",
1025                      "ctrl KP_DOWN", "selectNextRowChangeLead",
1026                              "LEFT", "selectPreviousColumn",
1027                           "KP_LEFT", "selectPreviousColumn",
1028                        "shift LEFT", "selectPreviousColumnExtendSelection",
1029                     "shift KP_LEFT", "selectPreviousColumnExtendSelection",
1030                   "ctrl shift LEFT", "selectPreviousColumnExtendSelection",
1031                "ctrl shift KP_LEFT", "selectPreviousColumnExtendSelection",
1032                         "ctrl LEFT", "selectPreviousColumnChangeLead",
1033                      "ctrl KP_LEFT", "selectPreviousColumnChangeLead",
1034                             "RIGHT", "selectNextColumn",
1035                          "KP_RIGHT", "selectNextColumn",
1036                       "shift RIGHT", "selectNextColumnExtendSelection",
1037                    "shift KP_RIGHT", "selectNextColumnExtendSelection",
1038                  "ctrl shift RIGHT", "selectNextColumnExtendSelection",
1039               "ctrl shift KP_RIGHT", "selectNextColumnExtendSelection",
1040                        "ctrl RIGHT", "selectNextColumnChangeLead",
1041                     "ctrl KP_RIGHT", "selectNextColumnChangeLead",
1042                              "HOME", "selectFirstRow",
1043                        "shift HOME", "selectFirstRowExtendSelection",
1044                   "ctrl shift HOME", "selectFirstRowExtendSelection",
1045                         "ctrl HOME", "selectFirstRowChangeLead",
1046                               "END", "selectLastRow",
1047                         "shift END", "selectLastRowExtendSelection",
1048                    "ctrl shift END", "selectLastRowExtendSelection",
1049                          "ctrl END", "selectLastRowChangeLead",
1050                           "PAGE_UP", "scrollUp",
1051                     "shift PAGE_UP", "scrollUpExtendSelection",
1052                "ctrl shift PAGE_UP", "scrollUpExtendSelection",
1053                      "ctrl PAGE_UP", "scrollUpChangeLead",
1054                         "PAGE_DOWN", "scrollDown",
1055                   "shift PAGE_DOWN", "scrollDownExtendSelection",
1056              "ctrl shift PAGE_DOWN", "scrollDownExtendSelection",
1057                    "ctrl PAGE_DOWN", "scrollDownChangeLead",
1058                            "ctrl A", "selectAll",
1059                        "ctrl SLASH", "selectAll",
1060                   "ctrl BACK_SLASH", "clearSelection",
1061                             "SPACE", "addToSelection",
1062                        "ctrl SPACE", "toggleAndAnchor",
1063                       "shift SPACE", "extendTo",
1064                  "ctrl shift SPACE", "moveSelectionTo"
1065                  }),
1066 
1067             // ScrollBar
1068             "ScrollBar.background", control,
1069             "ScrollBar.highlight", controlHighlight,
1070             "ScrollBar.shadow", controlShadow,
1071             "ScrollBar.darkShadow", controlDarkShadow,
1072             "ScrollBar.thumb", primaryControlShadow,
1073             "ScrollBar.thumbShadow", primaryControlDarkShadow,
1074             "ScrollBar.thumbHighlight", primaryControl,
1075             "ScrollBar.width", new Integer( 17 ),
1076             "ScrollBar.allowsAbsolutePositioning", Boolean.TRUE,
1077             "ScrollBar.ancestorInputMap",
1078                new UIDefaults.LazyInputMap(new Object[] {
1079                        "RIGHT", "positiveUnitIncrement",
1080                     "KP_RIGHT", "positiveUnitIncrement",
1081                         "DOWN", "positiveUnitIncrement",
1082                      "KP_DOWN", "positiveUnitIncrement",
1083                    "PAGE_DOWN", "positiveBlockIncrement",
1084                         "LEFT", "negativeUnitIncrement",
1085                      "KP_LEFT", "negativeUnitIncrement",
1086                           "UP", "negativeUnitIncrement",
1087                        "KP_UP", "negativeUnitIncrement",
1088                      "PAGE_UP", "negativeBlockIncrement",
1089                         "HOME", "minScroll",
1090                          "END", "maxScroll"
1091                  }),
1092 
1093             // ScrollPane
1094             "ScrollPane.border", scrollPaneBorder,
1095             "ScrollPane.ancestorInputMap",
1096                new UIDefaults.LazyInputMap(new Object[] {
1097                            "RIGHT", "unitScrollRight",
1098                         "KP_RIGHT", "unitScrollRight",
1099                             "DOWN", "unitScrollDown",
1100                          "KP_DOWN", "unitScrollDown",
1101                             "LEFT", "unitScrollLeft",
1102                          "KP_LEFT", "unitScrollLeft",
1103                               "UP", "unitScrollUp",
1104                            "KP_UP", "unitScrollUp",
1105                          "PAGE_UP", "scrollUp",
1106                        "PAGE_DOWN", "scrollDown",
1107                     "ctrl PAGE_UP", "scrollLeft",
1108                   "ctrl PAGE_DOWN", "scrollRight",
1109                        "ctrl HOME", "scrollHome",
1110                         "ctrl END", "scrollEnd"
1111                  }),
1112 
1113             // Tabbed Pane
1114             "TabbedPane.font", controlTextValue,
1115             "TabbedPane.tabAreaBackground", control,
1116             "TabbedPane.background", controlShadow,
1117             "TabbedPane.light", control,
1118             "TabbedPane.focus", primaryControlDarkShadow,
1119             "TabbedPane.selected", control,
1120             "TabbedPane.selectHighlight", controlHighlight,
1121             "TabbedPane.tabAreaInsets", tabbedPaneTabAreaInsets,
1122             "TabbedPane.tabInsets", tabbedPaneTabInsets,
1123             "TabbedPane.focusInputMap",
1124               new UIDefaults.LazyInputMap(new Object[] {
1125                          "RIGHT", "navigateRight",
1126                       "KP_RIGHT", "navigateRight",
1127                           "LEFT", "navigateLeft",
1128                        "KP_LEFT", "navigateLeft",
1129                             "UP", "navigateUp",
1130                          "KP_UP", "navigateUp",
1131                           "DOWN", "navigateDown",
1132                        "KP_DOWN", "navigateDown",
1133                      "ctrl DOWN", "requestFocusForVisibleComponent",
1134                   "ctrl KP_DOWN", "requestFocusForVisibleComponent",
1135                 }),
1136             "TabbedPane.ancestorInputMap",
1137                new UIDefaults.LazyInputMap(new Object[] {
1138                    "ctrl PAGE_DOWN", "navigatePageDown",
1139                      "ctrl PAGE_UP", "navigatePageUp",
1140                           "ctrl UP", "requestFocus",
1141                        "ctrl KP_UP", "requestFocus",
1142                  }),
1143 
1144             // Table
1145             "Table.font", userTextValue,
1146             "Table.focusCellHighlightBorder", focusCellHighlightBorder,
1147             "Table.scrollPaneBorder", scrollPaneBorder,
1148             "Table.dropLineColor", focusColor,
1149             "Table.dropLineShortColor", primaryControlDarkShadow,
1150             "Table.gridColor", controlShadow,  // grid line color
1151             "Table.ancestorInputMap",
1152                new UIDefaults.LazyInputMap(new Object[] {
1153                                "ctrl C", "copy",
1154                                "ctrl V", "paste",
1155                                "ctrl X", "cut",
1156                                  "COPY", "copy",
1157                                 "PASTE", "paste",
1158                                   "CUT", "cut",
1159                        "control INSERT", "copy",
1160                          "shift INSERT", "paste",
1161                          "shift DELETE", "cut",
1162                                 "RIGHT", "selectNextColumn",
1163                              "KP_RIGHT", "selectNextColumn",
1164                           "shift RIGHT", "selectNextColumnExtendSelection",
1165                        "shift KP_RIGHT", "selectNextColumnExtendSelection",
1166                      "ctrl shift RIGHT", "selectNextColumnExtendSelection",
1167                   "ctrl shift KP_RIGHT", "selectNextColumnExtendSelection",
1168                            "ctrl RIGHT", "selectNextColumnChangeLead",
1169                         "ctrl KP_RIGHT", "selectNextColumnChangeLead",
1170                                  "LEFT", "selectPreviousColumn",
1171                               "KP_LEFT", "selectPreviousColumn",
1172                            "shift LEFT", "selectPreviousColumnExtendSelection",
1173                         "shift KP_LEFT", "selectPreviousColumnExtendSelection",
1174                       "ctrl shift LEFT", "selectPreviousColumnExtendSelection",
1175                    "ctrl shift KP_LEFT", "selectPreviousColumnExtendSelection",
1176                             "ctrl LEFT", "selectPreviousColumnChangeLead",
1177                          "ctrl KP_LEFT", "selectPreviousColumnChangeLead",
1178                                  "DOWN", "selectNextRow",
1179                               "KP_DOWN", "selectNextRow",
1180                            "shift DOWN", "selectNextRowExtendSelection",
1181                         "shift KP_DOWN", "selectNextRowExtendSelection",
1182                       "ctrl shift DOWN", "selectNextRowExtendSelection",
1183                    "ctrl shift KP_DOWN", "selectNextRowExtendSelection",
1184                             "ctrl DOWN", "selectNextRowChangeLead",
1185                          "ctrl KP_DOWN", "selectNextRowChangeLead",
1186                                    "UP", "selectPreviousRow",
1187                                 "KP_UP", "selectPreviousRow",
1188                              "shift UP", "selectPreviousRowExtendSelection",
1189                           "shift KP_UP", "selectPreviousRowExtendSelection",
1190                         "ctrl shift UP", "selectPreviousRowExtendSelection",
1191                      "ctrl shift KP_UP", "selectPreviousRowExtendSelection",
1192                               "ctrl UP", "selectPreviousRowChangeLead",
1193                            "ctrl KP_UP", "selectPreviousRowChangeLead",
1194                                  "HOME", "selectFirstColumn",
1195                            "shift HOME", "selectFirstColumnExtendSelection",
1196                       "ctrl shift HOME", "selectFirstRowExtendSelection",
1197                             "ctrl HOME", "selectFirstRow",
1198                                   "END", "selectLastColumn",
1199                             "shift END", "selectLastColumnExtendSelection",
1200                        "ctrl shift END", "selectLastRowExtendSelection",
1201                              "ctrl END", "selectLastRow",
1202                               "PAGE_UP", "scrollUpChangeSelection",
1203                         "shift PAGE_UP", "scrollUpExtendSelection",
1204                    "ctrl shift PAGE_UP", "scrollLeftExtendSelection",
1205                          "ctrl PAGE_UP", "scrollLeftChangeSelection",
1206                             "PAGE_DOWN", "scrollDownChangeSelection",
1207                       "shift PAGE_DOWN", "scrollDownExtendSelection",
1208                  "ctrl shift PAGE_DOWN", "scrollRightExtendSelection",
1209                        "ctrl PAGE_DOWN", "scrollRightChangeSelection",
1210                                   "TAB", "selectNextColumnCell",
1211                             "shift TAB", "selectPreviousColumnCell",
1212                                 "ENTER", "selectNextRowCell",
1213                           "shift ENTER", "selectPreviousRowCell",
1214                                "ctrl A", "selectAll",
1215                            "ctrl SLASH", "selectAll",
1216                       "ctrl BACK_SLASH", "clearSelection",
1217                                "ESCAPE", "cancel",
1218                                    "F2", "startEditing",
1219                                 "SPACE", "addToSelection",
1220                            "ctrl SPACE", "toggleAndAnchor",
1221                           "shift SPACE", "extendTo",
1222                      "ctrl shift SPACE", "moveSelectionTo",
1223                                    "F8", "focusHeader"
1224                  }),
1225             "Table.ascendingSortIcon",
1226                 SwingUtilities2.makeIcon(getClass(), MetalLookAndFeel.class,
1227                 "icons/sortUp.png"),
1228             "Table.descendingSortIcon",
1229                 SwingUtilities2.makeIcon(getClass(), MetalLookAndFeel.class,
1230                 "icons/sortDown.png"),
1231 
1232             "TableHeader.font", userTextValue,
1233             "TableHeader.cellBorder",(LazyValue) t -> new MetalBorders.TableHeaderBorder(),
1234 
1235             // MenuBar
1236             "MenuBar.border", menuBarBorder,
1237             "MenuBar.font", menuTextValue,
1238             "MenuBar.windowBindings", new Object[] {
1239                 "F10", "takeFocus" },
1240 
1241             // Menu
1242             "Menu.border", menuItemBorder,
1243             "Menu.borderPainted", Boolean.TRUE,
1244             "Menu.menuPopupOffsetX", zero,
1245             "Menu.menuPopupOffsetY", zero,
1246             "Menu.submenuPopupOffsetX", new Integer(-4),
1247             "Menu.submenuPopupOffsetY", new Integer(-3),
1248             "Menu.font", menuTextValue,
1249             "Menu.selectionForeground", menuSelectedForeground,
1250             "Menu.selectionBackground", menuSelectedBackground,
1251             "Menu.disabledForeground", menuDisabledForeground,
1252             "Menu.acceleratorFont", subTextValue,
1253             "Menu.acceleratorForeground", acceleratorForeground,
1254             "Menu.acceleratorSelectionForeground", acceleratorSelectedForeground,
1255             "Menu.checkIcon",(LazyValue) t -> MetalIconFactory.getMenuItemCheckIcon(),
1256             "Menu.arrowIcon",(LazyValue) t -> MetalIconFactory.getMenuArrowIcon(),
1257 
1258             // Menu Item
1259             "MenuItem.border", menuItemBorder,
1260             "MenuItem.borderPainted", Boolean.TRUE,
1261             "MenuItem.font", menuTextValue,
1262             "MenuItem.selectionForeground", menuSelectedForeground,
1263             "MenuItem.selectionBackground", menuSelectedBackground,
1264             "MenuItem.disabledForeground", menuDisabledForeground,
1265             "MenuItem.acceleratorFont", subTextValue,
1266             "MenuItem.acceleratorForeground", acceleratorForeground,
1267             "MenuItem.acceleratorSelectionForeground", acceleratorSelectedForeground,
1268             "MenuItem.acceleratorDelimiter", menuItemAcceleratorDelimiter,
1269             "MenuItem.checkIcon",(LazyValue) t -> MetalIconFactory.getMenuItemCheckIcon(),
1270             "MenuItem.arrowIcon",(LazyValue) t -> MetalIconFactory.getMenuItemArrowIcon(),
1271                  // Menu Item Auditory Cue Mapping
1272             "MenuItem.commandSound", "sounds/MenuItemCommand.wav",
1273 
1274             // OptionPane.
1275             "OptionPane.windowBindings", new Object[] {
1276                 "ESCAPE", "close" },
1277             // Option Pane Auditory Cue Mappings
1278             "OptionPane.informationSound", "sounds/OptionPaneInformation.wav",
1279             "OptionPane.warningSound", "sounds/OptionPaneWarning.wav",
1280             "OptionPane.errorSound", "sounds/OptionPaneError.wav",
1281             "OptionPane.questionSound", "sounds/OptionPaneQuestion.wav",
1282 
1283             // Option Pane Special Dialog Colors, used when MetalRootPaneUI
1284             // is providing window manipulation widgets.
1285             "OptionPane.errorDialog.border.background",
1286                         new ColorUIResource(153, 51, 51),
1287             "OptionPane.errorDialog.titlePane.foreground",
1288                         new ColorUIResource(51, 0, 0),
1289             "OptionPane.errorDialog.titlePane.background",
1290                         new ColorUIResource(255, 153, 153),
1291             "OptionPane.errorDialog.titlePane.shadow",
1292                         new ColorUIResource(204, 102, 102),
1293             "OptionPane.questionDialog.border.background",
1294                         new ColorUIResource(51, 102, 51),
1295             "OptionPane.questionDialog.titlePane.foreground",
1296                         new ColorUIResource(0, 51, 0),
1297             "OptionPane.questionDialog.titlePane.background",
1298                         new ColorUIResource(153, 204, 153),
1299             "OptionPane.questionDialog.titlePane.shadow",
1300                         new ColorUIResource(102, 153, 102),
1301             "OptionPane.warningDialog.border.background",
1302                         new ColorUIResource(153, 102, 51),
1303             "OptionPane.warningDialog.titlePane.foreground",
1304                         new ColorUIResource(102, 51, 0),
1305             "OptionPane.warningDialog.titlePane.background",
1306                         new ColorUIResource(255, 204, 153),
1307             "OptionPane.warningDialog.titlePane.shadow",
1308                         new ColorUIResource(204, 153, 102),
1309             // OptionPane fonts are defined below
1310 
1311             // Separator
1312             "Separator.background", getSeparatorBackground(),
1313             "Separator.foreground", getSeparatorForeground(),
1314 
1315             // Popup Menu
1316             "PopupMenu.border", popupMenuBorder,
1317                  // Popup Menu Auditory Cue Mappings
1318             "PopupMenu.popupSound", "sounds/PopupMenuPopup.wav",
1319             "PopupMenu.font", menuTextValue,
1320 
1321             // CB & RB Menu Item
1322             "CheckBoxMenuItem.border", menuItemBorder,
1323             "CheckBoxMenuItem.borderPainted", Boolean.TRUE,
1324             "CheckBoxMenuItem.font", menuTextValue,
1325             "CheckBoxMenuItem.selectionForeground", menuSelectedForeground,
1326             "CheckBoxMenuItem.selectionBackground", menuSelectedBackground,
1327             "CheckBoxMenuItem.disabledForeground", menuDisabledForeground,
1328             "CheckBoxMenuItem.acceleratorFont", subTextValue,
1329             "CheckBoxMenuItem.acceleratorForeground", acceleratorForeground,
1330             "CheckBoxMenuItem.acceleratorSelectionForeground", acceleratorSelectedForeground,
1331             "CheckBoxMenuItem.checkIcon",(LazyValue) t -> MetalIconFactory.getCheckBoxMenuItemIcon(),
1332             "CheckBoxMenuItem.arrowIcon",(LazyValue) t -> MetalIconFactory.getMenuItemArrowIcon(),
1333             "CheckBoxMenuItem.commandSound", "sounds/MenuItemCommand.wav",
1334 
1335             "RadioButtonMenuItem.border", menuItemBorder,
1336             "RadioButtonMenuItem.borderPainted", Boolean.TRUE,
1337             "RadioButtonMenuItem.font", menuTextValue,
1338             "RadioButtonMenuItem.selectionForeground", menuSelectedForeground,
1339             "RadioButtonMenuItem.selectionBackground", menuSelectedBackground,
1340             "RadioButtonMenuItem.disabledForeground", menuDisabledForeground,
1341             "RadioButtonMenuItem.acceleratorFont", subTextValue,
1342             "RadioButtonMenuItem.acceleratorForeground", acceleratorForeground,
1343             "RadioButtonMenuItem.acceleratorSelectionForeground", acceleratorSelectedForeground,
1344             "RadioButtonMenuItem.checkIcon",(LazyValue) t -> MetalIconFactory.getRadioButtonMenuItemIcon(),
1345             "RadioButtonMenuItem.arrowIcon",(LazyValue) t -> MetalIconFactory.getMenuItemArrowIcon(),
1346             "RadioButtonMenuItem.commandSound", "sounds/MenuItemCommand.wav",
1347 
1348             "Spinner.ancestorInputMap",
1349                new UIDefaults.LazyInputMap(new Object[] {
1350                                "UP", "increment",
1351                             "KP_UP", "increment",
1352                              "DOWN", "decrement",
1353                           "KP_DOWN", "decrement",
1354                }),
1355             "Spinner.arrowButtonInsets", zeroInsets,
1356             "Spinner.border", textFieldBorder,
1357             "Spinner.arrowButtonBorder", buttonBorder,
1358             "Spinner.font", controlTextValue,
1359 
1360             // SplitPane
1361 
1362             "SplitPane.dividerSize", new Integer(10),
1363             "SplitPane.ancestorInputMap",
1364                new UIDefaults.LazyInputMap(new Object[] {
1365                         "UP", "negativeIncrement",
1366                       "DOWN", "positiveIncrement",
1367                       "LEFT", "negativeIncrement",
1368                      "RIGHT", "positiveIncrement",
1369                      "KP_UP", "negativeIncrement",
1370                    "KP_DOWN", "positiveIncrement",
1371                    "KP_LEFT", "negativeIncrement",
1372                   "KP_RIGHT", "positiveIncrement",
1373                       "HOME", "selectMin",
1374                        "END", "selectMax",
1375                         "F8", "startResize",
1376                         "F6", "toggleFocus",
1377                   "ctrl TAB", "focusOutForward",
1378             "ctrl shift TAB", "focusOutBackward"
1379                  }),
1380             "SplitPane.centerOneTouchButtons", Boolean.FALSE,
1381             "SplitPane.dividerFocusColor", primaryControl,
1382 
1383             // Tree
1384             // Tree.font was mapped to system font pre 1.4.1
1385             "Tree.font", userTextValue,
1386             "Tree.textBackground", getWindowBackground(),
1387             "Tree.selectionBorderColor", focusColor,
1388             "Tree.openIcon",(LazyValue) t -> MetalIconFactory.getTreeFolderIcon(),
1389             "Tree.closedIcon",(LazyValue) t -> MetalIconFactory.getTreeFolderIcon(),
1390             "Tree.leafIcon",(LazyValue) t -> MetalIconFactory.getTreeLeafIcon(),
1391             "Tree.expandedIcon",(LazyValue) t -> MetalIconFactory.getTreeControlIcon(Boolean.valueOf(MetalIconFactory.DARK)),
1392             "Tree.collapsedIcon",(LazyValue) t -> MetalIconFactory.getTreeControlIcon(Boolean.valueOf( MetalIconFactory.LIGHT )),
1393 
1394             "Tree.line", primaryControl, // horiz lines
1395             "Tree.hash", primaryControl,  // legs
1396             "Tree.rowHeight", zero,
1397             "Tree.focusInputMap",
1398                new UIDefaults.LazyInputMap(new Object[] {
1399                                     "ADD", "expand",
1400                                "SUBTRACT", "collapse",
1401                                  "ctrl C", "copy",
1402                                  "ctrl V", "paste",
1403                                  "ctrl X", "cut",
1404                                    "COPY", "copy",
1405                                   "PASTE", "paste",
1406                                     "CUT", "cut",
1407                          "control INSERT", "copy",
1408                            "shift INSERT", "paste",
1409                            "shift DELETE", "cut",
1410                                      "UP", "selectPrevious",
1411                                   "KP_UP", "selectPrevious",
1412                                "shift UP", "selectPreviousExtendSelection",
1413                             "shift KP_UP", "selectPreviousExtendSelection",
1414                           "ctrl shift UP", "selectPreviousExtendSelection",
1415                        "ctrl shift KP_UP", "selectPreviousExtendSelection",
1416                                 "ctrl UP", "selectPreviousChangeLead",
1417                              "ctrl KP_UP", "selectPreviousChangeLead",
1418                                    "DOWN", "selectNext",
1419                                 "KP_DOWN", "selectNext",
1420                              "shift DOWN", "selectNextExtendSelection",
1421                           "shift KP_DOWN", "selectNextExtendSelection",
1422                         "ctrl shift DOWN", "selectNextExtendSelection",
1423                      "ctrl shift KP_DOWN", "selectNextExtendSelection",
1424                               "ctrl DOWN", "selectNextChangeLead",
1425                            "ctrl KP_DOWN", "selectNextChangeLead",
1426                                   "RIGHT", "selectChild",
1427                                "KP_RIGHT", "selectChild",
1428                                    "LEFT", "selectParent",
1429                                 "KP_LEFT", "selectParent",
1430                                 "PAGE_UP", "scrollUpChangeSelection",
1431                           "shift PAGE_UP", "scrollUpExtendSelection",
1432                      "ctrl shift PAGE_UP", "scrollUpExtendSelection",
1433                            "ctrl PAGE_UP", "scrollUpChangeLead",
1434                               "PAGE_DOWN", "scrollDownChangeSelection",
1435                         "shift PAGE_DOWN", "scrollDownExtendSelection",
1436                    "ctrl shift PAGE_DOWN", "scrollDownExtendSelection",
1437                          "ctrl PAGE_DOWN", "scrollDownChangeLead",
1438                                    "HOME", "selectFirst",
1439                              "shift HOME", "selectFirstExtendSelection",
1440                         "ctrl shift HOME", "selectFirstExtendSelection",
1441                               "ctrl HOME", "selectFirstChangeLead",
1442                                     "END", "selectLast",
1443                               "shift END", "selectLastExtendSelection",
1444                          "ctrl shift END", "selectLastExtendSelection",
1445                                "ctrl END", "selectLastChangeLead",
1446                                      "F2", "startEditing",
1447                                  "ctrl A", "selectAll",
1448                              "ctrl SLASH", "selectAll",
1449                         "ctrl BACK_SLASH", "clearSelection",
1450                               "ctrl LEFT", "scrollLeft",
1451                            "ctrl KP_LEFT", "scrollLeft",
1452                              "ctrl RIGHT", "scrollRight",
1453                           "ctrl KP_RIGHT", "scrollRight",
1454                                   "SPACE", "addToSelection",
1455                              "ctrl SPACE", "toggleAndAnchor",
1456                             "shift SPACE", "extendTo",
1457                        "ctrl shift SPACE", "moveSelectionTo"
1458                  }),
1459             "Tree.ancestorInputMap",
1460                new UIDefaults.LazyInputMap(new Object[] {
1461                      "ESCAPE", "cancel"
1462                  }),
1463 
1464             // ToolBar
1465             "ToolBar.border", toolBarBorder,
1466             "ToolBar.background", menuBackground,
1467             "ToolBar.foreground", getMenuForeground(),
1468             "ToolBar.font", menuTextValue,
1469             "ToolBar.dockingBackground", menuBackground,
1470             "ToolBar.floatingBackground", menuBackground,
1471             "ToolBar.dockingForeground", primaryControlDarkShadow,
1472             "ToolBar.floatingForeground", primaryControl,
1473             "ToolBar.rolloverBorder", new MetalLazyValue(
1474                          "javax.swing.plaf.metal.MetalBorders",
1475                          "getToolBarRolloverBorder"),
1476             "ToolBar.nonrolloverBorder", new MetalLazyValue(
1477                          "javax.swing.plaf.metal.MetalBorders",
1478                          "getToolBarNonrolloverBorder"),
1479             "ToolBar.ancestorInputMap",
1480                new UIDefaults.LazyInputMap(new Object[] {
1481                         "UP", "navigateUp",
1482                      "KP_UP", "navigateUp",
1483                       "DOWN", "navigateDown",
1484                    "KP_DOWN", "navigateDown",
1485                       "LEFT", "navigateLeft",
1486                    "KP_LEFT", "navigateLeft",
1487                      "RIGHT", "navigateRight",
1488                   "KP_RIGHT", "navigateRight"
1489                  }),
1490 
1491             // RootPane
1492             "RootPane.frameBorder", new MetalLazyValue(
1493                       "javax.swing.plaf.metal.MetalBorders$FrameBorder"),
1494             "RootPane.plainDialogBorder", dialogBorder,
1495             "RootPane.informationDialogBorder", dialogBorder,
1496             "RootPane.errorDialogBorder", new MetalLazyValue(
1497                       "javax.swing.plaf.metal.MetalBorders$ErrorDialogBorder"),
1498             "RootPane.colorChooserDialogBorder", questionDialogBorder,
1499             "RootPane.fileChooserDialogBorder", questionDialogBorder,
1500             "RootPane.questionDialogBorder", questionDialogBorder,
1501             "RootPane.warningDialogBorder", new MetalLazyValue(
1502                     "javax.swing.plaf.metal.MetalBorders$WarningDialogBorder"),
1503             // These bindings are only enabled when there is a default
1504             // button set on the rootpane.
1505             "RootPane.defaultButtonWindowKeyBindings", new Object[] {
1506                              "ENTER", "press",
1507                     "released ENTER", "release",
1508                         "ctrl ENTER", "press",
1509                "ctrl released ENTER", "release"
1510               },
1511         };
1512 
1513         table.putDefaults(defaults);
1514 
1515         if (isWindows() && useSystemFonts() && theme.isSystemTheme()) {
1516             Object messageFont = new MetalFontDesktopProperty(
1517                 "win.messagebox.font.height", MetalTheme.CONTROL_TEXT_FONT);
1518 
1519             defaults = new Object[] {
1520                 "OptionPane.messageFont", messageFont,
1521                 "OptionPane.buttonFont", messageFont,
1522             };
1523             table.putDefaults(defaults);
1524         }
1525 
1526         flushUnreferenced(); // Remove old listeners
1527 
1528         boolean lafCond = SwingUtilities2.isLocalDisplay();
1529         Object aaTextInfo = SwingUtilities2.AATextInfo.getAATextInfo(lafCond);
1530         table.put(SwingUtilities2.AA_TEXT_PROPERTY_KEY, aaTextInfo);
1531         new AATextListener(this);
1532     }
1533 
1534     /**
1535      * Ensures the current {@code MetalTheme} is {@code non-null}. This is
1536      * a cover method for {@code getCurrentTheme}.
1537      *
1538      * @see #getCurrentTheme
1539      */
1540     protected void createDefaultTheme() {
1541         getCurrentTheme();
1542     }
1543 
1544     /**
1545      * Returns the look and feel defaults. This invokes, in order,
1546      * {@code createDefaultTheme()}, {@code super.getDefaults()} and
1547      * {@code getCurrentTheme().addCustomEntriesToTable(table)}.
1548      * <p>
1549      * While this method is public, it should only be invoked by the
1550      * {@code UIManager} when the look and feel is set as the current
1551      * look and feel and after {@code initialize} has been invoked.
1552      *
1553      * @return the look and feel defaults
1554      *
1555      * @see #createDefaultTheme
1556      * @see javax.swing.plaf.basic.BasicLookAndFeel#getDefaults()
1557      * @see MetalTheme#addCustomEntriesToTable(UIDefaults)
1558      */
1559     public UIDefaults getDefaults() {
1560         // PENDING: move this to initialize when API changes are allowed
1561         METAL_LOOK_AND_FEEL_INITED = true;
1562 
1563         createDefaultTheme();
1564         UIDefaults table = super.getDefaults();
1565         MetalTheme currentTheme = getCurrentTheme();
1566         currentTheme.addCustomEntriesToTable(table);
1567         currentTheme.install();
1568         return table;
1569     }
1570 
1571     /**
1572      * {@inheritDoc}
1573      *
1574      * @since 1.4
1575      */
1576     public void provideErrorFeedback(Component component) {
1577         super.provideErrorFeedback(component);
1578     }
1579 
1580     /**
1581      * Set the theme used by <code>MetalLookAndFeel</code>.
1582      * <p>
1583      * After the theme is set, {@code MetalLookAndFeel} needs to be
1584      * re-installed and the uis need to be recreated. The following
1585      * shows how to do this:
1586      * <pre>
1587      *   MetalLookAndFeel.setCurrentTheme(theme);
1588      *
1589      *   // re-install the Metal Look and Feel
1590      *   UIManager.setLookAndFeel(new MetalLookAndFeel());
1591      *
1592      *   // Update the ComponentUIs for all Components. This
1593      *   // needs to be invoked for all windows.
1594      *   SwingUtilities.updateComponentTreeUI(rootComponent);
1595      * </pre>
1596      * If this is not done the results are undefined.
1597      *
1598      * @param theme the theme to use
1599      * @throws NullPointerException if {@code theme} is {@code null}
1600      * @see #getCurrentTheme
1601      */
1602     public static void setCurrentTheme(MetalTheme theme) {
1603         // NOTE: because you need to recreate the look and feel after
1604         // this step, we don't bother blowing away any potential windows
1605         // values.
1606         if (theme == null) {
1607             throw new NullPointerException("Can't have null theme");
1608         }
1609         AppContext.getAppContext().put( "currentMetalTheme", theme );
1610     }
1611 
1612     /**
1613      * Return the theme currently being used by <code>MetalLookAndFeel</code>.
1614      * If the current theme is {@code null}, the default theme is created.
1615      *
1616      * @return the current theme
1617      * @see #setCurrentTheme
1618      * @since 1.5
1619      */
1620     public static MetalTheme getCurrentTheme() {
1621         MetalTheme currentTheme;
1622         AppContext context = AppContext.getAppContext();
1623         currentTheme = (MetalTheme) context.get( "currentMetalTheme" );
1624         if (currentTheme == null) {
1625             // This will happen in two cases:
1626             // . When MetalLookAndFeel is first being initialized.
1627             // . When a new AppContext has been created that hasn't
1628             //   triggered UIManager to load a LAF. Rather than invoke
1629             //   a method on the UIManager, which would trigger the loading
1630             //   of a potentially different LAF, we directly set the
1631             //   Theme here.
1632             if (useHighContrastTheme()) {
1633                 currentTheme = new MetalHighContrastTheme();
1634             }
1635             else {
1636                 // Create the default theme. We prefer Ocean, but will
1637                 // use DefaultMetalTheme if told to.
1638                 String theme = AccessController.doPrivileged(
1639                                new GetPropertyAction("swing.metalTheme"));
1640                 if ("steel".equals(theme)) {
1641                     currentTheme = new DefaultMetalTheme();
1642                 }
1643                 else {
1644                     currentTheme = new OceanTheme();
1645                 }
1646             }
1647             setCurrentTheme(currentTheme);
1648         }
1649         return currentTheme;
1650     }
1651 
1652     /**
1653      * Returns an <code>Icon</code> with a disabled appearance.
1654      * This method is used to generate a disabled <code>Icon</code> when
1655      * one has not been specified.  For example, if you create a
1656      * <code>JButton</code> and only specify an <code>Icon</code> via
1657      * <code>setIcon</code> this method will be called to generate the
1658      * disabled <code>Icon</code>. If null is passed as <code>icon</code>
1659      * this method returns null.
1660      * <p>
1661      * Some look and feels might not render the disabled Icon, in which
1662      * case they will ignore this.
1663      *
1664      * @param component JComponent that will display the Icon, may be null
1665      * @param icon Icon to generate disable icon from.
1666      * @return Disabled icon, or null if a suitable Icon can not be
1667      *         generated.
1668      * @since 1.5
1669      */
1670     public Icon getDisabledIcon(JComponent component, Icon icon) {
1671         if ((icon instanceof ImageIcon) && MetalLookAndFeel.usingOcean()) {
1672             return MetalUtils.getOceanDisabledButtonIcon(
1673                                   ((ImageIcon)icon).getImage());
1674         }
1675         return super.getDisabledIcon(component, icon);
1676     }
1677 
1678     /**
1679      * Returns an <code>Icon</code> for use by disabled
1680      * components that are also selected. This method is used to generate an
1681      * <code>Icon</code> for components that are in both the disabled and
1682      * selected states but do not have a specific <code>Icon</code> for this
1683      * state.  For example, if you create a <code>JButton</code> and only
1684      * specify an <code>Icon</code> via <code>setIcon</code> this method
1685      * will be called to generate the disabled and selected
1686      * <code>Icon</code>. If null is passed as <code>icon</code> this method
1687      * returns null.
1688      * <p>
1689      * Some look and feels might not render the disabled and selected Icon,
1690      * in which case they will ignore this.
1691      *
1692      * @param component JComponent that will display the Icon, may be null
1693      * @param icon Icon to generate disabled and selected icon from.
1694      * @return Disabled and Selected icon, or null if a suitable Icon can not
1695      *         be generated.
1696      * @since 1.5
1697      */
1698     public Icon getDisabledSelectedIcon(JComponent component, Icon icon) {
1699         if ((icon instanceof ImageIcon) && MetalLookAndFeel.usingOcean()) {
1700             return MetalUtils.getOceanDisabledButtonIcon(
1701                                   ((ImageIcon)icon).getImage());
1702         }
1703         return super.getDisabledSelectedIcon(component, icon);
1704     }
1705 
1706     /**
1707      * Returns the control text font of the current theme. This is a
1708      * cover method for {@code getCurrentTheme().getControlTextColor()}.
1709      *
1710      * @return the control text font
1711      *
1712      * @see MetalTheme
1713      */
1714     public static FontUIResource getControlTextFont() { return getCurrentTheme().getControlTextFont();}
1715 
1716     /**
1717      * Returns the system text font of the current theme. This is a
1718      * cover method for {@code getCurrentTheme().getSystemTextFont()}.
1719      *
1720      * @return the system text font
1721      *
1722      * @see MetalTheme
1723      */
1724     public static FontUIResource getSystemTextFont() { return getCurrentTheme().getSystemTextFont();}
1725 
1726     /**
1727      * Returns the user text font of the current theme. This is a
1728      * cover method for {@code getCurrentTheme().getUserTextFont()}.
1729      *
1730      * @return the user text font
1731      *
1732      * @see MetalTheme
1733      */
1734     public static FontUIResource getUserTextFont() { return getCurrentTheme().getUserTextFont();}
1735 
1736     /**
1737      * Returns the menu text font of the current theme. This is a
1738      * cover method for {@code getCurrentTheme().getMenuTextFont()}.
1739      *
1740      * @return the menu text font
1741      *
1742      * @see MetalTheme
1743      */
1744     public static FontUIResource getMenuTextFont() { return getCurrentTheme().getMenuTextFont();}
1745 
1746     /**
1747      * Returns the window title font of the current theme. This is a
1748      * cover method for {@code getCurrentTheme().getWindowTitleFont()}.
1749      *
1750      * @return the window title font
1751      *
1752      * @see MetalTheme
1753      */
1754     public static FontUIResource getWindowTitleFont() { return getCurrentTheme().getWindowTitleFont();}
1755 
1756     /**
1757      * Returns the sub-text font of the current theme. This is a
1758      * cover method for {@code getCurrentTheme().getSubTextFont()}.
1759      *
1760      * @return the sub-text font
1761      *
1762      * @see MetalTheme
1763      */
1764     public static FontUIResource getSubTextFont() { return getCurrentTheme().getSubTextFont();}
1765 
1766     /**
1767      * Returns the desktop color of the current theme. This is a
1768      * cover method for {@code getCurrentTheme().getDesktopColor()}.
1769      *
1770      * @return the desktop color
1771      *
1772      * @see MetalTheme
1773      */
1774     public static ColorUIResource getDesktopColor() { return getCurrentTheme().getDesktopColor(); }
1775 
1776     /**
1777      * Returns the focus color of the current theme. This is a
1778      * cover method for {@code getCurrentTheme().getFocusColor()}.
1779      *
1780      * @return the focus color
1781      *
1782      * @see MetalTheme
1783      */
1784     public static ColorUIResource getFocusColor() { return getCurrentTheme().getFocusColor(); }
1785 
1786     /**
1787      * Returns the white color of the current theme. This is a
1788      * cover method for {@code getCurrentTheme().getWhite()}.
1789      *
1790      * @return the white color
1791      *
1792      * @see MetalTheme
1793      */
1794     public static ColorUIResource getWhite() { return getCurrentTheme().getWhite(); }
1795 
1796     /**
1797      * Returns the black color of the current theme. This is a
1798      * cover method for {@code getCurrentTheme().getBlack()}.
1799      *
1800      * @return the black color
1801      *
1802      * @see MetalTheme
1803      */
1804     public static ColorUIResource getBlack() { return getCurrentTheme().getBlack(); }
1805 
1806     /**
1807      * Returns the control color of the current theme. This is a
1808      * cover method for {@code getCurrentTheme().getControl()}.
1809      *
1810      * @return the control color
1811      *
1812      * @see MetalTheme
1813      */
1814     public static ColorUIResource getControl() { return getCurrentTheme().getControl(); }
1815 
1816     /**
1817      * Returns the control shadow color of the current theme. This is a
1818      * cover method for {@code getCurrentTheme().getControlShadow()}.
1819      *
1820      * @return the control shadow color
1821      *
1822      * @see MetalTheme
1823      */
1824     public static ColorUIResource getControlShadow() { return getCurrentTheme().getControlShadow(); }
1825 
1826     /**
1827      * Returns the control dark shadow color of the current theme. This is a
1828      * cover method for {@code getCurrentTheme().getControlDarkShadow()}.
1829      *
1830      * @return the control dark shadow color
1831      *
1832      * @see MetalTheme
1833      */
1834     public static ColorUIResource getControlDarkShadow() { return getCurrentTheme().getControlDarkShadow(); }
1835 
1836     /**
1837      * Returns the control info color of the current theme. This is a
1838      * cover method for {@code getCurrentTheme().getControlInfo()}.
1839      *
1840      * @return the control info color
1841      *
1842      * @see MetalTheme
1843      */
1844     public static ColorUIResource getControlInfo() { return getCurrentTheme().getControlInfo(); }
1845 
1846     /**
1847      * Returns the control highlight color of the current theme. This is a
1848      * cover method for {@code getCurrentTheme().getControlHighlight()}.
1849      *
1850      * @return the control highlight color
1851      *
1852      * @see MetalTheme
1853      */
1854     public static ColorUIResource getControlHighlight() { return getCurrentTheme().getControlHighlight(); }
1855 
1856     /**
1857      * Returns the control disabled color of the current theme. This is a
1858      * cover method for {@code getCurrentTheme().getControlDisabled()}.
1859      *
1860      * @return the control disabled color
1861      *
1862      * @see MetalTheme
1863      */
1864     public static ColorUIResource getControlDisabled() { return getCurrentTheme().getControlDisabled(); }
1865 
1866     /**
1867      * Returns the primary control color of the current theme. This is a
1868      * cover method for {@code getCurrentTheme().getPrimaryControl()}.
1869      *
1870      * @return the primary control color
1871      *
1872      * @see MetalTheme
1873      */
1874     public static ColorUIResource getPrimaryControl() { return getCurrentTheme().getPrimaryControl(); }
1875 
1876     /**
1877      * Returns the primary control shadow color of the current theme. This is a
1878      * cover method for {@code getCurrentTheme().getPrimaryControlShadow()}.
1879      *
1880      * @return the primary control shadow color
1881      *
1882      * @see MetalTheme
1883      */
1884     public static ColorUIResource getPrimaryControlShadow() { return getCurrentTheme().getPrimaryControlShadow(); }
1885 
1886     /**
1887      * Returns the primary control dark shadow color of the current
1888      * theme. This is a cover method for {@code
1889      * getCurrentTheme().getPrimaryControlDarkShadow()}.
1890      *
1891      * @return the primary control dark shadow color
1892      *
1893      * @see MetalTheme
1894      */
1895     public static ColorUIResource getPrimaryControlDarkShadow() { return getCurrentTheme().getPrimaryControlDarkShadow(); }
1896 
1897     /**
1898      * Returns the primary control info color of the current theme. This is a
1899      * cover method for {@code getCurrentTheme().getPrimaryControlInfo()}.
1900      *
1901      * @return the primary control info color
1902      *
1903      * @see MetalTheme
1904      */
1905     public static ColorUIResource getPrimaryControlInfo() { return getCurrentTheme().getPrimaryControlInfo(); }
1906 
1907     /**
1908      * Returns the primary control highlight color of the current
1909      * theme. This is a cover method for {@code
1910      * getCurrentTheme().getPrimaryControlHighlight()}.
1911      *
1912      * @return the primary control highlight color
1913      *
1914      * @see MetalTheme
1915      */
1916     public static ColorUIResource getPrimaryControlHighlight() { return getCurrentTheme().getPrimaryControlHighlight(); }
1917 
1918     /**
1919      * Returns the system text color of the current theme. This is a
1920      * cover method for {@code getCurrentTheme().getSystemTextColor()}.
1921      *
1922      * @return the system text color
1923      *
1924      * @see MetalTheme
1925      */
1926     public static ColorUIResource getSystemTextColor() { return getCurrentTheme().getSystemTextColor(); }
1927 
1928     /**
1929      * Returns the control text color of the current theme. This is a
1930      * cover method for {@code getCurrentTheme().getControlTextColor()}.
1931      *
1932      * @return the control text color
1933      *
1934      * @see MetalTheme
1935      */
1936     public static ColorUIResource getControlTextColor() { return getCurrentTheme().getControlTextColor(); }
1937 
1938     /**
1939      * Returns the inactive control text color of the current theme. This is a
1940      * cover method for {@code
1941      * getCurrentTheme().getInactiveControlTextColor()}.
1942      *
1943      * @return the inactive control text color
1944      *
1945      * @see MetalTheme
1946      */
1947     public static ColorUIResource getInactiveControlTextColor() { return getCurrentTheme().getInactiveControlTextColor(); }
1948 
1949     /**
1950      * Returns the inactive system text color of the current theme. This is a
1951      * cover method for {@code
1952      * getCurrentTheme().getInactiveSystemTextColor()}.
1953      *
1954      * @return the inactive system text color
1955      *
1956      * @see MetalTheme
1957      */
1958     public static ColorUIResource getInactiveSystemTextColor() { return getCurrentTheme().getInactiveSystemTextColor(); }
1959 
1960     /**
1961      * Returns the user text color of the current theme. This is a
1962      * cover method for {@code getCurrentTheme().getUserTextColor()}.
1963      *
1964      * @return the user text color
1965      *
1966      * @see MetalTheme
1967      */
1968     public static ColorUIResource getUserTextColor() { return getCurrentTheme().getUserTextColor(); }
1969 
1970     /**
1971      * Returns the text highlight color of the current theme. This is a
1972      * cover method for {@code getCurrentTheme().getTextHighlightColor()}.
1973      *
1974      * @return the text highlight color
1975      *
1976      * @see MetalTheme
1977      */
1978     public static ColorUIResource getTextHighlightColor() { return getCurrentTheme().getTextHighlightColor(); }
1979 
1980     /**
1981      * Returns the highlighted text color of the current theme. This is a
1982      * cover method for {@code getCurrentTheme().getHighlightedTextColor()}.
1983      *
1984      * @return the highlighted text color
1985      *
1986      * @see MetalTheme
1987      */
1988     public static ColorUIResource getHighlightedTextColor() { return getCurrentTheme().getHighlightedTextColor(); }
1989 
1990     /**
1991      * Returns the window background color of the current theme. This is a
1992      * cover method for {@code getCurrentTheme().getWindowBackground()}.
1993      *
1994      * @return the window background color
1995      *
1996      * @see MetalTheme
1997      */
1998     public static ColorUIResource getWindowBackground() { return getCurrentTheme().getWindowBackground(); }
1999 
2000     /**
2001      * Returns the window title background color of the current
2002      * theme. This is a cover method for {@code
2003      * getCurrentTheme().getWindowTitleBackground()}.
2004      *
2005      * @return the window title background color
2006      *
2007      * @see MetalTheme
2008      */
2009     public static ColorUIResource getWindowTitleBackground() { return getCurrentTheme().getWindowTitleBackground(); }
2010 
2011     /**
2012      * Returns the window title foreground color of the current
2013      * theme. This is a cover method for {@code
2014      * getCurrentTheme().getWindowTitleForeground()}.
2015      *
2016      * @return the window title foreground color
2017      *
2018      * @see MetalTheme
2019      */
2020     public static ColorUIResource getWindowTitleForeground() { return getCurrentTheme().getWindowTitleForeground(); }
2021 
2022     /**
2023      * Returns the window title inactive background color of the current
2024      * theme. This is a cover method for {@code
2025      * getCurrentTheme().getWindowTitleInactiveBackground()}.
2026      *
2027      * @return the window title inactive background color
2028      *
2029      * @see MetalTheme
2030      */
2031     public static ColorUIResource getWindowTitleInactiveBackground() { return getCurrentTheme().getWindowTitleInactiveBackground(); }
2032 
2033     /**
2034      * Returns the window title inactive foreground color of the current
2035      * theme. This is a cover method for {@code
2036      * getCurrentTheme().getWindowTitleInactiveForeground()}.
2037      *
2038      * @return the window title inactive foreground color
2039      *
2040      * @see MetalTheme
2041      */
2042     public static ColorUIResource getWindowTitleInactiveForeground() { return getCurrentTheme().getWindowTitleInactiveForeground(); }
2043 
2044     /**
2045      * Returns the menu background color of the current theme. This is
2046      * a cover method for {@code getCurrentTheme().getMenuBackground()}.
2047      *
2048      * @return the menu background color
2049      *
2050      * @see MetalTheme
2051      */
2052     public static ColorUIResource getMenuBackground() { return getCurrentTheme().getMenuBackground(); }
2053 
2054     /**
2055      * Returns the menu foreground color of the current theme. This is
2056      * a cover method for {@code getCurrentTheme().getMenuForeground()}.
2057      *
2058      * @return the menu foreground color
2059      *
2060      * @see MetalTheme
2061      */
2062     public static ColorUIResource getMenuForeground() { return getCurrentTheme().getMenuForeground(); }
2063 
2064     /**
2065      * Returns the menu selected background color of the current theme. This is
2066      * a cover method for
2067      * {@code getCurrentTheme().getMenuSelectedBackground()}.
2068      *
2069      * @return the menu selected background color
2070      *
2071      * @see MetalTheme
2072      */
2073     public static ColorUIResource getMenuSelectedBackground() { return getCurrentTheme().getMenuSelectedBackground(); }
2074 
2075     /**
2076      * Returns the menu selected foreground color of the current theme. This is
2077      * a cover method for
2078      * {@code getCurrentTheme().getMenuSelectedForeground()}.
2079      *
2080      * @return the menu selected foreground color
2081      *
2082      * @see MetalTheme
2083      */
2084     public static ColorUIResource getMenuSelectedForeground() { return getCurrentTheme().getMenuSelectedForeground(); }
2085 
2086     /**
2087      * Returns the menu disabled foreground color of the current theme. This is
2088      * a cover method for
2089      * {@code getCurrentTheme().getMenuDisabledForeground()}.
2090      *
2091      * @return the menu disabled foreground color
2092      *
2093      * @see MetalTheme
2094      */
2095     public static ColorUIResource getMenuDisabledForeground() { return getCurrentTheme().getMenuDisabledForeground(); }
2096 
2097     /**
2098      * Returns the separator background color of the current theme. This is
2099      * a cover method for {@code getCurrentTheme().getSeparatorBackground()}.
2100      *
2101      * @return the separator background color
2102      *
2103      * @see MetalTheme
2104      */
2105     public static ColorUIResource getSeparatorBackground() { return getCurrentTheme().getSeparatorBackground(); }
2106 
2107     /**
2108      * Returns the separator foreground color of the current theme. This is
2109      * a cover method for {@code getCurrentTheme().getSeparatorForeground()}.
2110      *
2111      * @return the separator foreground color
2112      *
2113      * @see MetalTheme
2114      */
2115     public static ColorUIResource getSeparatorForeground() { return getCurrentTheme().getSeparatorForeground(); }
2116 
2117     /**
2118      * Returns the accelerator foreground color of the current theme. This is
2119      * a cover method for {@code getCurrentTheme().getAcceleratorForeground()}.
2120      *
2121      * @return the separator accelerator foreground color
2122      *
2123      * @see MetalTheme
2124      */
2125     public static ColorUIResource getAcceleratorForeground() { return getCurrentTheme().getAcceleratorForeground(); }
2126 
2127     /**
2128      * Returns the accelerator selected foreground color of the
2129      * current theme. This is a cover method for {@code
2130      * getCurrentTheme().getAcceleratorSelectedForeground()}.
2131      *
2132      * @return the accelerator selected foreground color
2133      *
2134      * @see MetalTheme
2135      */
2136     public static ColorUIResource getAcceleratorSelectedForeground() { return getCurrentTheme().getAcceleratorSelectedForeground(); }
2137 
2138 
2139     /**
2140      * Returns a {@code LayoutStyle} implementing the Java look and feel
2141      * design guidelines as specified at
2142      * <a href="http://www.oracle.com/technetwork/java/hig-136467.html">http://www.oracle.com/technetwork/java/hig-136467.html</a>.
2143      *
2144      * @return LayoutStyle implementing the Java look and feel design
2145      *         guidelines
2146      * @since 1.6
2147      */
2148     public LayoutStyle getLayoutStyle() {
2149         return MetalLayoutStyle.INSTANCE;
2150     }
2151 
2152 
2153     /**
2154      * MetalLazyValue is a slimmed down version of <code>ProxyLaxyValue</code>.
2155      * The code is duplicate so that it can get at the package private
2156      * classes in metal.
2157      */
2158     private static class MetalLazyValue implements UIDefaults.LazyValue {
2159         /**
2160          * Name of the class to create.
2161          */
2162         private String className;
2163         private String methodName;
2164 
2165         MetalLazyValue(String name) {
2166             this.className = name;
2167         }
2168 
2169         MetalLazyValue(String name, String methodName) {
2170             this(name);
2171             this.methodName = methodName;
2172         }
2173 
2174         public Object createValue(UIDefaults table) {
2175             try {
2176                 final Class c = Class.forName(className);
2177 
2178                 if (methodName == null) {
2179                     return c.newInstance();
2180                 }
2181                 Method method = AccessController.doPrivileged(
2182                     new PrivilegedAction<Method>() {
2183                     public Method run() {
2184                         Method[] methods = c.getDeclaredMethods();
2185                         for (int counter = methods.length - 1; counter >= 0;
2186                              counter--) {
2187                             if (methods[counter].getName().equals(methodName)){
2188                                 methods[counter].setAccessible(true);
2189                                 return methods[counter];
2190                             }
2191                         }
2192                         return null;
2193                     }
2194                 });
2195                 if (method != null) {
2196                     return method.invoke(null, (Object[])null);
2197                 }
2198             } catch (ClassNotFoundException cnfe) {
2199             } catch (InstantiationException ie) {
2200             } catch (IllegalAccessException iae) {
2201             } catch (InvocationTargetException ite) {
2202             }
2203             return null;
2204         }
2205     }
2206 
2207 
2208     /**
2209      * FontActiveValue redirects to the appropriate metal theme method.
2210      */
2211     private static class FontActiveValue implements UIDefaults.ActiveValue {
2212         private int type;
2213         private MetalTheme theme;
2214 
2215         FontActiveValue(MetalTheme theme, int type) {
2216             this.theme = theme;
2217             this.type = type;
2218         }
2219 
2220         public Object createValue(UIDefaults table) {
2221             Object value = null;
2222             switch (type) {
2223             case MetalTheme.CONTROL_TEXT_FONT:
2224                 value = theme.getControlTextFont();
2225                 break;
2226             case MetalTheme.SYSTEM_TEXT_FONT:
2227                 value = theme.getSystemTextFont();
2228                 break;
2229             case MetalTheme.USER_TEXT_FONT:
2230                 value = theme.getUserTextFont();
2231                 break;
2232             case MetalTheme.MENU_TEXT_FONT:
2233                 value = theme.getMenuTextFont();
2234                 break;
2235             case MetalTheme.WINDOW_TITLE_FONT:
2236                 value = theme.getWindowTitleFont();
2237                 break;
2238             case MetalTheme.SUB_TEXT_FONT:
2239                 value = theme.getSubTextFont();
2240                 break;
2241             }
2242             return value;
2243         }
2244     }
2245 
2246     static ReferenceQueue<LookAndFeel> queue = new ReferenceQueue<LookAndFeel>();
2247 
2248     static void flushUnreferenced() {
2249         AATextListener aatl;
2250         while ((aatl = (AATextListener)queue.poll()) != null) {
2251             aatl.dispose();
2252         }
2253     }
2254 
2255     static class AATextListener
2256         extends WeakReference<LookAndFeel> implements PropertyChangeListener {
2257 
2258         private String key = SunToolkit.DESKTOPFONTHINTS;
2259 
2260         AATextListener(LookAndFeel laf) {
2261             super(laf, queue);
2262             Toolkit tk = Toolkit.getDefaultToolkit();
2263             tk.addPropertyChangeListener(key, this);
2264         }
2265 
2266         public void propertyChange(PropertyChangeEvent pce) {
2267             LookAndFeel laf = get();
2268             if (laf == null || laf != UIManager.getLookAndFeel()) {
2269                 dispose();
2270                 return;
2271             }
2272             UIDefaults defaults = UIManager.getLookAndFeelDefaults();
2273             boolean lafCond = SwingUtilities2.isLocalDisplay();
2274             Object aaTextInfo =
2275                 SwingUtilities2.AATextInfo.getAATextInfo(lafCond);
2276             defaults.put(SwingUtilities2.AA_TEXT_PROPERTY_KEY, aaTextInfo);
2277             updateUI();
2278         }
2279 
2280         void dispose() {
2281             Toolkit tk = Toolkit.getDefaultToolkit();
2282             tk.removePropertyChangeListener(key, this);
2283         }
2284 
2285         /**
2286          * Updates the UI of the passed in window and all its children.
2287          */
2288         private static void updateWindowUI(Window window) {
2289             SwingUtilities.updateComponentTreeUI(window);
2290             Window ownedWins[] = window.getOwnedWindows();
2291             for (Window w : ownedWins) {
2292                 updateWindowUI(w);
2293             }
2294         }
2295 
2296         /**
2297          * Updates the UIs of all the known Frames.
2298          */
2299         private static void updateAllUIs() {
2300             Frame appFrames[] = Frame.getFrames();
2301             for (Frame frame : appFrames) {
2302                 updateWindowUI(frame);
2303             }
2304         }
2305 
2306         /**
2307          * Indicates if an updateUI call is pending.
2308          */
2309         private static boolean updatePending;
2310 
2311         /**
2312          * Sets whether or not an updateUI call is pending.
2313          */
2314         private static synchronized void setUpdatePending(boolean update) {
2315             updatePending = update;
2316         }
2317 
2318         /**
2319          * Returns true if a UI update is pending.
2320          */
2321         private static synchronized boolean isUpdatePending() {
2322             return updatePending;
2323     }
2324 
2325         protected void updateUI() {
2326             if (!isUpdatePending()) {
2327                 setUpdatePending(true);
2328                 Runnable uiUpdater = new Runnable() {
2329                         public void run() {
2330                             updateAllUIs();
2331                             setUpdatePending(false);
2332                         }
2333                     };
2334                 SwingUtilities.invokeLater(uiUpdater);
2335             }
2336         }
2337     }
2338 
2339     // From the JLF Design Guidelines:
2340     // http://www.oracle.com/technetwork/java/jlf-135985.html
2341     private static class MetalLayoutStyle extends DefaultLayoutStyle {
2342         private static MetalLayoutStyle INSTANCE = new MetalLayoutStyle();
2343 
2344         @Override
2345         public int getPreferredGap(JComponent component1,
2346                 JComponent component2, ComponentPlacement type, int position,
2347                 Container parent) {
2348             // Checks args
2349             super.getPreferredGap(component1, component2, type, position,
2350                                   parent);
2351 
2352             int offset = 0;
2353 
2354             switch(type) {
2355             case INDENT:
2356                 // Metal doesn't spec this.
2357                 if (position == SwingConstants.EAST ||
2358                         position == SwingConstants.WEST) {
2359                     int indent = getIndent(component1, position);
2360                     if (indent > 0) {
2361                         return indent;
2362                     }
2363                     return 12;
2364                 }
2365                 // Fall through to related.
2366             case RELATED:
2367                 if (component1.getUIClassID() == "ToggleButtonUI" &&
2368                         component2.getUIClassID() == "ToggleButtonUI") {
2369                     ButtonModel sourceModel = ((JToggleButton)component1).
2370                             getModel();
2371                     ButtonModel targetModel = ((JToggleButton)component2).
2372                             getModel();
2373                     if ((sourceModel instanceof DefaultButtonModel) &&
2374                         (targetModel instanceof DefaultButtonModel) &&
2375                         (((DefaultButtonModel)sourceModel).getGroup() ==
2376                          ((DefaultButtonModel)targetModel).getGroup()) &&
2377                         ((DefaultButtonModel)sourceModel).getGroup() != null) {
2378                         // When toggle buttons are exclusive (that is,
2379                         // they form a radio button set), separate
2380                         // them with 2 pixels. This rule applies
2381                         // whether the toggle buttons appear in a
2382                         // toolbar or elsewhere in the interface.
2383                         // Note: this number does not appear to
2384                         // include any borders and so is not adjusted
2385                         // by the border of the toggle button
2386                         return 2;
2387                     }
2388                     // When toggle buttons are independent (like
2389                     // checkboxes) and used outside a toolbar,
2390                     // separate them with 5 pixels.
2391                     if (usingOcean()) {
2392                         return 6;
2393                     }
2394                     return 5;
2395                 }
2396                 offset = 6;
2397                 break;
2398             case UNRELATED:
2399                 offset = 12;
2400                 break;
2401             }
2402             if (isLabelAndNonlabel(component1, component2, position)) {
2403                 // Insert 12 pixels between the trailing edge of a
2404                 // label and any associated components. Insert 12
2405                 // pixels between the trailing edge of a label and the
2406                 // component it describes when labels are
2407                 // right-aligned. When labels are left-aligned, insert
2408                 // 12 pixels between the trailing edge of the longest
2409                 // label and its associated component
2410                 return getButtonGap(component1, component2, position,
2411                                     offset + 6);
2412             }
2413             return getButtonGap(component1, component2, position, offset);
2414         }
2415 
2416         @Override
2417         public int getContainerGap(JComponent component, int position,
2418                                    Container parent) {
2419             super.getContainerGap(component, position, parent);
2420             // Include 11 pixels between the bottom and right
2421             // borders of a dialog box and its command
2422             // buttons. (To the eye, the 11-pixel spacing appears
2423             // to be 12 pixels because the white borders on the
2424             // lower and right edges of the button components are
2425             // not visually significant.)
2426             // NOTE: this last text was designed with Steel in mind,
2427             // not Ocean.
2428             //
2429             // Insert 12 pixels between the edges of the panel and the
2430             // titled border. Insert 11 pixels between the top of the
2431             // title and the component above the titled border. Insert 12
2432             // pixels between the bottom of the title and the top of the
2433             // first label in the panel. Insert 11 pixels between
2434             // component groups and between the bottom of the last
2435             // component and the lower border.
2436             return getButtonGap(component, position, 12 -
2437                                 getButtonAdjustment(component, position));
2438         }
2439 
2440         @Override
2441         protected int getButtonGap(JComponent source, JComponent target,
2442                                    int position, int offset) {
2443             offset = super.getButtonGap(source, target, position, offset);
2444             if (offset > 0) {
2445                 int buttonAdjustment = getButtonAdjustment(source, position);
2446                 if (buttonAdjustment == 0) {
2447                     buttonAdjustment = getButtonAdjustment(
2448                             target, flipDirection(position));
2449                 }
2450                 offset -= buttonAdjustment;
2451             }
2452             if (offset < 0) {
2453                 return 0;
2454             }
2455             return offset;
2456         }
2457 
2458         private int getButtonAdjustment(JComponent source, int edge) {
2459             String classID = source.getUIClassID();
2460             if (classID == "ButtonUI" || classID == "ToggleButtonUI") {
2461                 if (!usingOcean() && (edge == SwingConstants.EAST ||
2462                                       edge == SwingConstants.SOUTH)) {
2463                     if (source.getBorder() instanceof UIResource) {
2464                         return 1;
2465                     }
2466                 }
2467             }
2468             else if (edge == SwingConstants.SOUTH) {
2469                 if ((classID == "RadioButtonUI" || classID == "CheckBoxUI") &&
2470                         !usingOcean()) {
2471                     return 1;
2472                 }
2473             }
2474             return 0;
2475         }
2476     }
2477 }