1 /*
   2  * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package javax.swing.plaf.basic;
  27 
  28 import java.awt.Font;
  29 import java.awt.Color;
  30 import java.awt.SystemColor;
  31 import java.awt.event.*;
  32 import java.awt.Insets;
  33 import java.awt.Component;
  34 import java.awt.Container;
  35 import java.awt.FocusTraversalPolicy;
  36 import java.awt.AWTEvent;
  37 import java.awt.Toolkit;
  38 import java.awt.Point;
  39 import java.net.URL;
  40 import java.io.*;
  41 import java.awt.Dimension;
  42 import java.awt.KeyboardFocusManager;
  43 import java.security.AccessController;
  44 import java.security.PrivilegedAction;
  45 import java.util.*;
  46 import java.lang.reflect.*;
  47 import javax.sound.sampled.*;
  48 
  49 import sun.awt.AppContext;
  50 import sun.awt.SunToolkit;
  51 
  52 import sun.swing.SwingUtilities2;
  53 import sun.swing.icon.SortArrowIcon;
  54 
  55 import javax.swing.LookAndFeel;
  56 import javax.swing.AbstractAction;
  57 import javax.swing.Action;
  58 import javax.swing.ActionMap;
  59 import javax.swing.BorderFactory;
  60 import javax.swing.JComponent;
  61 import javax.swing.ImageIcon;
  62 import javax.swing.UIDefaults;
  63 import javax.swing.UIManager;
  64 import javax.swing.KeyStroke;
  65 import javax.swing.JTextField;
  66 import javax.swing.DefaultListCellRenderer;
  67 import javax.swing.FocusManager;
  68 import javax.swing.LayoutFocusTraversalPolicy;
  69 import javax.swing.SwingUtilities;
  70 import javax.swing.MenuSelectionManager;
  71 import javax.swing.MenuElement;
  72 import javax.swing.border.*;
  73 import javax.swing.plaf.*;
  74 import javax.swing.text.JTextComponent;
  75 import javax.swing.text.DefaultEditorKit;
  76 import javax.swing.JInternalFrame;
  77 import static javax.swing.UIDefaults.LazyValue;
  78 import java.beans.PropertyVetoException;
  79 import java.awt.Window;
  80 import java.beans.PropertyChangeListener;
  81 import java.beans.PropertyChangeEvent;
  82 
  83 
  84 /**
  85  * A base class to use in creating a look and feel for Swing.
  86  * <p>
  87  * Each of the {@code ComponentUI}s provided by {@code
  88  * BasicLookAndFeel} derives its behavior from the defaults
  89  * table. Unless otherwise noted each of the {@code ComponentUI}
  90  * implementations in this package document the set of defaults they
  91  * use. Unless otherwise noted the defaults are installed at the time
  92  * {@code installUI} is invoked, and follow the recommendations
  93  * outlined in {@code LookAndFeel} for installing defaults.
  94  * <p>
  95  * <strong>Warning:</strong>
  96  * Serialized objects of this class will not be compatible with
  97  * future Swing releases. The current serialization support is
  98  * appropriate for short term storage or RMI between applications running
  99  * the same version of Swing.  As of 1.4, support for long term storage
 100  * of all JavaBeans&trade;
 101  * has been added to the <code>java.beans</code> package.
 102  * Please see {@link java.beans.XMLEncoder}.
 103  *
 104  * @author unattributed
 105  */
 106 @SuppressWarnings("serial") // Same-version serialization only
 107 public abstract class BasicLookAndFeel extends LookAndFeel implements Serializable
 108 {
 109     /**
 110      * Whether or not the developer has created a JPopupMenu.
 111      */
 112     static boolean needsEventHelper;
 113 
 114     /**
 115      * Lock used when manipulating clipPlaying.
 116      */
 117     private transient Object audioLock = new Object();
 118     /**
 119      * The Clip that is currently playing (set in AudioAction).
 120      */
 121     private Clip clipPlaying;
 122 
 123     AWTEventHelper invocator = null;
 124 
 125     /*
 126      * Listen for our AppContext being disposed
 127      */
 128     private PropertyChangeListener disposer = null;
 129 
 130     /**
 131      * Returns the look and feel defaults. The returned {@code UIDefaults}
 132      * is populated by invoking, in order, {@code initClassDefaults},
 133      * {@code initSystemColorDefaults} and {@code initComponentDefaults}.
 134      * <p>
 135      * While this method is public, it should only be invoked by the
 136      * {@code UIManager} when the look and feel is set as the current
 137      * look and feel and after {@code initialize} has been invoked.
 138      *
 139      * @return the look and feel defaults
 140      *
 141      * @see #initClassDefaults
 142      * @see #initSystemColorDefaults
 143      * @see #initComponentDefaults
 144      */
 145     public UIDefaults getDefaults() {
 146         UIDefaults table = new UIDefaults(610, 0.75f);
 147 
 148         initClassDefaults(table);
 149         initSystemColorDefaults(table);
 150         initComponentDefaults(table);
 151 
 152         return table;
 153     }
 154 
 155     /**
 156      * {@inheritDoc}
 157      */
 158     public void initialize() {
 159         if (needsEventHelper) {
 160             installAWTEventListener();
 161         }
 162     }
 163 
 164     void installAWTEventListener() {
 165         if (invocator == null) {
 166             invocator = new AWTEventHelper();
 167             needsEventHelper = true;
 168 
 169             // Add a PropertyChangeListener to our AppContext so we're alerted
 170             // when the AppContext is disposed(), at which time this laf should
 171             // be uninitialize()d.
 172             disposer = new PropertyChangeListener() {
 173                 public void propertyChange(PropertyChangeEvent prpChg) {
 174                     uninitialize();
 175                 }
 176             };
 177             AppContext.getAppContext().addPropertyChangeListener(
 178                                                         AppContext.GUI_DISPOSED,
 179                                                         disposer);
 180         }
 181     }
 182 
 183     /**
 184      * {@inheritDoc}
 185      */
 186     public void uninitialize() {
 187         AppContext context = AppContext.getAppContext();
 188         synchronized (BasicPopupMenuUI.MOUSE_GRABBER_KEY) {
 189             Object grabber = context.get(BasicPopupMenuUI.MOUSE_GRABBER_KEY);
 190             if (grabber != null) {
 191                 ((BasicPopupMenuUI.MouseGrabber)grabber).uninstall();
 192             }
 193         }
 194         synchronized (BasicPopupMenuUI.MENU_KEYBOARD_HELPER_KEY) {
 195             Object helper =
 196                     context.get(BasicPopupMenuUI.MENU_KEYBOARD_HELPER_KEY);
 197             if (helper != null) {
 198                 ((BasicPopupMenuUI.MenuKeyboardHelper)helper).uninstall();
 199             }
 200         }
 201 
 202         if(invocator != null) {
 203             AccessController.doPrivileged(invocator);
 204             invocator = null;
 205         }
 206 
 207         if (disposer != null) {
 208             // Note that we're likely calling removePropertyChangeListener()
 209             // during the course of AppContext.firePropertyChange().
 210             // However, EventListenerAggreggate has code to safely modify
 211             // the list under such circumstances.
 212             context.removePropertyChangeListener(AppContext.GUI_DISPOSED,
 213                                                  disposer);
 214             disposer = null;
 215         }
 216     }
 217 
 218     /**
 219      * Populates {@code table} with mappings from {@code uiClassID} to the
 220      * fully qualified name of the ui class. The value for a
 221      * particular {@code uiClassID} is {@code
 222      * "javax.swing.plaf.basic.Basic + uiClassID"}. For example, the
 223      * value for the {@code uiClassID} {@code TreeUI} is {@code
 224      * "javax.swing.plaf.basic.BasicTreeUI"}.
 225      *
 226      * @param table the {@code UIDefaults} instance the entries are
 227      *        added to
 228      * @throws NullPointerException if {@code table} is {@code null}
 229      *
 230      * @see javax.swing.LookAndFeel
 231      * @see #getDefaults
 232      */
 233     protected void initClassDefaults(UIDefaults table)
 234     {
 235         final String basicPackageName = "javax.swing.plaf.basic.";
 236         Object[] uiDefaults = {
 237                    "ButtonUI", basicPackageName + "BasicButtonUI",
 238                  "CheckBoxUI", basicPackageName + "BasicCheckBoxUI",
 239              "ColorChooserUI", basicPackageName + "BasicColorChooserUI",
 240        "FormattedTextFieldUI", basicPackageName + "BasicFormattedTextFieldUI",
 241                   "MenuBarUI", basicPackageName + "BasicMenuBarUI",
 242                      "MenuUI", basicPackageName + "BasicMenuUI",
 243                  "MenuItemUI", basicPackageName + "BasicMenuItemUI",
 244          "CheckBoxMenuItemUI", basicPackageName + "BasicCheckBoxMenuItemUI",
 245       "RadioButtonMenuItemUI", basicPackageName + "BasicRadioButtonMenuItemUI",
 246               "RadioButtonUI", basicPackageName + "BasicRadioButtonUI",
 247              "ToggleButtonUI", basicPackageName + "BasicToggleButtonUI",
 248                 "PopupMenuUI", basicPackageName + "BasicPopupMenuUI",
 249               "ProgressBarUI", basicPackageName + "BasicProgressBarUI",
 250                 "ScrollBarUI", basicPackageName + "BasicScrollBarUI",
 251                "ScrollPaneUI", basicPackageName + "BasicScrollPaneUI",
 252                 "SplitPaneUI", basicPackageName + "BasicSplitPaneUI",
 253                    "SliderUI", basicPackageName + "BasicSliderUI",
 254                 "SeparatorUI", basicPackageName + "BasicSeparatorUI",
 255                   "SpinnerUI", basicPackageName + "BasicSpinnerUI",
 256          "ToolBarSeparatorUI", basicPackageName + "BasicToolBarSeparatorUI",
 257        "PopupMenuSeparatorUI", basicPackageName + "BasicPopupMenuSeparatorUI",
 258                "TabbedPaneUI", basicPackageName + "BasicTabbedPaneUI",
 259                  "TextAreaUI", basicPackageName + "BasicTextAreaUI",
 260                 "TextFieldUI", basicPackageName + "BasicTextFieldUI",
 261             "PasswordFieldUI", basicPackageName + "BasicPasswordFieldUI",
 262                  "TextPaneUI", basicPackageName + "BasicTextPaneUI",
 263                "EditorPaneUI", basicPackageName + "BasicEditorPaneUI",
 264                      "TreeUI", basicPackageName + "BasicTreeUI",
 265                     "LabelUI", basicPackageName + "BasicLabelUI",
 266                      "ListUI", basicPackageName + "BasicListUI",
 267                   "ToolBarUI", basicPackageName + "BasicToolBarUI",
 268                   "ToolTipUI", basicPackageName + "BasicToolTipUI",
 269                  "ComboBoxUI", basicPackageName + "BasicComboBoxUI",
 270                     "TableUI", basicPackageName + "BasicTableUI",
 271               "TableHeaderUI", basicPackageName + "BasicTableHeaderUI",
 272             "InternalFrameUI", basicPackageName + "BasicInternalFrameUI",
 273               "DesktopPaneUI", basicPackageName + "BasicDesktopPaneUI",
 274               "DesktopIconUI", basicPackageName + "BasicDesktopIconUI",
 275               "FileChooserUI", basicPackageName + "BasicFileChooserUI",
 276                "OptionPaneUI", basicPackageName + "BasicOptionPaneUI",
 277                     "PanelUI", basicPackageName + "BasicPanelUI",
 278                  "ViewportUI", basicPackageName + "BasicViewportUI",
 279                  "RootPaneUI", basicPackageName + "BasicRootPaneUI",
 280         };
 281 
 282         table.putDefaults(uiDefaults);
 283     }
 284 
 285     /**
 286      * Populates {@code table} with system colors. This creates an
 287      * array of {@code name-color} pairs and invokes {@code
 288      * loadSystemColors}.
 289      * <p>
 290      * The name is a {@code String} that corresponds to the name of
 291      * one of the static {@code SystemColor} fields in the {@code
 292      * SystemColor} class.  A name-color pair is created for every
 293      * such {@code SystemColor} field.
 294      * <p>
 295      * The {@code color} corresponds to a hex {@code String} as
 296      * understood by {@code Color.decode}. For example, one of the
 297      * {@code name-color} pairs is {@code
 298      * "desktop"-"#005C5C"}. This corresponds to the {@code
 299      * SystemColor} field {@code desktop}, with a color value of
 300      * {@code new Color(0x005C5C)}.
 301      * <p>
 302      * The following shows two of the {@code name-color} pairs:
 303      * <pre>
 304      *   String[] nameColorPairs = new String[] {
 305      *          "desktop", "#005C5C",
 306      *    "activeCaption", "#000080" };
 307      *   loadSystemColors(table, nameColorPairs, isNativeLookAndFeel());
 308      * </pre>
 309      *
 310      * As previously stated, this invokes {@code loadSystemColors}
 311      * with the supplied {@code table} and {@code name-color} pair
 312      * array. The last argument to {@code loadSystemColors} indicates
 313      * whether the value of the field in {@code SystemColor} should be
 314      * used. This method passes the value of {@code
 315      * isNativeLookAndFeel()} as the last argument to {@code loadSystemColors}.
 316      *
 317      * @param table the {@code UIDefaults} object the values are added to
 318      * @throws NullPointerException if {@code table} is {@code null}
 319      *
 320      * @see java.awt.SystemColor
 321      * @see #getDefaults
 322      * @see #loadSystemColors
 323      */
 324     protected void initSystemColorDefaults(UIDefaults table)
 325     {
 326         String[] defaultSystemColors = {
 327                 "desktop", "#005C5C", /* Color of the desktop background */
 328           "activeCaption", "#000080", /* Color for captions (title bars) when they are active. */
 329       "activeCaptionText", "#FFFFFF", /* Text color for text in captions (title bars). */
 330     "activeCaptionBorder", "#C0C0C0", /* Border color for caption (title bar) window borders. */
 331         "inactiveCaption", "#808080", /* Color for captions (title bars) when not active. */
 332     "inactiveCaptionText", "#C0C0C0", /* Text color for text in inactive captions (title bars). */
 333   "inactiveCaptionBorder", "#C0C0C0", /* Border color for inactive caption (title bar) window borders. */
 334                  "window", "#FFFFFF", /* Default color for the interior of windows */
 335            "windowBorder", "#000000", /* ??? */
 336              "windowText", "#000000", /* ??? */
 337                    "menu", "#C0C0C0", /* Background color for menus */
 338                "menuText", "#000000", /* Text color for menus  */
 339                    "text", "#C0C0C0", /* Text background color */
 340                "textText", "#000000", /* Text foreground color */
 341           "textHighlight", "#000080", /* Text background color when selected */
 342       "textHighlightText", "#FFFFFF", /* Text color when selected */
 343        "textInactiveText", "#808080", /* Text color when disabled */
 344                 "control", "#C0C0C0", /* Default color for controls (buttons, sliders, etc) */
 345             "controlText", "#000000", /* Default color for text in controls */
 346        "controlHighlight", "#C0C0C0", /* Specular highlight (opposite of the shadow) */
 347      "controlLtHighlight", "#FFFFFF", /* Highlight color for controls */
 348           "controlShadow", "#808080", /* Shadow color for controls */
 349         "controlDkShadow", "#000000", /* Dark shadow color for controls */
 350               "scrollbar", "#E0E0E0", /* Scrollbar background (usually the "track") */
 351                    "info", "#FFFFE1", /* ??? */
 352                "infoText", "#000000"  /* ??? */
 353         };
 354 
 355         loadSystemColors(table, defaultSystemColors, isNativeLookAndFeel());
 356     }
 357 
 358 
 359     /**
 360      * Populates {@code table} with the {@code name-color} pairs in
 361      * {@code systemColors}. Refer to
 362      * {@link #initSystemColorDefaults(UIDefaults)} for details on
 363      * the format of {@code systemColors}.
 364      * <p>
 365      * An entry is added to {@code table} for each of the {@code name-color}
 366      * pairs in {@code systemColors}. The entry key is
 367      * the {@code name} of the {@code name-color} pair.
 368      * <p>
 369      * The value of the entry corresponds to the {@code color} of the
 370      * {@code name-color} pair.  The value of the entry is calculated
 371      * in one of two ways. With either approach the value is always a
 372      * {@code ColorUIResource}.
 373      * <p>
 374      * If {@code useNative} is {@code false}, the {@code color} is
 375      * created by using {@code Color.decode} to convert the {@code
 376      * String} into a {@code Color}. If {@code decode} can not convert
 377      * the {@code String} into a {@code Color} ({@code
 378      * NumberFormatException} is thrown) then a {@code
 379      * ColorUIResource} of black is used.
 380      * <p>
 381      * If {@code useNative} is {@code true}, the {@code color} is the
 382      * value of the field in {@code SystemColor} with the same name as
 383      * the {@code name} of the {@code name-color} pair. If the field
 384      * is not valid, a {@code ColorUIResource} of black is used.
 385      *
 386      * @param table the {@code UIDefaults} object the values are added to
 387      * @param systemColors array of {@code name-color} pairs as described
 388      *        in {@link #initSystemColorDefaults(UIDefaults)}
 389      * @param useNative whether the color is obtained from {@code SystemColor}
 390      *        or {@code Color.decode}
 391      * @throws NullPointerException if {@code systemColors} is {@code null}; or
 392      *         {@code systemColors} is not empty, and {@code table} is
 393      *         {@code null}; or one of the
 394      *         names of the {@code name-color} pairs is {@code null}; or
 395      *         {@code useNative} is {@code false} and one of the
 396      *         {@code colors} of the {@code name-color} pairs is {@code null}
 397      * @throws ArrayIndexOutOfBoundsException if {@code useNative} is
 398      *         {@code false} and {@code systemColors.length} is odd
 399      *
 400      * @see #initSystemColorDefaults(javax.swing.UIDefaults)
 401      * @see java.awt.SystemColor
 402      * @see java.awt.Color#decode(String)
 403      */
 404     protected void loadSystemColors(UIDefaults table, String[] systemColors, boolean useNative)
 405     {
 406         /* PENDING(hmuller) We don't load the system colors below because
 407          * they're not reliable.  Hopefully we'll be able to do better in
 408          * a future version of AWT.
 409          */
 410         if (useNative) {
 411             for(int i = 0; i < systemColors.length; i += 2) {
 412                 Color color = Color.black;
 413                 try {
 414                     String name = systemColors[i];
 415                     color = (Color)(SystemColor.class.getField(name).get(null));
 416                 } catch (Exception e) {
 417                 }
 418                 table.put(systemColors[i], new ColorUIResource(color));
 419             }
 420         } else {
 421             for(int i = 0; i < systemColors.length; i += 2) {
 422                 Color color = Color.black;
 423                 try {
 424                     color = Color.decode(systemColors[i + 1]);
 425                 }
 426                 catch(NumberFormatException e) {
 427                     e.printStackTrace();
 428                 }
 429                 table.put(systemColors[i], new ColorUIResource(color));
 430             }
 431         }
 432     }
 433     /**
 434      * Initialize the defaults table with the name of the ResourceBundle
 435      * used for getting localized defaults.  Also initialize the default
 436      * locale used when no locale is passed into UIDefaults.get().  The
 437      * default locale should generally not be relied upon. It is here for
 438      * compatibility with releases prior to 1.4.
 439      */
 440     private void initResourceBundle(UIDefaults table) {
 441         table.setDefaultLocale( Locale.getDefault() );
 442         table.addResourceBundle( "com.sun.swing.internal.plaf.basic.resources.basic" );
 443     }
 444 
 445     /**
 446      * Populates {@code table} with the defaults for the basic look and
 447      * feel.
 448      *
 449      * @param table the {@code UIDefaults} to add the values to
 450      * @throws NullPointerException if {@code table} is {@code null}
 451      */
 452     protected void initComponentDefaults(UIDefaults table)
 453     {
 454 
 455         initResourceBundle(table);
 456 
 457         // *** Shared Integers
 458         Integer fiveHundred = new Integer(500);
 459 
 460         // *** Shared Longs
 461         Long oneThousand = new Long(1000);
 462 
 463         LazyValue dialogPlain12 = t ->
 464             new FontUIResource(Font.DIALOG, Font.PLAIN, 12);
 465         LazyValue serifPlain12 = t ->
 466             new FontUIResource(Font.SERIF, Font.PLAIN, 12);
 467         LazyValue sansSerifPlain12 =  t ->
 468             new FontUIResource(Font.SANS_SERIF, Font.PLAIN, 12);
 469         LazyValue monospacedPlain12 = t ->
 470             new FontUIResource(Font.MONOSPACED, Font.PLAIN, 12);
 471         LazyValue dialogBold12 = t ->
 472             new FontUIResource(Font.DIALOG, Font.BOLD, 12);
 473 
 474 
 475         // *** Shared Colors
 476         ColorUIResource red = new ColorUIResource(Color.red);
 477         ColorUIResource black = new ColorUIResource(Color.black);
 478         ColorUIResource white = new ColorUIResource(Color.white);
 479         ColorUIResource yellow = new ColorUIResource(Color.yellow);
 480         ColorUIResource gray = new ColorUIResource(Color.gray);
 481         ColorUIResource lightGray = new ColorUIResource(Color.lightGray);
 482         ColorUIResource darkGray = new ColorUIResource(Color.darkGray);
 483         ColorUIResource scrollBarTrack = new ColorUIResource(224, 224, 224);
 484 
 485         Color control = table.getColor("control");
 486         Color controlDkShadow = table.getColor("controlDkShadow");
 487         Color controlHighlight = table.getColor("controlHighlight");
 488         Color controlLtHighlight = table.getColor("controlLtHighlight");
 489         Color controlShadow = table.getColor("controlShadow");
 490         Color controlText = table.getColor("controlText");
 491         Color menu = table.getColor("menu");
 492         Color menuText = table.getColor("menuText");
 493         Color textHighlight = table.getColor("textHighlight");
 494         Color textHighlightText = table.getColor("textHighlightText");
 495         Color textInactiveText = table.getColor("textInactiveText");
 496         Color textText = table.getColor("textText");
 497         Color window = table.getColor("window");
 498 
 499         // *** Shared Insets
 500         InsetsUIResource zeroInsets = new InsetsUIResource(0,0,0,0);
 501         InsetsUIResource twoInsets = new InsetsUIResource(2,2,2,2);
 502         InsetsUIResource threeInsets = new InsetsUIResource(3,3,3,3);
 503 
 504         // *** Shared Borders
 505         LazyValue marginBorder = t -> new BasicBorders.MarginBorder();
 506         LazyValue etchedBorder = t ->
 507             BorderUIResource.getEtchedBorderUIResource();
 508         LazyValue loweredBevelBorder = t ->
 509             BorderUIResource.getLoweredBevelBorderUIResource();
 510 
 511         LazyValue popupMenuBorder = t -> BasicBorders.getInternalFrameBorder();
 512 
 513         LazyValue blackLineBorder = t ->
 514             BorderUIResource.getBlackLineBorderUIResource();
 515         LazyValue focusCellHighlightBorder = t ->
 516             new BorderUIResource.LineBorderUIResource(yellow);
 517 
 518         Object noFocusBorder = new BorderUIResource.EmptyBorderUIResource(1,1,1,1);
 519 
 520         LazyValue tableHeaderBorder = t ->
 521             new BorderUIResource.BevelBorderUIResource(
 522                     BevelBorder.RAISED,
 523                                          controlLtHighlight,
 524                                          control,
 525                                          controlDkShadow,
 526                     controlShadow);
 527 
 528 
 529         // *** Button value objects
 530 
 531         LazyValue buttonBorder =
 532             t -> BasicBorders.getButtonBorder();
 533 
 534         LazyValue buttonToggleBorder =
 535             t -> BasicBorders.getToggleButtonBorder();
 536 
 537         LazyValue radioButtonBorder =
 538             t -> BasicBorders.getRadioButtonBorder();
 539 
 540         // *** FileChooser / FileView value objects
 541 
 542         Object newFolderIcon = SwingUtilities2.makeIcon(getClass(),
 543                                                         BasicLookAndFeel.class,
 544                                                         "icons/NewFolder.gif");
 545         Object upFolderIcon = SwingUtilities2.makeIcon(getClass(),
 546                                                        BasicLookAndFeel.class,
 547                                                        "icons/UpFolder.gif");
 548         Object homeFolderIcon = SwingUtilities2.makeIcon(getClass(),
 549                                                          BasicLookAndFeel.class,
 550                                                          "icons/HomeFolder.gif");
 551         Object detailsViewIcon = SwingUtilities2.makeIcon(getClass(),
 552                                                           BasicLookAndFeel.class,
 553                                                           "icons/DetailsView.gif");
 554         Object listViewIcon = SwingUtilities2.makeIcon(getClass(),
 555                                                        BasicLookAndFeel.class,
 556                                                        "icons/ListView.gif");
 557         Object directoryIcon = SwingUtilities2.makeIcon(getClass(),
 558                                                         BasicLookAndFeel.class,
 559                                                         "icons/Directory.gif");
 560         Object fileIcon = SwingUtilities2.makeIcon(getClass(),
 561                                                    BasicLookAndFeel.class,
 562                                                    "icons/File.gif");
 563         Object computerIcon = SwingUtilities2.makeIcon(getClass(),
 564                                                        BasicLookAndFeel.class,
 565                                                        "icons/Computer.gif");
 566         Object hardDriveIcon = SwingUtilities2.makeIcon(getClass(),
 567                                                         BasicLookAndFeel.class,
 568                                                         "icons/HardDrive.gif");
 569         Object floppyDriveIcon = SwingUtilities2.makeIcon(getClass(),
 570                                                           BasicLookAndFeel.class,
 571                                                           "icons/FloppyDrive.gif");
 572 
 573 
 574         // *** InternalFrame value objects
 575 
 576         LazyValue internalFrameBorder = t ->
 577             BasicBorders.getInternalFrameBorder();
 578 
 579         // *** List value objects
 580 
 581         Object listCellRendererActiveValue = new UIDefaults.ActiveValue() {
 582             public Object createValue(UIDefaults table) {
 583                 return new DefaultListCellRenderer.UIResource();
 584             }
 585         };
 586 
 587 
 588         // *** Menus value objects
 589 
 590         LazyValue menuBarBorder =
 591             t -> BasicBorders.getMenuBarBorder();
 592 
 593         LazyValue menuItemCheckIcon =
 594             t -> BasicIconFactory.getMenuItemCheckIcon();
 595 
 596         LazyValue menuItemArrowIcon =
 597             t -> BasicIconFactory.getMenuItemArrowIcon();
 598 
 599 
 600         LazyValue menuArrowIcon =
 601             t -> BasicIconFactory.getMenuArrowIcon();
 602 
 603         LazyValue checkBoxIcon =
 604             t -> BasicIconFactory.getCheckBoxIcon();
 605 
 606         LazyValue radioButtonIcon =
 607             t -> BasicIconFactory.getRadioButtonIcon();
 608 
 609         LazyValue checkBoxMenuItemIcon =
 610             t -> BasicIconFactory.getCheckBoxMenuItemIcon();
 611 
 612         LazyValue radioButtonMenuItemIcon =
 613             t -> BasicIconFactory.getRadioButtonMenuItemIcon();
 614 
 615         Object menuItemAcceleratorDelimiter = "+";
 616 
 617         // *** OptionPane value objects
 618 
 619         Object optionPaneMinimumSize = new DimensionUIResource(262, 90);
 620 
 621         int zero =  0;
 622         LazyValue zeroBorder = t ->
 623             new BorderUIResource.EmptyBorderUIResource(zero, zero, zero, zero);
 624 
 625         int ten = 10;
 626         LazyValue optionPaneBorder = t ->
 627             new BorderUIResource.EmptyBorderUIResource(ten, ten, 12, ten);
 628 
 629         LazyValue optionPaneButtonAreaBorder = t ->
 630             new BorderUIResource.EmptyBorderUIResource(6, zero, zero, zero);
 631 
 632 
 633         // *** ProgessBar value objects
 634 
 635         LazyValue progressBarBorder =
 636             t -> BasicBorders.getProgressBarBorder();
 637 
 638         // ** ScrollBar value objects
 639 
 640         Object minimumThumbSize = new DimensionUIResource(8,8);
 641         Object maximumThumbSize = new DimensionUIResource(4096,4096);
 642 
 643         // ** Slider value objects
 644 
 645         Object sliderFocusInsets = twoInsets;
 646 
 647         Object toolBarSeparatorSize = new DimensionUIResource( 10, 10 );
 648 
 649 
 650         // *** SplitPane value objects
 651 
 652         LazyValue splitPaneBorder =
 653             t -> BasicBorders.getSplitPaneBorder();
 654         LazyValue splitPaneDividerBorder =
 655             t -> BasicBorders.getSplitPaneDividerBorder();
 656 
 657         // ** TabbedBane value objects
 658 
 659         Object tabbedPaneTabInsets = new InsetsUIResource(0, 4, 1, 4);
 660 
 661         Object tabbedPaneTabPadInsets = new InsetsUIResource(2, 2, 2, 1);
 662 
 663         Object tabbedPaneTabAreaInsets = new InsetsUIResource(3, 2, 0, 2);
 664 
 665         Object tabbedPaneContentBorderInsets = new InsetsUIResource(2, 2, 3, 3);
 666 
 667 
 668         // *** Text value objects
 669 
 670         LazyValue textFieldBorder =
 671             t -> BasicBorders.getTextFieldBorder();
 672 
 673         Object editorMargin = threeInsets;
 674 
 675         Object caretBlinkRate = fiveHundred;
 676         Integer four = new Integer(4);
 677 
 678         Object[] allAuditoryCues = new Object[] {
 679                 "CheckBoxMenuItem.commandSound",
 680                 "InternalFrame.closeSound",
 681                 "InternalFrame.maximizeSound",
 682                 "InternalFrame.minimizeSound",
 683                 "InternalFrame.restoreDownSound",
 684                 "InternalFrame.restoreUpSound",
 685                 "MenuItem.commandSound",
 686                 "OptionPane.errorSound",
 687                 "OptionPane.informationSound",
 688                 "OptionPane.questionSound",
 689                 "OptionPane.warningSound",
 690                 "PopupMenu.popupSound",
 691                 "RadioButtonMenuItem.commandSound"};
 692 
 693         Object[] noAuditoryCues = new Object[] {"mute"};
 694 
 695         // *** Component Defaults
 696 
 697         Object[] defaults = {
 698             // *** Auditory Feedback
 699             "AuditoryCues.cueList", allAuditoryCues,
 700             "AuditoryCues.allAuditoryCues", allAuditoryCues,
 701             "AuditoryCues.noAuditoryCues", noAuditoryCues,
 702             // this key defines which of the various cues to render.
 703             // L&Fs that want auditory feedback NEED to override playList.
 704             "AuditoryCues.playList", null,
 705 
 706             // *** Buttons
 707             "Button.defaultButtonFollowsFocus", Boolean.TRUE,
 708             "Button.font", dialogPlain12,
 709             "Button.background", control,
 710             "Button.foreground", controlText,
 711             "Button.shadow", controlShadow,
 712             "Button.darkShadow", controlDkShadow,
 713             "Button.light", controlHighlight,
 714             "Button.highlight", controlLtHighlight,
 715             "Button.border", buttonBorder,
 716             "Button.margin", new InsetsUIResource(2, 14, 2, 14),
 717             "Button.textIconGap", four,
 718             "Button.textShiftOffset", zero,
 719             "Button.focusInputMap", new UIDefaults.LazyInputMap(new Object[] {
 720                          "SPACE", "pressed",
 721                 "released SPACE", "released",
 722                          "ENTER", "pressed",
 723                 "released ENTER", "released"
 724               }),
 725 
 726             "ToggleButton.font", dialogPlain12,
 727             "ToggleButton.background", control,
 728             "ToggleButton.foreground", controlText,
 729             "ToggleButton.shadow", controlShadow,
 730             "ToggleButton.darkShadow", controlDkShadow,
 731             "ToggleButton.light", controlHighlight,
 732             "ToggleButton.highlight", controlLtHighlight,
 733             "ToggleButton.border", buttonToggleBorder,
 734             "ToggleButton.margin", new InsetsUIResource(2, 14, 2, 14),
 735             "ToggleButton.textIconGap", four,
 736             "ToggleButton.textShiftOffset", zero,
 737             "ToggleButton.focusInputMap",
 738               new UIDefaults.LazyInputMap(new Object[] {
 739                             "SPACE", "pressed",
 740                    "released SPACE", "released"
 741                 }),
 742 
 743             "RadioButton.font", dialogPlain12,
 744             "RadioButton.background", control,
 745             "RadioButton.foreground", controlText,
 746             "RadioButton.shadow", controlShadow,
 747             "RadioButton.darkShadow", controlDkShadow,
 748             "RadioButton.light", controlHighlight,
 749             "RadioButton.highlight", controlLtHighlight,
 750             "RadioButton.border", radioButtonBorder,
 751             "RadioButton.margin", twoInsets,
 752             "RadioButton.textIconGap", four,
 753             "RadioButton.textShiftOffset", zero,
 754             "RadioButton.icon", radioButtonIcon,
 755             "RadioButton.focusInputMap",
 756                new UIDefaults.LazyInputMap(new Object[] {
 757                           "SPACE", "pressed",
 758                  "released SPACE", "released",
 759                          "RETURN", "pressed"
 760               }),
 761 
 762             "CheckBox.font", dialogPlain12,
 763             "CheckBox.background", control,
 764             "CheckBox.foreground", controlText,
 765             "CheckBox.border", radioButtonBorder,
 766             "CheckBox.margin", twoInsets,
 767             "CheckBox.textIconGap", four,
 768             "CheckBox.textShiftOffset", zero,
 769             "CheckBox.icon", checkBoxIcon,
 770             "CheckBox.focusInputMap",
 771                new UIDefaults.LazyInputMap(new Object[] {
 772                             "SPACE", "pressed",
 773                    "released SPACE", "released"
 774                  }),
 775             "FileChooser.useSystemExtensionHiding", Boolean.FALSE,
 776 
 777             // *** ColorChooser
 778             "ColorChooser.font", dialogPlain12,
 779             "ColorChooser.background", control,
 780             "ColorChooser.foreground", controlText,
 781 
 782             "ColorChooser.swatchesSwatchSize", new Dimension(10, 10),
 783             "ColorChooser.swatchesRecentSwatchSize", new Dimension(10, 10),
 784             "ColorChooser.swatchesDefaultRecentColor", control,
 785 
 786             // *** ComboBox
 787             "ComboBox.font", sansSerifPlain12,
 788             "ComboBox.background", window,
 789             "ComboBox.foreground", textText,
 790             "ComboBox.buttonBackground", control,
 791             "ComboBox.buttonShadow", controlShadow,
 792             "ComboBox.buttonDarkShadow", controlDkShadow,
 793             "ComboBox.buttonHighlight", controlLtHighlight,
 794             "ComboBox.selectionBackground", textHighlight,
 795             "ComboBox.selectionForeground", textHighlightText,
 796             "ComboBox.disabledBackground", control,
 797             "ComboBox.disabledForeground", textInactiveText,
 798             "ComboBox.timeFactor", oneThousand,
 799             "ComboBox.isEnterSelectablePopup", Boolean.FALSE,
 800             "ComboBox.ancestorInputMap",
 801                new UIDefaults.LazyInputMap(new Object[] {
 802                       "ESCAPE", "hidePopup",
 803                      "PAGE_UP", "pageUpPassThrough",
 804                    "PAGE_DOWN", "pageDownPassThrough",
 805                         "HOME", "homePassThrough",
 806                          "END", "endPassThrough",
 807                        "ENTER", "enterPressed"
 808                  }),
 809             "ComboBox.noActionOnKeyNavigation", Boolean.FALSE,
 810 
 811             // *** FileChooser
 812 
 813             "FileChooser.newFolderIcon", newFolderIcon,
 814             "FileChooser.upFolderIcon", upFolderIcon,
 815             "FileChooser.homeFolderIcon", homeFolderIcon,
 816             "FileChooser.detailsViewIcon", detailsViewIcon,
 817             "FileChooser.listViewIcon", listViewIcon,
 818             "FileChooser.readOnly", Boolean.FALSE,
 819             "FileChooser.usesSingleFilePane", Boolean.FALSE,
 820             "FileChooser.ancestorInputMap",
 821                new UIDefaults.LazyInputMap(new Object[] {
 822                      "ESCAPE", "cancelSelection",
 823                      "F5", "refresh",
 824                  }),
 825 
 826             "FileView.directoryIcon", directoryIcon,
 827             "FileView.fileIcon", fileIcon,
 828             "FileView.computerIcon", computerIcon,
 829             "FileView.hardDriveIcon", hardDriveIcon,
 830             "FileView.floppyDriveIcon", floppyDriveIcon,
 831 
 832             // *** InternalFrame
 833             "InternalFrame.titleFont", dialogBold12,
 834             "InternalFrame.borderColor", control,
 835             "InternalFrame.borderShadow", controlShadow,
 836             "InternalFrame.borderDarkShadow", controlDkShadow,
 837             "InternalFrame.borderHighlight", controlLtHighlight,
 838             "InternalFrame.borderLight", controlHighlight,
 839             "InternalFrame.border", internalFrameBorder,
 840             "InternalFrame.icon",   SwingUtilities2.makeIcon(getClass(),
 841                                                              BasicLookAndFeel.class,
 842                                                              "icons/JavaCup16.png"),
 843 
 844             /* Default frame icons are undefined for Basic. */
 845             "InternalFrame.maximizeIcon",
 846                (LazyValue) t -> BasicIconFactory.createEmptyFrameIcon(),
 847             "InternalFrame.minimizeIcon",
 848                (LazyValue) t -> BasicIconFactory.createEmptyFrameIcon(),
 849             "InternalFrame.iconifyIcon",
 850                (LazyValue) t -> BasicIconFactory.createEmptyFrameIcon(),
 851             "InternalFrame.closeIcon",
 852                (LazyValue) t -> BasicIconFactory.createEmptyFrameIcon(),
 853             // InternalFrame Auditory Cue Mappings
 854             "InternalFrame.closeSound", null,
 855             "InternalFrame.maximizeSound", null,
 856             "InternalFrame.minimizeSound", null,
 857             "InternalFrame.restoreDownSound", null,
 858             "InternalFrame.restoreUpSound", null,
 859 
 860             "InternalFrame.activeTitleBackground", table.get("activeCaption"),
 861             "InternalFrame.activeTitleForeground", table.get("activeCaptionText"),
 862             "InternalFrame.inactiveTitleBackground", table.get("inactiveCaption"),
 863             "InternalFrame.inactiveTitleForeground", table.get("inactiveCaptionText"),
 864             "InternalFrame.windowBindings", new Object[] {
 865               "shift ESCAPE", "showSystemMenu",
 866                 "ctrl SPACE", "showSystemMenu",
 867                     "ESCAPE", "hideSystemMenu"},
 868 
 869             "InternalFrameTitlePane.iconifyButtonOpacity", Boolean.TRUE,
 870             "InternalFrameTitlePane.maximizeButtonOpacity", Boolean.TRUE,
 871             "InternalFrameTitlePane.closeButtonOpacity", Boolean.TRUE,
 872 
 873         "DesktopIcon.border", internalFrameBorder,
 874 
 875             "Desktop.minOnScreenInsets", threeInsets,
 876             "Desktop.background", table.get("desktop"),
 877             "Desktop.ancestorInputMap",
 878                new UIDefaults.LazyInputMap(new Object[] {
 879                  "ctrl F5", "restore",
 880                  "ctrl F4", "close",
 881                  "ctrl F7", "move",
 882                  "ctrl F8", "resize",
 883                    "RIGHT", "right",
 884                 "KP_RIGHT", "right",
 885              "shift RIGHT", "shrinkRight",
 886           "shift KP_RIGHT", "shrinkRight",
 887                     "LEFT", "left",
 888                  "KP_LEFT", "left",
 889               "shift LEFT", "shrinkLeft",
 890            "shift KP_LEFT", "shrinkLeft",
 891                       "UP", "up",
 892                    "KP_UP", "up",
 893                 "shift UP", "shrinkUp",
 894              "shift KP_UP", "shrinkUp",
 895                     "DOWN", "down",
 896                  "KP_DOWN", "down",
 897               "shift DOWN", "shrinkDown",
 898            "shift KP_DOWN", "shrinkDown",
 899                   "ESCAPE", "escape",
 900                  "ctrl F9", "minimize",
 901                 "ctrl F10", "maximize",
 902                  "ctrl F6", "selectNextFrame",
 903                 "ctrl TAB", "selectNextFrame",
 904              "ctrl alt F6", "selectNextFrame",
 905        "shift ctrl alt F6", "selectPreviousFrame",
 906                 "ctrl F12", "navigateNext",
 907           "shift ctrl F12", "navigatePrevious"
 908               }),
 909 
 910             // *** Label
 911             "Label.font", dialogPlain12,
 912             "Label.background", control,
 913             "Label.foreground", controlText,
 914             "Label.disabledForeground", white,
 915             "Label.disabledShadow", controlShadow,
 916             "Label.border", null,
 917 
 918             // *** List
 919             "List.font", dialogPlain12,
 920             "List.background", window,
 921             "List.foreground", textText,
 922             "List.selectionBackground", textHighlight,
 923             "List.selectionForeground", textHighlightText,
 924             "List.noFocusBorder", noFocusBorder,
 925             "List.focusCellHighlightBorder", focusCellHighlightBorder,
 926             "List.dropLineColor", controlShadow,
 927             "List.border", null,
 928             "List.cellRenderer", listCellRendererActiveValue,
 929             "List.timeFactor", oneThousand,
 930             "List.focusInputMap",
 931                new UIDefaults.LazyInputMap(new Object[] {
 932                            "ctrl C", "copy",
 933                            "ctrl V", "paste",
 934                            "ctrl X", "cut",
 935                              "COPY", "copy",
 936                             "PASTE", "paste",
 937                               "CUT", "cut",
 938                    "control INSERT", "copy",
 939                      "shift INSERT", "paste",
 940                      "shift DELETE", "cut",
 941                                "UP", "selectPreviousRow",
 942                             "KP_UP", "selectPreviousRow",
 943                          "shift UP", "selectPreviousRowExtendSelection",
 944                       "shift KP_UP", "selectPreviousRowExtendSelection",
 945                     "ctrl shift UP", "selectPreviousRowExtendSelection",
 946                  "ctrl shift KP_UP", "selectPreviousRowExtendSelection",
 947                           "ctrl UP", "selectPreviousRowChangeLead",
 948                        "ctrl KP_UP", "selectPreviousRowChangeLead",
 949                              "DOWN", "selectNextRow",
 950                           "KP_DOWN", "selectNextRow",
 951                        "shift DOWN", "selectNextRowExtendSelection",
 952                     "shift KP_DOWN", "selectNextRowExtendSelection",
 953                   "ctrl shift DOWN", "selectNextRowExtendSelection",
 954                "ctrl shift KP_DOWN", "selectNextRowExtendSelection",
 955                         "ctrl DOWN", "selectNextRowChangeLead",
 956                      "ctrl KP_DOWN", "selectNextRowChangeLead",
 957                              "LEFT", "selectPreviousColumn",
 958                           "KP_LEFT", "selectPreviousColumn",
 959                        "shift LEFT", "selectPreviousColumnExtendSelection",
 960                     "shift KP_LEFT", "selectPreviousColumnExtendSelection",
 961                   "ctrl shift LEFT", "selectPreviousColumnExtendSelection",
 962                "ctrl shift KP_LEFT", "selectPreviousColumnExtendSelection",
 963                         "ctrl LEFT", "selectPreviousColumnChangeLead",
 964                      "ctrl KP_LEFT", "selectPreviousColumnChangeLead",
 965                             "RIGHT", "selectNextColumn",
 966                          "KP_RIGHT", "selectNextColumn",
 967                       "shift RIGHT", "selectNextColumnExtendSelection",
 968                    "shift KP_RIGHT", "selectNextColumnExtendSelection",
 969                  "ctrl shift RIGHT", "selectNextColumnExtendSelection",
 970               "ctrl shift KP_RIGHT", "selectNextColumnExtendSelection",
 971                        "ctrl RIGHT", "selectNextColumnChangeLead",
 972                     "ctrl KP_RIGHT", "selectNextColumnChangeLead",
 973                              "HOME", "selectFirstRow",
 974                        "shift HOME", "selectFirstRowExtendSelection",
 975                   "ctrl shift HOME", "selectFirstRowExtendSelection",
 976                         "ctrl HOME", "selectFirstRowChangeLead",
 977                               "END", "selectLastRow",
 978                         "shift END", "selectLastRowExtendSelection",
 979                    "ctrl shift END", "selectLastRowExtendSelection",
 980                          "ctrl END", "selectLastRowChangeLead",
 981                           "PAGE_UP", "scrollUp",
 982                     "shift PAGE_UP", "scrollUpExtendSelection",
 983                "ctrl shift PAGE_UP", "scrollUpExtendSelection",
 984                      "ctrl PAGE_UP", "scrollUpChangeLead",
 985                         "PAGE_DOWN", "scrollDown",
 986                   "shift PAGE_DOWN", "scrollDownExtendSelection",
 987              "ctrl shift PAGE_DOWN", "scrollDownExtendSelection",
 988                    "ctrl PAGE_DOWN", "scrollDownChangeLead",
 989                            "ctrl A", "selectAll",
 990                        "ctrl SLASH", "selectAll",
 991                   "ctrl BACK_SLASH", "clearSelection",
 992                             "SPACE", "addToSelection",
 993                        "ctrl SPACE", "toggleAndAnchor",
 994                       "shift SPACE", "extendTo",
 995                  "ctrl shift SPACE", "moveSelectionTo"
 996                  }),
 997             "List.focusInputMap.RightToLeft",
 998                new UIDefaults.LazyInputMap(new Object[] {
 999                              "LEFT", "selectNextColumn",
1000                           "KP_LEFT", "selectNextColumn",
1001                        "shift LEFT", "selectNextColumnExtendSelection",
1002                     "shift KP_LEFT", "selectNextColumnExtendSelection",
1003                   "ctrl shift LEFT", "selectNextColumnExtendSelection",
1004                "ctrl shift KP_LEFT", "selectNextColumnExtendSelection",
1005                         "ctrl LEFT", "selectNextColumnChangeLead",
1006                      "ctrl KP_LEFT", "selectNextColumnChangeLead",
1007                             "RIGHT", "selectPreviousColumn",
1008                          "KP_RIGHT", "selectPreviousColumn",
1009                       "shift RIGHT", "selectPreviousColumnExtendSelection",
1010                    "shift KP_RIGHT", "selectPreviousColumnExtendSelection",
1011                  "ctrl shift RIGHT", "selectPreviousColumnExtendSelection",
1012               "ctrl shift KP_RIGHT", "selectPreviousColumnExtendSelection",
1013                        "ctrl RIGHT", "selectPreviousColumnChangeLead",
1014                     "ctrl KP_RIGHT", "selectPreviousColumnChangeLead",
1015                  }),
1016 
1017             // *** Menus
1018             "MenuBar.font", dialogPlain12,
1019             "MenuBar.background", menu,
1020             "MenuBar.foreground", menuText,
1021             "MenuBar.shadow", controlShadow,
1022             "MenuBar.highlight", controlLtHighlight,
1023             "MenuBar.border", menuBarBorder,
1024             "MenuBar.windowBindings", new Object[] {
1025                 "F10", "takeFocus" },
1026 
1027             "MenuItem.font", dialogPlain12,
1028             "MenuItem.acceleratorFont", dialogPlain12,
1029             "MenuItem.background", menu,
1030             "MenuItem.foreground", menuText,
1031             "MenuItem.selectionForeground", textHighlightText,
1032             "MenuItem.selectionBackground", textHighlight,
1033             "MenuItem.disabledForeground", null,
1034             "MenuItem.acceleratorForeground", menuText,
1035             "MenuItem.acceleratorSelectionForeground", textHighlightText,
1036             "MenuItem.acceleratorDelimiter", menuItemAcceleratorDelimiter,
1037             "MenuItem.border", marginBorder,
1038             "MenuItem.borderPainted", Boolean.FALSE,
1039             "MenuItem.margin", twoInsets,
1040             "MenuItem.checkIcon", menuItemCheckIcon,
1041             "MenuItem.arrowIcon", menuItemArrowIcon,
1042             "MenuItem.commandSound", null,
1043 
1044             "RadioButtonMenuItem.font", dialogPlain12,
1045             "RadioButtonMenuItem.acceleratorFont", dialogPlain12,
1046             "RadioButtonMenuItem.background", menu,
1047             "RadioButtonMenuItem.foreground", menuText,
1048             "RadioButtonMenuItem.selectionForeground", textHighlightText,
1049             "RadioButtonMenuItem.selectionBackground", textHighlight,
1050             "RadioButtonMenuItem.disabledForeground", null,
1051             "RadioButtonMenuItem.acceleratorForeground", menuText,
1052             "RadioButtonMenuItem.acceleratorSelectionForeground", textHighlightText,
1053             "RadioButtonMenuItem.border", marginBorder,
1054             "RadioButtonMenuItem.borderPainted", Boolean.FALSE,
1055             "RadioButtonMenuItem.margin", twoInsets,
1056             "RadioButtonMenuItem.checkIcon", radioButtonMenuItemIcon,
1057             "RadioButtonMenuItem.arrowIcon", menuItemArrowIcon,
1058             "RadioButtonMenuItem.commandSound", null,
1059 
1060             "CheckBoxMenuItem.font", dialogPlain12,
1061             "CheckBoxMenuItem.acceleratorFont", dialogPlain12,
1062             "CheckBoxMenuItem.background", menu,
1063             "CheckBoxMenuItem.foreground", menuText,
1064             "CheckBoxMenuItem.selectionForeground", textHighlightText,
1065             "CheckBoxMenuItem.selectionBackground", textHighlight,
1066             "CheckBoxMenuItem.disabledForeground", null,
1067             "CheckBoxMenuItem.acceleratorForeground", menuText,
1068             "CheckBoxMenuItem.acceleratorSelectionForeground", textHighlightText,
1069             "CheckBoxMenuItem.border", marginBorder,
1070             "CheckBoxMenuItem.borderPainted", Boolean.FALSE,
1071             "CheckBoxMenuItem.margin", twoInsets,
1072             "CheckBoxMenuItem.checkIcon", checkBoxMenuItemIcon,
1073             "CheckBoxMenuItem.arrowIcon", menuItemArrowIcon,
1074             "CheckBoxMenuItem.commandSound", null,
1075 
1076             "Menu.font", dialogPlain12,
1077             "Menu.acceleratorFont", dialogPlain12,
1078             "Menu.background", menu,
1079             "Menu.foreground", menuText,
1080             "Menu.selectionForeground", textHighlightText,
1081             "Menu.selectionBackground", textHighlight,
1082             "Menu.disabledForeground", null,
1083             "Menu.acceleratorForeground", menuText,
1084             "Menu.acceleratorSelectionForeground", textHighlightText,
1085             "Menu.border", marginBorder,
1086             "Menu.borderPainted", Boolean.FALSE,
1087             "Menu.margin", twoInsets,
1088             "Menu.checkIcon", menuItemCheckIcon,
1089             "Menu.arrowIcon", menuArrowIcon,
1090             "Menu.menuPopupOffsetX", new Integer(0),
1091             "Menu.menuPopupOffsetY", new Integer(0),
1092             "Menu.submenuPopupOffsetX", new Integer(0),
1093             "Menu.submenuPopupOffsetY", new Integer(0),
1094             "Menu.shortcutKeys", new int[]{
1095                 SwingUtilities2.getSystemMnemonicKeyMask()
1096             },
1097             "Menu.crossMenuMnemonic", Boolean.TRUE,
1098             // Menu.cancelMode affects the cancel menu action behaviour;
1099             // currently supports:
1100             // "hideLastSubmenu" (default)
1101             //     hides the last open submenu,
1102             //     and move selection one step back
1103             // "hideMenuTree"
1104             //     resets selection and
1105             //     hide the entire structure of open menu and its submenus
1106             "Menu.cancelMode", "hideLastSubmenu",
1107 
1108              // Menu.preserveTopLevelSelection affects
1109              // the cancel menu action behaviour
1110              // if set to true then top level menu selection
1111              // will be preserved when the last popup was cancelled;
1112              // the menu itself will be unselect with the next cancel action
1113              "Menu.preserveTopLevelSelection", Boolean.FALSE,
1114 
1115             // PopupMenu
1116             "PopupMenu.font", dialogPlain12,
1117             "PopupMenu.background", menu,
1118             "PopupMenu.foreground", menuText,
1119             "PopupMenu.border", popupMenuBorder,
1120                  // Internal Frame Auditory Cue Mappings
1121             "PopupMenu.popupSound", null,
1122             // These window InputMap bindings are used when the Menu is
1123             // selected.
1124             "PopupMenu.selectedWindowInputMapBindings", new Object[] {
1125                   "ESCAPE", "cancel",
1126                     "DOWN", "selectNext",
1127                  "KP_DOWN", "selectNext",
1128                       "UP", "selectPrevious",
1129                    "KP_UP", "selectPrevious",
1130                     "LEFT", "selectParent",
1131                  "KP_LEFT", "selectParent",
1132                    "RIGHT", "selectChild",
1133                 "KP_RIGHT", "selectChild",
1134                    "ENTER", "return",
1135               "ctrl ENTER", "return",
1136                    "SPACE", "return"
1137             },
1138             "PopupMenu.selectedWindowInputMapBindings.RightToLeft", new Object[] {
1139                     "LEFT", "selectChild",
1140                  "KP_LEFT", "selectChild",
1141                    "RIGHT", "selectParent",
1142                 "KP_RIGHT", "selectParent",
1143             },
1144             "PopupMenu.consumeEventOnClose", Boolean.FALSE,
1145 
1146             // *** OptionPane
1147             // You can additionaly define OptionPane.messageFont which will
1148             // dictate the fonts used for the message, and
1149             // OptionPane.buttonFont, which defines the font for the buttons.
1150             "OptionPane.font", dialogPlain12,
1151             "OptionPane.background", control,
1152             "OptionPane.foreground", controlText,
1153             "OptionPane.messageForeground", controlText,
1154             "OptionPane.border", optionPaneBorder,
1155             "OptionPane.messageAreaBorder", zeroBorder,
1156             "OptionPane.buttonAreaBorder", optionPaneButtonAreaBorder,
1157             "OptionPane.minimumSize", optionPaneMinimumSize,
1158             "OptionPane.errorIcon", SwingUtilities2.makeIcon(getClass(),
1159                                                              BasicLookAndFeel.class,
1160                                                              "icons/Error.gif"),
1161             "OptionPane.informationIcon", SwingUtilities2.makeIcon(getClass(),
1162                                                                    BasicLookAndFeel.class,
1163                                                                    "icons/Inform.gif"),
1164             "OptionPane.warningIcon", SwingUtilities2.makeIcon(getClass(),
1165                                                                BasicLookAndFeel.class,
1166                                                                "icons/Warn.gif"),
1167             "OptionPane.questionIcon", SwingUtilities2.makeIcon(getClass(),
1168                                                                 BasicLookAndFeel.class,
1169                                                                 "icons/Question.gif"),
1170             "OptionPane.windowBindings", new Object[] {
1171                 "ESCAPE", "close" },
1172                  // OptionPane Auditory Cue Mappings
1173             "OptionPane.errorSound", null,
1174             "OptionPane.informationSound", null, // Info and Plain
1175             "OptionPane.questionSound", null,
1176             "OptionPane.warningSound", null,
1177             "OptionPane.buttonClickThreshhold", fiveHundred,
1178 
1179             // *** Panel
1180             "Panel.font", dialogPlain12,
1181             "Panel.background", control,
1182             "Panel.foreground", textText,
1183 
1184             // *** ProgressBar
1185             "ProgressBar.font", dialogPlain12,
1186             "ProgressBar.foreground",  textHighlight,
1187             "ProgressBar.background", control,
1188             "ProgressBar.selectionForeground", control,
1189             "ProgressBar.selectionBackground", textHighlight,
1190             "ProgressBar.border", progressBarBorder,
1191             "ProgressBar.cellLength", new Integer(1),
1192             "ProgressBar.cellSpacing", zero,
1193             "ProgressBar.repaintInterval", new Integer(50),
1194             "ProgressBar.cycleTime", new Integer(3000),
1195             "ProgressBar.horizontalSize", new DimensionUIResource(146, 12),
1196             "ProgressBar.verticalSize", new DimensionUIResource(12, 146),
1197 
1198            // *** Separator
1199             "Separator.shadow", controlShadow,          // DEPRECATED - DO NOT USE!
1200             "Separator.highlight", controlLtHighlight,  // DEPRECATED - DO NOT USE!
1201 
1202             "Separator.background", controlLtHighlight,
1203             "Separator.foreground", controlShadow,
1204 
1205             // *** ScrollBar/ScrollPane/Viewport
1206             "ScrollBar.background", scrollBarTrack,
1207             "ScrollBar.foreground", control,
1208             "ScrollBar.track", table.get("scrollbar"),
1209             "ScrollBar.trackHighlight", controlDkShadow,
1210             "ScrollBar.thumb", control,
1211             "ScrollBar.thumbHighlight", controlLtHighlight,
1212             "ScrollBar.thumbDarkShadow", controlDkShadow,
1213             "ScrollBar.thumbShadow", controlShadow,
1214             "ScrollBar.border", null,
1215             "ScrollBar.minimumThumbSize", minimumThumbSize,
1216             "ScrollBar.maximumThumbSize", maximumThumbSize,
1217             "ScrollBar.ancestorInputMap",
1218                new UIDefaults.LazyInputMap(new Object[] {
1219                        "RIGHT", "positiveUnitIncrement",
1220                     "KP_RIGHT", "positiveUnitIncrement",
1221                         "DOWN", "positiveUnitIncrement",
1222                      "KP_DOWN", "positiveUnitIncrement",
1223                    "PAGE_DOWN", "positiveBlockIncrement",
1224                         "LEFT", "negativeUnitIncrement",
1225                      "KP_LEFT", "negativeUnitIncrement",
1226                           "UP", "negativeUnitIncrement",
1227                        "KP_UP", "negativeUnitIncrement",
1228                      "PAGE_UP", "negativeBlockIncrement",
1229                         "HOME", "minScroll",
1230                          "END", "maxScroll"
1231                  }),
1232             "ScrollBar.ancestorInputMap.RightToLeft",
1233                new UIDefaults.LazyInputMap(new Object[] {
1234                        "RIGHT", "negativeUnitIncrement",
1235                     "KP_RIGHT", "negativeUnitIncrement",
1236                         "LEFT", "positiveUnitIncrement",
1237                      "KP_LEFT", "positiveUnitIncrement",
1238                  }),
1239             "ScrollBar.width", new Integer(16),
1240 
1241             "ScrollPane.font", dialogPlain12,
1242             "ScrollPane.background", control,
1243             "ScrollPane.foreground", controlText,
1244             "ScrollPane.border", textFieldBorder,
1245             "ScrollPane.viewportBorder", null,
1246             "ScrollPane.ancestorInputMap",
1247                new UIDefaults.LazyInputMap(new Object[] {
1248                            "RIGHT", "unitScrollRight",
1249                         "KP_RIGHT", "unitScrollRight",
1250                             "DOWN", "unitScrollDown",
1251                          "KP_DOWN", "unitScrollDown",
1252                             "LEFT", "unitScrollLeft",
1253                          "KP_LEFT", "unitScrollLeft",
1254                               "UP", "unitScrollUp",
1255                            "KP_UP", "unitScrollUp",
1256                          "PAGE_UP", "scrollUp",
1257                        "PAGE_DOWN", "scrollDown",
1258                     "ctrl PAGE_UP", "scrollLeft",
1259                   "ctrl PAGE_DOWN", "scrollRight",
1260                        "ctrl HOME", "scrollHome",
1261                         "ctrl END", "scrollEnd"
1262                  }),
1263             "ScrollPane.ancestorInputMap.RightToLeft",
1264                new UIDefaults.LazyInputMap(new Object[] {
1265                     "ctrl PAGE_UP", "scrollRight",
1266                   "ctrl PAGE_DOWN", "scrollLeft",
1267                  }),
1268 
1269             "Viewport.font", dialogPlain12,
1270             "Viewport.background", control,
1271             "Viewport.foreground", textText,
1272 
1273             // *** Slider
1274             "Slider.font", dialogPlain12,
1275             "Slider.foreground", control,
1276             "Slider.background", control,
1277             "Slider.highlight", controlLtHighlight,
1278             "Slider.tickColor", Color.black,
1279             "Slider.shadow", controlShadow,
1280             "Slider.focus", controlDkShadow,
1281             "Slider.border", null,
1282             "Slider.horizontalSize", new Dimension(200, 21),
1283             "Slider.verticalSize", new Dimension(21, 200),
1284             "Slider.minimumHorizontalSize", new Dimension(36, 21),
1285             "Slider.minimumVerticalSize", new Dimension(21, 36),
1286             "Slider.focusInsets", sliderFocusInsets,
1287             "Slider.focusInputMap",
1288                new UIDefaults.LazyInputMap(new Object[] {
1289                        "RIGHT", "positiveUnitIncrement",
1290                     "KP_RIGHT", "positiveUnitIncrement",
1291                         "DOWN", "negativeUnitIncrement",
1292                      "KP_DOWN", "negativeUnitIncrement",
1293                    "PAGE_DOWN", "negativeBlockIncrement",
1294                         "LEFT", "negativeUnitIncrement",
1295                      "KP_LEFT", "negativeUnitIncrement",
1296                           "UP", "positiveUnitIncrement",
1297                        "KP_UP", "positiveUnitIncrement",
1298                      "PAGE_UP", "positiveBlockIncrement",
1299                         "HOME", "minScroll",
1300                          "END", "maxScroll"
1301                  }),
1302             "Slider.focusInputMap.RightToLeft",
1303                new UIDefaults.LazyInputMap(new Object[] {
1304                        "RIGHT", "negativeUnitIncrement",
1305                     "KP_RIGHT", "negativeUnitIncrement",
1306                         "LEFT", "positiveUnitIncrement",
1307                      "KP_LEFT", "positiveUnitIncrement",
1308                  }),
1309             "Slider.onlyLeftMouseButtonDrag", Boolean.TRUE,
1310 
1311             // *** Spinner
1312             "Spinner.font", monospacedPlain12,
1313             "Spinner.background", control,
1314             "Spinner.foreground", control,
1315             "Spinner.border", textFieldBorder,
1316             "Spinner.arrowButtonBorder", null,
1317             "Spinner.arrowButtonInsets", null,
1318             "Spinner.arrowButtonSize", new Dimension(16, 5),
1319             "Spinner.ancestorInputMap",
1320                new UIDefaults.LazyInputMap(new Object[] {
1321                                "UP", "increment",
1322                             "KP_UP", "increment",
1323                              "DOWN", "decrement",
1324                           "KP_DOWN", "decrement",
1325                }),
1326             "Spinner.editorBorderPainted", Boolean.FALSE,
1327             "Spinner.editorAlignment", JTextField.TRAILING,
1328 
1329             // *** SplitPane
1330             "SplitPane.background", control,
1331             "SplitPane.highlight", controlLtHighlight,
1332             "SplitPane.shadow", controlShadow,
1333             "SplitPane.darkShadow", controlDkShadow,
1334             "SplitPane.border", splitPaneBorder,
1335             "SplitPane.dividerSize", new Integer(7),
1336             "SplitPaneDivider.border", splitPaneDividerBorder,
1337             "SplitPaneDivider.draggingColor", darkGray,
1338             "SplitPane.ancestorInputMap",
1339                new UIDefaults.LazyInputMap(new Object[] {
1340                         "UP", "negativeIncrement",
1341                       "DOWN", "positiveIncrement",
1342                       "LEFT", "negativeIncrement",
1343                      "RIGHT", "positiveIncrement",
1344                      "KP_UP", "negativeIncrement",
1345                    "KP_DOWN", "positiveIncrement",
1346                    "KP_LEFT", "negativeIncrement",
1347                   "KP_RIGHT", "positiveIncrement",
1348                       "HOME", "selectMin",
1349                        "END", "selectMax",
1350                         "F8", "startResize",
1351                         "F6", "toggleFocus",
1352                   "ctrl TAB", "focusOutForward",
1353             "ctrl shift TAB", "focusOutBackward"
1354                  }),
1355 
1356             // *** TabbedPane
1357             "TabbedPane.font", dialogPlain12,
1358             "TabbedPane.background", control,
1359             "TabbedPane.foreground", controlText,
1360             "TabbedPane.highlight", controlLtHighlight,
1361             "TabbedPane.light", controlHighlight,
1362             "TabbedPane.shadow", controlShadow,
1363             "TabbedPane.darkShadow", controlDkShadow,
1364             "TabbedPane.selected", null,
1365             "TabbedPane.focus", controlText,
1366             "TabbedPane.textIconGap", four,
1367 
1368             // Causes tabs to be painted on top of the content area border.
1369             // The amount of overlap is then controlled by tabAreaInsets.bottom,
1370             // which is zero by default
1371             "TabbedPane.tabsOverlapBorder", Boolean.FALSE,
1372             "TabbedPane.selectionFollowsFocus", Boolean.TRUE,
1373 
1374             "TabbedPane.labelShift", 1,
1375             "TabbedPane.selectedLabelShift", -1,
1376             "TabbedPane.tabInsets", tabbedPaneTabInsets,
1377             "TabbedPane.selectedTabPadInsets", tabbedPaneTabPadInsets,
1378             "TabbedPane.tabAreaInsets", tabbedPaneTabAreaInsets,
1379             "TabbedPane.contentBorderInsets", tabbedPaneContentBorderInsets,
1380             "TabbedPane.tabRunOverlay", new Integer(2),
1381             "TabbedPane.tabsOpaque", Boolean.TRUE,
1382             "TabbedPane.contentOpaque", Boolean.TRUE,
1383             "TabbedPane.focusInputMap",
1384               new UIDefaults.LazyInputMap(new Object[] {
1385                          "RIGHT", "navigateRight",
1386                       "KP_RIGHT", "navigateRight",
1387                           "LEFT", "navigateLeft",
1388                        "KP_LEFT", "navigateLeft",
1389                             "UP", "navigateUp",
1390                          "KP_UP", "navigateUp",
1391                           "DOWN", "navigateDown",
1392                        "KP_DOWN", "navigateDown",
1393                      "ctrl DOWN", "requestFocusForVisibleComponent",
1394                   "ctrl KP_DOWN", "requestFocusForVisibleComponent",
1395                 }),
1396             "TabbedPane.ancestorInputMap",
1397                new UIDefaults.LazyInputMap(new Object[] {
1398                    "ctrl PAGE_DOWN", "navigatePageDown",
1399                      "ctrl PAGE_UP", "navigatePageUp",
1400                           "ctrl UP", "requestFocus",
1401                        "ctrl KP_UP", "requestFocus",
1402                  }),
1403 
1404 
1405             // *** Table
1406             "Table.font", dialogPlain12,
1407             "Table.foreground", controlText,  // cell text color
1408             "Table.background", window,  // cell background color
1409             "Table.selectionForeground", textHighlightText,
1410             "Table.selectionBackground", textHighlight,
1411             "Table.dropLineColor", controlShadow,
1412             "Table.dropLineShortColor", black,
1413             "Table.gridColor", gray,  // grid line color
1414             "Table.focusCellBackground", window,
1415             "Table.focusCellForeground", controlText,
1416             "Table.focusCellHighlightBorder", focusCellHighlightBorder,
1417             "Table.scrollPaneBorder", loweredBevelBorder,
1418             "Table.ancestorInputMap",
1419                new UIDefaults.LazyInputMap(new Object[] {
1420                                "ctrl C", "copy",
1421                                "ctrl V", "paste",
1422                                "ctrl X", "cut",
1423                                  "COPY", "copy",
1424                                 "PASTE", "paste",
1425                                   "CUT", "cut",
1426                        "control INSERT", "copy",
1427                          "shift INSERT", "paste",
1428                          "shift DELETE", "cut",
1429                                 "RIGHT", "selectNextColumn",
1430                              "KP_RIGHT", "selectNextColumn",
1431                           "shift RIGHT", "selectNextColumnExtendSelection",
1432                        "shift KP_RIGHT", "selectNextColumnExtendSelection",
1433                      "ctrl shift RIGHT", "selectNextColumnExtendSelection",
1434                   "ctrl shift KP_RIGHT", "selectNextColumnExtendSelection",
1435                            "ctrl RIGHT", "selectNextColumnChangeLead",
1436                         "ctrl KP_RIGHT", "selectNextColumnChangeLead",
1437                                  "LEFT", "selectPreviousColumn",
1438                               "KP_LEFT", "selectPreviousColumn",
1439                            "shift LEFT", "selectPreviousColumnExtendSelection",
1440                         "shift KP_LEFT", "selectPreviousColumnExtendSelection",
1441                       "ctrl shift LEFT", "selectPreviousColumnExtendSelection",
1442                    "ctrl shift KP_LEFT", "selectPreviousColumnExtendSelection",
1443                             "ctrl LEFT", "selectPreviousColumnChangeLead",
1444                          "ctrl KP_LEFT", "selectPreviousColumnChangeLead",
1445                                  "DOWN", "selectNextRow",
1446                               "KP_DOWN", "selectNextRow",
1447                            "shift DOWN", "selectNextRowExtendSelection",
1448                         "shift KP_DOWN", "selectNextRowExtendSelection",
1449                       "ctrl shift DOWN", "selectNextRowExtendSelection",
1450                    "ctrl shift KP_DOWN", "selectNextRowExtendSelection",
1451                             "ctrl DOWN", "selectNextRowChangeLead",
1452                          "ctrl KP_DOWN", "selectNextRowChangeLead",
1453                                    "UP", "selectPreviousRow",
1454                                 "KP_UP", "selectPreviousRow",
1455                              "shift UP", "selectPreviousRowExtendSelection",
1456                           "shift KP_UP", "selectPreviousRowExtendSelection",
1457                         "ctrl shift UP", "selectPreviousRowExtendSelection",
1458                      "ctrl shift KP_UP", "selectPreviousRowExtendSelection",
1459                               "ctrl UP", "selectPreviousRowChangeLead",
1460                            "ctrl KP_UP", "selectPreviousRowChangeLead",
1461                                  "HOME", "selectFirstColumn",
1462                            "shift HOME", "selectFirstColumnExtendSelection",
1463                       "ctrl shift HOME", "selectFirstRowExtendSelection",
1464                             "ctrl HOME", "selectFirstRow",
1465                                   "END", "selectLastColumn",
1466                             "shift END", "selectLastColumnExtendSelection",
1467                        "ctrl shift END", "selectLastRowExtendSelection",
1468                              "ctrl END", "selectLastRow",
1469                               "PAGE_UP", "scrollUpChangeSelection",
1470                         "shift PAGE_UP", "scrollUpExtendSelection",
1471                    "ctrl shift PAGE_UP", "scrollLeftExtendSelection",
1472                          "ctrl PAGE_UP", "scrollLeftChangeSelection",
1473                             "PAGE_DOWN", "scrollDownChangeSelection",
1474                       "shift PAGE_DOWN", "scrollDownExtendSelection",
1475                  "ctrl shift PAGE_DOWN", "scrollRightExtendSelection",
1476                        "ctrl PAGE_DOWN", "scrollRightChangeSelection",
1477                                   "TAB", "selectNextColumnCell",
1478                             "shift TAB", "selectPreviousColumnCell",
1479                                 "ENTER", "selectNextRowCell",
1480                           "shift ENTER", "selectPreviousRowCell",
1481                                "ctrl A", "selectAll",
1482                            "ctrl SLASH", "selectAll",
1483                       "ctrl BACK_SLASH", "clearSelection",
1484                                "ESCAPE", "cancel",
1485                                    "F2", "startEditing",
1486                                 "SPACE", "addToSelection",
1487                            "ctrl SPACE", "toggleAndAnchor",
1488                           "shift SPACE", "extendTo",
1489                      "ctrl shift SPACE", "moveSelectionTo",
1490                                    "F8", "focusHeader"
1491                  }),
1492             "Table.ancestorInputMap.RightToLeft",
1493                new UIDefaults.LazyInputMap(new Object[] {
1494                                 "RIGHT", "selectPreviousColumn",
1495                              "KP_RIGHT", "selectPreviousColumn",
1496                           "shift RIGHT", "selectPreviousColumnExtendSelection",
1497                        "shift KP_RIGHT", "selectPreviousColumnExtendSelection",
1498                      "ctrl shift RIGHT", "selectPreviousColumnExtendSelection",
1499                   "ctrl shift KP_RIGHT", "selectPreviousColumnExtendSelection",
1500                            "ctrl RIGHT", "selectPreviousColumnChangeLead",
1501                         "ctrl KP_RIGHT", "selectPreviousColumnChangeLead",
1502                                  "LEFT", "selectNextColumn",
1503                               "KP_LEFT", "selectNextColumn",
1504                            "shift LEFT", "selectNextColumnExtendSelection",
1505                         "shift KP_LEFT", "selectNextColumnExtendSelection",
1506                       "ctrl shift LEFT", "selectNextColumnExtendSelection",
1507                    "ctrl shift KP_LEFT", "selectNextColumnExtendSelection",
1508                             "ctrl LEFT", "selectNextColumnChangeLead",
1509                          "ctrl KP_LEFT", "selectNextColumnChangeLead",
1510                          "ctrl PAGE_UP", "scrollRightChangeSelection",
1511                        "ctrl PAGE_DOWN", "scrollLeftChangeSelection",
1512                    "ctrl shift PAGE_UP", "scrollRightExtendSelection",
1513                  "ctrl shift PAGE_DOWN", "scrollLeftExtendSelection",
1514                  }),
1515             "Table.ascendingSortIcon", (LazyValue) t ->
1516                     new SortArrowIcon(true, "Table.sortIconColor"),
1517             "Table.descendingSortIcon", (LazyValue) t ->
1518                     new SortArrowIcon(false, "Table.sortIconColor"),
1519             "Table.sortIconColor", controlShadow,
1520 
1521             "TableHeader.font", dialogPlain12,
1522             "TableHeader.foreground", controlText, // header text color
1523             "TableHeader.background", control, // header background
1524             "TableHeader.cellBorder", tableHeaderBorder,
1525 
1526             // Support for changing the background/border of the currently
1527             // selected header column when the header has the keyboard focus.
1528             "TableHeader.focusCellBackground", table.getColor("text"), // like text component bg
1529             "TableHeader.focusCellForeground", null,
1530             "TableHeader.focusCellBorder", null,
1531             "TableHeader.ancestorInputMap",
1532                new UIDefaults.LazyInputMap(new Object[] {
1533                                 "SPACE", "toggleSortOrder",
1534                                  "LEFT", "selectColumnToLeft",
1535                               "KP_LEFT", "selectColumnToLeft",
1536                                 "RIGHT", "selectColumnToRight",
1537                              "KP_RIGHT", "selectColumnToRight",
1538                              "alt LEFT", "moveColumnLeft",
1539                           "alt KP_LEFT", "moveColumnLeft",
1540                             "alt RIGHT", "moveColumnRight",
1541                          "alt KP_RIGHT", "moveColumnRight",
1542                        "alt shift LEFT", "resizeLeft",
1543                     "alt shift KP_LEFT", "resizeLeft",
1544                       "alt shift RIGHT", "resizeRight",
1545                    "alt shift KP_RIGHT", "resizeRight",
1546                                "ESCAPE", "focusTable",
1547                }),
1548 
1549             // *** Text
1550             "TextField.font", sansSerifPlain12,
1551             "TextField.background", window,
1552             "TextField.foreground", textText,
1553             "TextField.shadow", controlShadow,
1554             "TextField.darkShadow", controlDkShadow,
1555             "TextField.light", controlHighlight,
1556             "TextField.highlight", controlLtHighlight,
1557             "TextField.inactiveForeground", textInactiveText,
1558             "TextField.inactiveBackground", control,
1559             "TextField.selectionBackground", textHighlight,
1560             "TextField.selectionForeground", textHighlightText,
1561             "TextField.caretForeground", textText,
1562             "TextField.caretBlinkRate", caretBlinkRate,
1563             "TextField.border", textFieldBorder,
1564             "TextField.margin", zeroInsets,
1565 
1566             "FormattedTextField.font", sansSerifPlain12,
1567             "FormattedTextField.background", window,
1568             "FormattedTextField.foreground", textText,
1569             "FormattedTextField.inactiveForeground", textInactiveText,
1570             "FormattedTextField.inactiveBackground", control,
1571             "FormattedTextField.selectionBackground", textHighlight,
1572             "FormattedTextField.selectionForeground", textHighlightText,
1573             "FormattedTextField.caretForeground", textText,
1574             "FormattedTextField.caretBlinkRate", caretBlinkRate,
1575             "FormattedTextField.border", textFieldBorder,
1576             "FormattedTextField.margin", zeroInsets,
1577             "FormattedTextField.focusInputMap",
1578               new UIDefaults.LazyInputMap(new Object[] {
1579                            "ctrl C", DefaultEditorKit.copyAction,
1580                            "ctrl V", DefaultEditorKit.pasteAction,
1581                            "ctrl X", DefaultEditorKit.cutAction,
1582                              "COPY", DefaultEditorKit.copyAction,
1583                             "PASTE", DefaultEditorKit.pasteAction,
1584                               "CUT", DefaultEditorKit.cutAction,
1585                    "control INSERT", DefaultEditorKit.copyAction,
1586                      "shift INSERT", DefaultEditorKit.pasteAction,
1587                      "shift DELETE", DefaultEditorKit.cutAction,
1588                        "shift LEFT", DefaultEditorKit.selectionBackwardAction,
1589                     "shift KP_LEFT", DefaultEditorKit.selectionBackwardAction,
1590                       "shift RIGHT", DefaultEditorKit.selectionForwardAction,
1591                    "shift KP_RIGHT", DefaultEditorKit.selectionForwardAction,
1592                         "ctrl LEFT", DefaultEditorKit.previousWordAction,
1593                      "ctrl KP_LEFT", DefaultEditorKit.previousWordAction,
1594                        "ctrl RIGHT", DefaultEditorKit.nextWordAction,
1595                     "ctrl KP_RIGHT", DefaultEditorKit.nextWordAction,
1596                   "ctrl shift LEFT", DefaultEditorKit.selectionPreviousWordAction,
1597                "ctrl shift KP_LEFT", DefaultEditorKit.selectionPreviousWordAction,
1598                  "ctrl shift RIGHT", DefaultEditorKit.selectionNextWordAction,
1599               "ctrl shift KP_RIGHT", DefaultEditorKit.selectionNextWordAction,
1600                            "ctrl A", DefaultEditorKit.selectAllAction,
1601                              "HOME", DefaultEditorKit.beginLineAction,
1602                               "END", DefaultEditorKit.endLineAction,
1603                        "shift HOME", DefaultEditorKit.selectionBeginLineAction,
1604                         "shift END", DefaultEditorKit.selectionEndLineAction,
1605                        "BACK_SPACE", DefaultEditorKit.deletePrevCharAction,
1606                  "shift BACK_SPACE", DefaultEditorKit.deletePrevCharAction,
1607                            "ctrl H", DefaultEditorKit.deletePrevCharAction,
1608                            "DELETE", DefaultEditorKit.deleteNextCharAction,
1609                       "ctrl DELETE", DefaultEditorKit.deleteNextWordAction,
1610                   "ctrl BACK_SPACE", DefaultEditorKit.deletePrevWordAction,
1611                             "RIGHT", DefaultEditorKit.forwardAction,
1612                              "LEFT", DefaultEditorKit.backwardAction,
1613                          "KP_RIGHT", DefaultEditorKit.forwardAction,
1614                           "KP_LEFT", DefaultEditorKit.backwardAction,
1615                             "ENTER", JTextField.notifyAction,
1616                   "ctrl BACK_SLASH", "unselect",
1617                   "control shift O", "toggle-componentOrientation",
1618                            "ESCAPE", "reset-field-edit",
1619                                "UP", "increment",
1620                             "KP_UP", "increment",
1621                              "DOWN", "decrement",
1622                           "KP_DOWN", "decrement",
1623               }),
1624 
1625             "PasswordField.font", monospacedPlain12,
1626             "PasswordField.background", window,
1627             "PasswordField.foreground", textText,
1628             "PasswordField.inactiveForeground", textInactiveText,
1629             "PasswordField.inactiveBackground", control,
1630             "PasswordField.selectionBackground", textHighlight,
1631             "PasswordField.selectionForeground", textHighlightText,
1632             "PasswordField.caretForeground", textText,
1633             "PasswordField.caretBlinkRate", caretBlinkRate,
1634             "PasswordField.border", textFieldBorder,
1635             "PasswordField.margin", zeroInsets,
1636             "PasswordField.echoChar", '*',
1637 
1638             "TextArea.font", monospacedPlain12,
1639             "TextArea.background", window,
1640             "TextArea.foreground", textText,
1641             "TextArea.inactiveForeground", textInactiveText,
1642             "TextArea.selectionBackground", textHighlight,
1643             "TextArea.selectionForeground", textHighlightText,
1644             "TextArea.caretForeground", textText,
1645             "TextArea.caretBlinkRate", caretBlinkRate,
1646             "TextArea.border", marginBorder,
1647             "TextArea.margin", zeroInsets,
1648 
1649             "TextPane.font", serifPlain12,
1650             "TextPane.background", white,
1651             "TextPane.foreground", textText,
1652             "TextPane.selectionBackground", textHighlight,
1653             "TextPane.selectionForeground", textHighlightText,
1654             "TextPane.caretForeground", textText,
1655             "TextPane.caretBlinkRate", caretBlinkRate,
1656             "TextPane.inactiveForeground", textInactiveText,
1657             "TextPane.border", marginBorder,
1658             "TextPane.margin", editorMargin,
1659 
1660             "EditorPane.font", serifPlain12,
1661             "EditorPane.background", white,
1662             "EditorPane.foreground", textText,
1663             "EditorPane.selectionBackground", textHighlight,
1664             "EditorPane.selectionForeground", textHighlightText,
1665             "EditorPane.caretForeground", textText,
1666             "EditorPane.caretBlinkRate", caretBlinkRate,
1667             "EditorPane.inactiveForeground", textInactiveText,
1668             "EditorPane.border", marginBorder,
1669             "EditorPane.margin", editorMargin,
1670 
1671             "html.pendingImage", SwingUtilities2.makeIcon(getClass(),
1672                                     BasicLookAndFeel.class,
1673                                     "icons/image-delayed.png"),
1674             "html.missingImage", SwingUtilities2.makeIcon(getClass(),
1675                                     BasicLookAndFeel.class,
1676                                     "icons/image-failed.png"),
1677             // *** TitledBorder
1678             "TitledBorder.font", dialogPlain12,
1679             "TitledBorder.titleColor", controlText,
1680             "TitledBorder.border", etchedBorder,
1681 
1682             // *** ToolBar
1683             "ToolBar.font", dialogPlain12,
1684             "ToolBar.background", control,
1685             "ToolBar.foreground", controlText,
1686             "ToolBar.shadow", controlShadow,
1687             "ToolBar.darkShadow", controlDkShadow,
1688             "ToolBar.light", controlHighlight,
1689             "ToolBar.highlight", controlLtHighlight,
1690             "ToolBar.dockingBackground", control,
1691             "ToolBar.dockingForeground", red,
1692             "ToolBar.floatingBackground", control,
1693             "ToolBar.floatingForeground", darkGray,
1694             "ToolBar.border", etchedBorder,
1695             "ToolBar.separatorSize", toolBarSeparatorSize,
1696             "ToolBar.ancestorInputMap",
1697                new UIDefaults.LazyInputMap(new Object[] {
1698                         "UP", "navigateUp",
1699                      "KP_UP", "navigateUp",
1700                       "DOWN", "navigateDown",
1701                    "KP_DOWN", "navigateDown",
1702                       "LEFT", "navigateLeft",
1703                    "KP_LEFT", "navigateLeft",
1704                      "RIGHT", "navigateRight",
1705                   "KP_RIGHT", "navigateRight"
1706                  }),
1707 
1708             // *** ToolTips
1709             "ToolTip.font", sansSerifPlain12,
1710             "ToolTip.background", table.get("info"),
1711             "ToolTip.foreground", table.get("infoText"),
1712             "ToolTip.border", blackLineBorder,
1713             // ToolTips also support backgroundInactive, borderInactive,
1714             // and foregroundInactive
1715 
1716         // *** ToolTipManager
1717             // ToolTipManager.enableToolTipMode currently supports:
1718             // "allWindows" (default):
1719             //     enables tool tips for all windows of all java applications,
1720             //     whether the windows are active or inactive
1721             // "activeApplication"
1722             //     enables tool tips for windows of an application only when
1723             //     the application has an active window
1724             "ToolTipManager.enableToolTipMode", "allWindows",
1725 
1726         // *** Tree
1727             "Tree.paintLines", Boolean.TRUE,
1728             "Tree.lineTypeDashed", Boolean.FALSE,
1729             "Tree.font", dialogPlain12,
1730             "Tree.background", window,
1731             "Tree.foreground", textText,
1732             "Tree.hash", gray,
1733             "Tree.textForeground", textText,
1734             "Tree.textBackground", table.get("text"),
1735             "Tree.selectionForeground", textHighlightText,
1736             "Tree.selectionBackground", textHighlight,
1737             "Tree.selectionBorderColor", black,
1738             "Tree.dropLineColor", controlShadow,
1739             "Tree.editorBorder", blackLineBorder,
1740             "Tree.leftChildIndent", new Integer(7),
1741             "Tree.rightChildIndent", new Integer(13),
1742             "Tree.rowHeight", new Integer(16),
1743             "Tree.scrollsOnExpand", Boolean.TRUE,
1744             "Tree.openIcon", SwingUtilities2.makeIcon(getClass(),
1745                                                       BasicLookAndFeel.class,
1746                                                       "icons/TreeOpen.gif"),
1747             "Tree.closedIcon", SwingUtilities2.makeIcon(getClass(),
1748                                                         BasicLookAndFeel.class,
1749                                                         "icons/TreeClosed.gif"),
1750             "Tree.leafIcon", SwingUtilities2.makeIcon(getClass(),
1751                                                       BasicLookAndFeel.class,
1752                                                       "icons/TreeLeaf.gif"),
1753             "Tree.expandedIcon", null,
1754             "Tree.collapsedIcon", null,
1755             "Tree.changeSelectionWithFocus", Boolean.TRUE,
1756             "Tree.drawsFocusBorderAroundIcon", Boolean.FALSE,
1757             "Tree.timeFactor", oneThousand,
1758             "Tree.focusInputMap",
1759                new UIDefaults.LazyInputMap(new Object[] {
1760                                  "ctrl C", "copy",
1761                                  "ctrl V", "paste",
1762                                  "ctrl X", "cut",
1763                                    "COPY", "copy",
1764                                   "PASTE", "paste",
1765                                     "CUT", "cut",
1766                          "control INSERT", "copy",
1767                            "shift INSERT", "paste",
1768                            "shift DELETE", "cut",
1769                                      "UP", "selectPrevious",
1770                                   "KP_UP", "selectPrevious",
1771                                "shift UP", "selectPreviousExtendSelection",
1772                             "shift KP_UP", "selectPreviousExtendSelection",
1773                           "ctrl shift UP", "selectPreviousExtendSelection",
1774                        "ctrl shift KP_UP", "selectPreviousExtendSelection",
1775                                 "ctrl UP", "selectPreviousChangeLead",
1776                              "ctrl KP_UP", "selectPreviousChangeLead",
1777                                    "DOWN", "selectNext",
1778                                 "KP_DOWN", "selectNext",
1779                              "shift DOWN", "selectNextExtendSelection",
1780                           "shift KP_DOWN", "selectNextExtendSelection",
1781                         "ctrl shift DOWN", "selectNextExtendSelection",
1782                      "ctrl shift KP_DOWN", "selectNextExtendSelection",
1783                               "ctrl DOWN", "selectNextChangeLead",
1784                            "ctrl KP_DOWN", "selectNextChangeLead",
1785                                   "RIGHT", "selectChild",
1786                                "KP_RIGHT", "selectChild",
1787                                    "LEFT", "selectParent",
1788                                 "KP_LEFT", "selectParent",
1789                                 "PAGE_UP", "scrollUpChangeSelection",
1790                           "shift PAGE_UP", "scrollUpExtendSelection",
1791                      "ctrl shift PAGE_UP", "scrollUpExtendSelection",
1792                            "ctrl PAGE_UP", "scrollUpChangeLead",
1793                               "PAGE_DOWN", "scrollDownChangeSelection",
1794                         "shift PAGE_DOWN", "scrollDownExtendSelection",
1795                    "ctrl shift PAGE_DOWN", "scrollDownExtendSelection",
1796                          "ctrl PAGE_DOWN", "scrollDownChangeLead",
1797                                    "HOME", "selectFirst",
1798                              "shift HOME", "selectFirstExtendSelection",
1799                         "ctrl shift HOME", "selectFirstExtendSelection",
1800                               "ctrl HOME", "selectFirstChangeLead",
1801                                     "END", "selectLast",
1802                               "shift END", "selectLastExtendSelection",
1803                          "ctrl shift END", "selectLastExtendSelection",
1804                                "ctrl END", "selectLastChangeLead",
1805                                      "F2", "startEditing",
1806                                  "ctrl A", "selectAll",
1807                              "ctrl SLASH", "selectAll",
1808                         "ctrl BACK_SLASH", "clearSelection",
1809                               "ctrl LEFT", "scrollLeft",
1810                            "ctrl KP_LEFT", "scrollLeft",
1811                              "ctrl RIGHT", "scrollRight",
1812                           "ctrl KP_RIGHT", "scrollRight",
1813                                   "SPACE", "addToSelection",
1814                              "ctrl SPACE", "toggleAndAnchor",
1815                             "shift SPACE", "extendTo",
1816                        "ctrl shift SPACE", "moveSelectionTo"
1817                  }),
1818             "Tree.focusInputMap.RightToLeft",
1819                new UIDefaults.LazyInputMap(new Object[] {
1820                                   "RIGHT", "selectParent",
1821                                "KP_RIGHT", "selectParent",
1822                                    "LEFT", "selectChild",
1823                                 "KP_LEFT", "selectChild",
1824                  }),
1825             "Tree.ancestorInputMap",
1826                new UIDefaults.LazyInputMap(new Object[] {
1827                      "ESCAPE", "cancel"
1828                  }),
1829             // Bind specific keys that can invoke popup on currently
1830             // focused JComponent
1831             "RootPane.ancestorInputMap",
1832                 new UIDefaults.LazyInputMap(new Object[] {
1833                      "shift F10", "postPopup",
1834                   "CONTEXT_MENU", "postPopup"
1835                   }),
1836 
1837             // These bindings are only enabled when there is a default
1838             // button set on the rootpane.
1839             "RootPane.defaultButtonWindowKeyBindings", new Object[] {
1840                              "ENTER", "press",
1841                     "released ENTER", "release",
1842                         "ctrl ENTER", "press",
1843                "ctrl released ENTER", "release"
1844               },
1845         };
1846 
1847         table.putDefaults(defaults);
1848     }
1849 
1850     static int getFocusAcceleratorKeyMask() {
1851         Toolkit tk = Toolkit.getDefaultToolkit();
1852         if (tk instanceof SunToolkit) {
1853             return ((SunToolkit)tk).getFocusAcceleratorKeyMask();
1854         }
1855         return ActionEvent.ALT_MASK;
1856     }
1857 
1858 
1859 
1860     /**
1861      * Returns the ui that is of type <code>klass</code>, or null if
1862      * one can not be found.
1863      */
1864     static Object getUIOfType(ComponentUI ui, Class klass) {
1865         if (klass.isInstance(ui)) {
1866             return ui;
1867         }
1868         return null;
1869     }
1870 
1871     // ********* Auditory Cue support methods and objects *********
1872     // also see the "AuditoryCues" section of the defaults table
1873 
1874     /**
1875      * Returns an <code>ActionMap</code> containing the audio actions
1876      * for this look and feel.
1877      * <P>
1878      * The returned <code>ActionMap</code> contains <code>Actions</code> that
1879      * embody the ability to render an auditory cue. These auditory
1880      * cues map onto user and system activities that may be useful
1881      * for an end user to know about (such as a dialog box appearing).
1882      * <P>
1883      * At the appropriate time,
1884      * the {@code ComponentUI} is responsible for obtaining an
1885      * <code>Action</code> out of the <code>ActionMap</code> and passing
1886      * it to <code>playSound</code>.
1887      * <P>
1888      * This method first looks up the {@code ActionMap} from the
1889      * defaults using the key {@code "AuditoryCues.actionMap"}.
1890      * <p>
1891      * If the value is {@code non-null}, it is returned. If the value
1892      * of the default {@code "AuditoryCues.actionMap"} is {@code null}
1893      * and the value of the default {@code "AuditoryCues.cueList"} is
1894      * {@code non-null}, an {@code ActionMapUIResource} is created and
1895      * populated. Population is done by iterating over each of the
1896      * elements of the {@code "AuditoryCues.cueList"} array, and
1897      * invoking {@code createAudioAction()} to create an {@code
1898      * Action} for each element.  The resulting {@code Action} is
1899      * placed in the {@code ActionMapUIResource}, using the array
1900      * element as the key.  For example, if the {@code
1901      * "AuditoryCues.cueList"} array contains a single-element, {@code
1902      * "audioKey"}, the {@code ActionMapUIResource} is created, then
1903      * populated by way of {@code actionMap.put(cueList[0],
1904      * createAudioAction(cueList[0]))}.
1905      * <p>
1906      * If the value of the default {@code "AuditoryCues.actionMap"} is
1907      * {@code null} and the value of the default
1908      * {@code "AuditoryCues.cueList"} is {@code null}, an empty
1909      * {@code ActionMapUIResource} is created.
1910      *
1911      *
1912      * @return      an ActionMap containing {@code Actions}
1913      *              responsible for playing auditory cues
1914      * @throws ClassCastException if the value of the
1915      *         default {@code "AuditoryCues.actionMap"} is not an
1916      *         {@code ActionMap}, or the value of the default
1917      *         {@code "AuditoryCues.cueList"} is not an {@code Object[]}
1918      * @see #createAudioAction
1919      * @see #playSound(Action)
1920      * @since 1.4
1921      */
1922     protected ActionMap getAudioActionMap() {
1923         ActionMap audioActionMap = (ActionMap)UIManager.get(
1924                                               "AuditoryCues.actionMap");
1925         if (audioActionMap == null) {
1926             Object[] acList = (Object[])UIManager.get("AuditoryCues.cueList");
1927             if (acList != null) {
1928                 audioActionMap = new ActionMapUIResource();
1929                 for(int counter = acList.length-1; counter >= 0; counter--) {
1930                     audioActionMap.put(acList[counter],
1931                                        createAudioAction(acList[counter]));
1932                 }
1933             }
1934             UIManager.getLookAndFeelDefaults().put("AuditoryCues.actionMap",
1935                                                    audioActionMap);
1936         }
1937         return audioActionMap;
1938     }
1939 
1940     /**
1941      * Creates and returns an {@code Action} used to play a sound.
1942      * <p>
1943      * If {@code key} is {@code non-null}, an {@code Action} is created
1944      * using the value from the defaults with key {@code key}. The value
1945      * identifies the sound resource to load when
1946      * {@code actionPerformed} is invoked on the {@code Action}. The
1947      * sound resource is loaded into a {@code byte[]} by way of
1948      * {@code getClass().getResourceAsStream()}.
1949      *
1950      * @param key the key identifying the audio action
1951      * @return      an {@code Action} used to play the source, or {@code null}
1952      *              if {@code key} is {@code null}
1953      * @see #playSound(Action)
1954      * @since 1.4
1955      */
1956     protected Action createAudioAction(Object key) {
1957         if (key != null) {
1958             String audioKey = (String)key;
1959             String audioValue = (String)UIManager.get(key);
1960             return new AudioAction(audioKey, audioValue);
1961         } else {
1962             return null;
1963         }
1964     }
1965 
1966     /**
1967      * Pass the name String to the super constructor. This is used
1968      * later to identify the Action and decide whether to play it or
1969      * not. Store the resource String. I is used to get the audio
1970      * resource. In this case, the resource is an audio file.
1971      *
1972      * @since 1.4
1973      */
1974     private class AudioAction extends AbstractAction implements LineListener {
1975         // We strive to only play one sound at a time (other platforms
1976         // appear to do this). This is done by maintaining the field
1977         // clipPlaying. Every time a sound is to be played,
1978         // cancelCurrentSound is invoked to cancel any sound that may be
1979         // playing.
1980         private String audioResource;
1981         private byte[] audioBuffer;
1982 
1983         /**
1984          * The String is the name of the Action and
1985          * points to the audio resource.
1986          * The byte[] is a buffer of the audio bits.
1987          */
1988         public AudioAction(String name, String resource) {
1989             super(name);
1990             audioResource = resource;
1991         }
1992 
1993         public void actionPerformed(ActionEvent e) {
1994             if (audioBuffer == null) {
1995                 audioBuffer = loadAudioData(audioResource);
1996             }
1997             if (audioBuffer != null) {
1998                 cancelCurrentSound(null);
1999                 try {
2000                     AudioInputStream soundStream =
2001                         AudioSystem.getAudioInputStream(
2002                             new ByteArrayInputStream(audioBuffer));
2003                     DataLine.Info info =
2004                         new DataLine.Info(Clip.class, soundStream.getFormat());
2005                     Clip clip = (Clip) AudioSystem.getLine(info);
2006                     clip.open(soundStream);
2007                     clip.addLineListener(this);
2008 
2009                     synchronized(audioLock) {
2010                         clipPlaying = clip;
2011                     }
2012 
2013                     clip.start();
2014                 } catch (Exception ex) {}
2015             }
2016         }
2017 
2018         public void update(LineEvent event) {
2019             if (event.getType() == LineEvent.Type.STOP) {
2020                 cancelCurrentSound((Clip)event.getLine());
2021             }
2022         }
2023 
2024         /**
2025          * If the parameter is null, or equal to the currently
2026          * playing sound, then cancel the currently playing sound.
2027          */
2028         private void cancelCurrentSound(Clip clip) {
2029             Clip lastClip = null;
2030 
2031             synchronized(audioLock) {
2032                 if (clip == null || clip == clipPlaying) {
2033                     lastClip = clipPlaying;
2034                     clipPlaying = null;
2035                 }
2036             }
2037 
2038             if (lastClip != null) {
2039                 lastClip.removeLineListener(this);
2040                 lastClip.close();
2041             }
2042         }
2043     }
2044 
2045     /**
2046      * Utility method that loads audio bits for the specified
2047      * <code>soundFile</code> filename. If this method is unable to
2048      * build a viable path name from the <code>baseClass</code> and
2049      * <code>soundFile</code> passed into this method, it will
2050      * return <code>null</code>.
2051      *
2052      * @param soundFile    the name of the audio file to be retrieved
2053      *                     from disk
2054      * @return             A byte[] with audio data or null
2055      * @since 1.4
2056      */
2057     private byte[] loadAudioData(final String soundFile){
2058         if (soundFile == null) {
2059             return null;
2060         }
2061         /* Copy resource into a byte array.  This is
2062          * necessary because several browsers consider
2063          * Class.getResource a security risk since it
2064          * can be used to load additional classes.
2065          * Class.getResourceAsStream just returns raw
2066          * bytes, which we can convert to a sound.
2067          */
2068         byte[] buffer = AccessController.doPrivileged(
2069                                                  new PrivilegedAction<byte[]>() {
2070                 public byte[] run() {
2071                     try {
2072                         InputStream resource = BasicLookAndFeel.this.
2073                             getClass().getResourceAsStream(soundFile);
2074                         if (resource == null) {
2075                             return null;
2076                         }
2077                         BufferedInputStream in =
2078                             new BufferedInputStream(resource);
2079                         ByteArrayOutputStream out =
2080                             new ByteArrayOutputStream(1024);
2081                         byte[] buffer = new byte[1024];
2082                         int n;
2083                         while ((n = in.read(buffer)) > 0) {
2084                             out.write(buffer, 0, n);
2085                         }
2086                         in.close();
2087                         out.flush();
2088                         buffer = out.toByteArray();
2089                         return buffer;
2090                     } catch (IOException ioe) {
2091                         System.err.println(ioe.toString());
2092                         return null;
2093                     }
2094                 }
2095             });
2096         if (buffer == null) {
2097             System.err.println(getClass().getName() + "/" +
2098                                soundFile + " not found.");
2099             return null;
2100         }
2101         if (buffer.length == 0) {
2102             System.err.println("warning: " + soundFile +
2103                                " is zero-length");
2104             return null;
2105         }
2106         return buffer;
2107     }
2108 
2109     /**
2110      * If necessary, invokes {@code actionPerformed} on
2111      * {@code audioAction} to play a sound.
2112      * The {@code actionPerformed} method is invoked if the value of
2113      * the {@code "AuditoryCues.playList"} default is a {@code
2114      * non-null} {@code Object[]} containing a {@code String} entry
2115      * equal to the name of the {@code audioAction}.
2116      *
2117      * @param audioAction an Action that knows how to render the audio
2118      *                    associated with the system or user activity
2119      *                    that is occurring; a value of {@code null}, is
2120      *                    ignored
2121      * @throws ClassCastException if {@code audioAction} is {@code non-null}
2122      *         and the value of the default {@code "AuditoryCues.playList"}
2123      *         is not an {@code Object[]}
2124      * @since 1.4
2125      */
2126     protected void playSound(Action audioAction) {
2127         if (audioAction != null) {
2128             Object[] audioStrings = (Object[])
2129                                     UIManager.get("AuditoryCues.playList");
2130             if (audioStrings != null) {
2131                 // create a HashSet to help us decide to play or not
2132                 HashSet<Object> audioCues = new HashSet<Object>();
2133                 for (Object audioString : audioStrings) {
2134                     audioCues.add(audioString);
2135                 }
2136                 // get the name of the Action
2137                 String actionName = (String)audioAction.getValue(Action.NAME);
2138                 // if the actionName is in the audioCues HashSet, play it.
2139                 if (audioCues.contains(actionName)) {
2140                     audioAction.actionPerformed(new
2141                         ActionEvent(this, ActionEvent.ACTION_PERFORMED,
2142                                     actionName));
2143                 }
2144             }
2145         }
2146     }
2147 
2148 
2149     /**
2150      * Sets the parent of the passed in ActionMap to be the audio action
2151      * map.
2152      */
2153     static void installAudioActionMap(ActionMap map) {
2154         LookAndFeel laf = UIManager.getLookAndFeel();
2155         if (laf instanceof BasicLookAndFeel) {
2156             map.setParent(((BasicLookAndFeel)laf).getAudioActionMap());
2157         }
2158     }
2159 
2160 
2161     /**
2162      * Helper method to play a named sound.
2163      *
2164      * @param c JComponent to play the sound for.
2165      * @param actionKey Key for the sound.
2166      */
2167     static void playSound(JComponent c, Object actionKey) {
2168         LookAndFeel laf = UIManager.getLookAndFeel();
2169         if (laf instanceof BasicLookAndFeel) {
2170             ActionMap map = c.getActionMap();
2171             if (map != null) {
2172                 Action audioAction = map.get(actionKey);
2173                 if (audioAction != null) {
2174                     // pass off firing the Action to a utility method
2175                     ((BasicLookAndFeel)laf).playSound(audioAction);
2176                 }
2177             }
2178         }
2179     }
2180 
2181     /**
2182      * This class contains listener that watches for all the mouse
2183      * events that can possibly invoke popup on the component
2184      */
2185     class AWTEventHelper implements AWTEventListener,PrivilegedAction<Object> {
2186         AWTEventHelper() {
2187             super();
2188             AccessController.doPrivileged(this);
2189         }
2190 
2191         public Object run() {
2192             Toolkit tk = Toolkit.getDefaultToolkit();
2193             if(invocator == null) {
2194                 tk.addAWTEventListener(this, AWTEvent.MOUSE_EVENT_MASK);
2195             } else {
2196                 tk.removeAWTEventListener(invocator);
2197             }
2198             // Return value not used.
2199             return null;
2200         }
2201 
2202         public void eventDispatched(AWTEvent ev) {
2203             int eventID = ev.getID();
2204             if((eventID & AWTEvent.MOUSE_EVENT_MASK) != 0) {
2205                 MouseEvent me = (MouseEvent) ev;
2206                 if(me.isPopupTrigger()) {
2207                     MenuElement[] elems = MenuSelectionManager
2208                             .defaultManager()
2209                             .getSelectedPath();
2210                     if(elems != null && elems.length != 0) {
2211                         return;
2212                         // We shall not interfere with already opened menu
2213                     }
2214                     Object c = me.getSource();
2215                     JComponent src = null;
2216                     if(c instanceof JComponent) {
2217                         src = (JComponent) c;
2218                     } else if(c instanceof BasicSplitPaneDivider) {
2219                         // Special case - if user clicks on divider we must
2220                         // invoke popup from the SplitPane
2221                         src = (JComponent)
2222                             ((BasicSplitPaneDivider)c).getParent();
2223                     }
2224                     if(src != null) {
2225                         if(src.getComponentPopupMenu() != null) {
2226                             Point pt = src.getPopupLocation(me);
2227                             if(pt == null) {
2228                                 pt = me.getPoint();
2229                                 pt = SwingUtilities.convertPoint((Component)c,
2230                                                                   pt, src);
2231                             }
2232                             src.getComponentPopupMenu().show(src, pt.x, pt.y);
2233                             me.consume();
2234                         }
2235                     }
2236                 }
2237             }
2238             /* Activate a JInternalFrame if necessary. */
2239             if (eventID == MouseEvent.MOUSE_PRESSED) {
2240                 Object object = ev.getSource();
2241                 if (!(object instanceof Component)) {
2242                     return;
2243                 }
2244                 Component component = (Component)object;
2245                 if (component != null) {
2246                     Component parent = component;
2247                     while (parent != null && !(parent instanceof Window)) {
2248                         if (parent instanceof JInternalFrame) {
2249                             // Activate the frame.
2250                             try { ((JInternalFrame)parent).setSelected(true); }
2251                             catch (PropertyVetoException e1) { }
2252                         }
2253                         parent = parent.getParent();
2254                     }
2255                 }
2256             }
2257         }
2258     }
2259 }