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