1 /*
   2  * Copyright (c) 1997, 2017, 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 import sun.swing.SwingAccessor;
  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         SwingAccessor.getUIDefaultsAccessor()
 443                      .addInternalBundle(table,
 444                              "com.sun.swing.internal.plaf.basic.resources.basic");
 445     }
 446 
 447     /**
 448      * Populates {@code table} with the defaults for the basic look and
 449      * feel.
 450      *
 451      * @param table the {@code UIDefaults} to add the values to
 452      * @throws NullPointerException if {@code table} is {@code null}
 453      */
 454     protected void initComponentDefaults(UIDefaults table)
 455     {
 456 
 457         initResourceBundle(table);
 458 
 459         // *** Shared Integers
 460         Integer fiveHundred = 500;
 461 
 462         // *** Shared Longs
 463         Long oneThousand = 1000L;
 464 
 465         LazyValue dialogPlain12 = t ->
 466             new FontUIResource(Font.DIALOG, Font.PLAIN, 12);
 467         LazyValue serifPlain12 = t ->
 468             new FontUIResource(Font.SERIF, Font.PLAIN, 12);
 469         LazyValue sansSerifPlain12 =  t ->
 470             new FontUIResource(Font.SANS_SERIF, Font.PLAIN, 12);
 471         LazyValue monospacedPlain12 = t ->
 472             new FontUIResource(Font.MONOSPACED, Font.PLAIN, 12);
 473         LazyValue dialogBold12 = t ->
 474             new FontUIResource(Font.DIALOG, Font.BOLD, 12);
 475 
 476 
 477         // *** Shared Colors
 478         ColorUIResource red = new ColorUIResource(Color.red);
 479         ColorUIResource black = new ColorUIResource(Color.black);
 480         ColorUIResource white = new ColorUIResource(Color.white);
 481         ColorUIResource yellow = new ColorUIResource(Color.yellow);
 482         ColorUIResource gray = new ColorUIResource(Color.gray);
 483         ColorUIResource lightGray = new ColorUIResource(Color.lightGray);
 484         ColorUIResource darkGray = new ColorUIResource(Color.darkGray);
 485         ColorUIResource scrollBarTrack = new ColorUIResource(224, 224, 224);
 486 
 487         Color control = table.getColor("control");
 488         Color controlDkShadow = table.getColor("controlDkShadow");
 489         Color controlHighlight = table.getColor("controlHighlight");
 490         Color controlLtHighlight = table.getColor("controlLtHighlight");
 491         Color controlShadow = table.getColor("controlShadow");
 492         Color controlText = table.getColor("controlText");
 493         Color menu = table.getColor("menu");
 494         Color menuText = table.getColor("menuText");
 495         Color textHighlight = table.getColor("textHighlight");
 496         Color textHighlightText = table.getColor("textHighlightText");
 497         Color textInactiveText = table.getColor("textInactiveText");
 498         Color textText = table.getColor("textText");
 499         Color window = table.getColor("window");
 500 
 501         // *** Shared Insets
 502         InsetsUIResource zeroInsets = new InsetsUIResource(0,0,0,0);
 503         InsetsUIResource twoInsets = new InsetsUIResource(2,2,2,2);
 504         InsetsUIResource threeInsets = new InsetsUIResource(3,3,3,3);
 505 
 506         // *** Shared Borders
 507         LazyValue marginBorder = t -> new BasicBorders.MarginBorder();
 508         LazyValue etchedBorder = t ->
 509             BorderUIResource.getEtchedBorderUIResource();
 510         LazyValue loweredBevelBorder = t ->
 511             BorderUIResource.getLoweredBevelBorderUIResource();
 512 
 513         LazyValue popupMenuBorder = t -> BasicBorders.getInternalFrameBorder();
 514 
 515         LazyValue blackLineBorder = t ->
 516             BorderUIResource.getBlackLineBorderUIResource();
 517         LazyValue focusCellHighlightBorder = t ->
 518             new BorderUIResource.LineBorderUIResource(yellow);
 519 
 520         Object noFocusBorder = new BorderUIResource.EmptyBorderUIResource(1,1,1,1);
 521 
 522         LazyValue tableHeaderBorder = t ->
 523             new BorderUIResource.BevelBorderUIResource(
 524                     BevelBorder.RAISED,
 525                                          controlLtHighlight,
 526                                          control,
 527                                          controlDkShadow,
 528                     controlShadow);
 529 
 530 
 531         // *** Button value objects
 532 
 533         LazyValue buttonBorder =
 534             t -> BasicBorders.getButtonBorder();
 535 
 536         LazyValue buttonToggleBorder =
 537             t -> BasicBorders.getToggleButtonBorder();
 538 
 539         LazyValue radioButtonBorder =
 540             t -> BasicBorders.getRadioButtonBorder();
 541 
 542         // *** FileChooser / FileView value objects
 543 
 544         Object newFolderIcon = SwingUtilities2.makeIcon(getClass(),
 545                                                         BasicLookAndFeel.class,
 546                                                         "icons/NewFolder.gif");
 547         Object upFolderIcon = SwingUtilities2.makeIcon(getClass(),
 548                                                        BasicLookAndFeel.class,
 549                                                        "icons/UpFolder.gif");
 550         Object homeFolderIcon = SwingUtilities2.makeIcon(getClass(),
 551                                                          BasicLookAndFeel.class,
 552                                                          "icons/HomeFolder.gif");
 553         Object detailsViewIcon = SwingUtilities2.makeIcon(getClass(),
 554                                                           BasicLookAndFeel.class,
 555                                                           "icons/DetailsView.gif");
 556         Object listViewIcon = SwingUtilities2.makeIcon(getClass(),
 557                                                        BasicLookAndFeel.class,
 558                                                        "icons/ListView.gif");
 559         Object directoryIcon = SwingUtilities2.makeIcon(getClass(),
 560                                                         BasicLookAndFeel.class,
 561                                                         "icons/Directory.gif");
 562         Object fileIcon = SwingUtilities2.makeIcon(getClass(),
 563                                                    BasicLookAndFeel.class,
 564                                                    "icons/File.gif");
 565         Object computerIcon = SwingUtilities2.makeIcon(getClass(),
 566                                                        BasicLookAndFeel.class,
 567                                                        "icons/Computer.gif");
 568         Object hardDriveIcon = SwingUtilities2.makeIcon(getClass(),
 569                                                         BasicLookAndFeel.class,
 570                                                         "icons/HardDrive.gif");
 571         Object floppyDriveIcon = SwingUtilities2.makeIcon(getClass(),
 572                                                           BasicLookAndFeel.class,
 573                                                           "icons/FloppyDrive.gif");
 574 
 575 
 576         // *** InternalFrame value objects
 577 
 578         LazyValue internalFrameBorder = t ->
 579             BasicBorders.getInternalFrameBorder();
 580 
 581         // *** List value objects
 582 
 583         Object listCellRendererActiveValue = new UIDefaults.ActiveValue() {
 584             public Object createValue(UIDefaults table) {
 585                 return new DefaultListCellRenderer.UIResource();
 586             }
 587         };
 588 
 589 
 590         // *** Menus value objects
 591 
 592         LazyValue menuBarBorder =
 593             t -> BasicBorders.getMenuBarBorder();
 594 
 595         LazyValue menuItemCheckIcon =
 596             t -> BasicIconFactory.getMenuItemCheckIcon();
 597 
 598         LazyValue menuItemArrowIcon =
 599             t -> BasicIconFactory.getMenuItemArrowIcon();
 600 
 601 
 602         LazyValue menuArrowIcon =
 603             t -> BasicIconFactory.getMenuArrowIcon();
 604 
 605         LazyValue checkBoxIcon =
 606             t -> BasicIconFactory.getCheckBoxIcon();
 607 
 608         LazyValue radioButtonIcon =
 609             t -> BasicIconFactory.getRadioButtonIcon();
 610 
 611         LazyValue checkBoxMenuItemIcon =
 612             t -> BasicIconFactory.getCheckBoxMenuItemIcon();
 613 
 614         LazyValue radioButtonMenuItemIcon =
 615             t -> BasicIconFactory.getRadioButtonMenuItemIcon();
 616 
 617         Object menuItemAcceleratorDelimiter = "+";
 618 
 619         // *** OptionPane value objects
 620 
 621         Object optionPaneMinimumSize = new DimensionUIResource(262, 90);
 622 
 623         int zero =  0;
 624         LazyValue zeroBorder = t ->
 625             new BorderUIResource.EmptyBorderUIResource(zero, zero, zero, zero);
 626 
 627         int ten = 10;
 628         LazyValue optionPaneBorder = t ->
 629             new BorderUIResource.EmptyBorderUIResource(ten, ten, 12, ten);
 630 
 631         LazyValue optionPaneButtonAreaBorder = t ->
 632             new BorderUIResource.EmptyBorderUIResource(6, zero, zero, zero);
 633 
 634 
 635         // *** ProgessBar value objects
 636 
 637         LazyValue progressBarBorder =
 638             t -> BasicBorders.getProgressBarBorder();
 639 
 640         // ** ScrollBar value objects
 641 
 642         Object minimumThumbSize = new DimensionUIResource(8,8);
 643         Object maximumThumbSize = new DimensionUIResource(4096,4096);
 644 
 645         // ** Slider value objects
 646 
 647         Object sliderFocusInsets = twoInsets;
 648 
 649         Object toolBarSeparatorSize = new DimensionUIResource( 10, 10 );
 650 
 651 
 652         // *** SplitPane value objects
 653 
 654         LazyValue splitPaneBorder =
 655             t -> BasicBorders.getSplitPaneBorder();
 656         LazyValue splitPaneDividerBorder =
 657             t -> BasicBorders.getSplitPaneDividerBorder();
 658 
 659         // ** TabbedBane value objects
 660 
 661         Object tabbedPaneTabInsets = new InsetsUIResource(0, 4, 1, 4);
 662 
 663         Object tabbedPaneTabPadInsets = new InsetsUIResource(2, 2, 2, 1);
 664 
 665         Object tabbedPaneTabAreaInsets = new InsetsUIResource(3, 2, 0, 2);
 666 
 667         Object tabbedPaneContentBorderInsets = new InsetsUIResource(2, 2, 3, 3);
 668 
 669 
 670         // *** Text value objects
 671 
 672         LazyValue textFieldBorder =
 673             t -> BasicBorders.getTextFieldBorder();
 674 
 675         Object editorMargin = threeInsets;
 676 
 677         Object caretBlinkRate = fiveHundred;
 678 
 679         Object[] allAuditoryCues = new Object[] {
 680                 "CheckBoxMenuItem.commandSound",
 681                 "InternalFrame.closeSound",
 682                 "InternalFrame.maximizeSound",
 683                 "InternalFrame.minimizeSound",
 684                 "InternalFrame.restoreDownSound",
 685                 "InternalFrame.restoreUpSound",
 686                 "MenuItem.commandSound",
 687                 "OptionPane.errorSound",
 688                 "OptionPane.informationSound",
 689                 "OptionPane.questionSound",
 690                 "OptionPane.warningSound",
 691                 "PopupMenu.popupSound",
 692                 "RadioButtonMenuItem.commandSound"};
 693 
 694         Object[] noAuditoryCues = new Object[] {"mute"};
 695 
 696         // *** Component Defaults
 697 
 698         Object[] defaults = {
 699             // *** Auditory Feedback
 700             "AuditoryCues.cueList", allAuditoryCues,
 701             "AuditoryCues.allAuditoryCues", allAuditoryCues,
 702             "AuditoryCues.noAuditoryCues", noAuditoryCues,
 703             // this key defines which of the various cues to render.
 704             // L&Fs that want auditory feedback NEED to override playList.
 705             "AuditoryCues.playList", null,
 706 
 707             // *** Buttons
 708             "Button.defaultButtonFollowsFocus", Boolean.TRUE,
 709             "Button.font", dialogPlain12,
 710             "Button.background", control,
 711             "Button.foreground", controlText,
 712             "Button.shadow", controlShadow,
 713             "Button.darkShadow", controlDkShadow,
 714             "Button.light", controlHighlight,
 715             "Button.highlight", controlLtHighlight,
 716             "Button.border", buttonBorder,
 717             "Button.margin", new InsetsUIResource(2, 14, 2, 14),
 718             "Button.textIconGap", 4,
 719             "Button.textShiftOffset", zero,
 720             "Button.focusInputMap", new UIDefaults.LazyInputMap(new Object[] {
 721                          "SPACE", "pressed",
 722                 "released SPACE", "released",
 723                          "ENTER", "pressed",
 724                 "released ENTER", "released"
 725               }),
 726 
 727             "ToggleButton.font", dialogPlain12,
 728             "ToggleButton.background", control,
 729             "ToggleButton.foreground", controlText,
 730             "ToggleButton.shadow", controlShadow,
 731             "ToggleButton.darkShadow", controlDkShadow,
 732             "ToggleButton.light", controlHighlight,
 733             "ToggleButton.highlight", controlLtHighlight,
 734             "ToggleButton.border", buttonToggleBorder,
 735             "ToggleButton.margin", new InsetsUIResource(2, 14, 2, 14),
 736             "ToggleButton.textIconGap", 4,
 737             "ToggleButton.textShiftOffset", zero,
 738             "ToggleButton.focusInputMap",
 739               new UIDefaults.LazyInputMap(new Object[] {
 740                             "SPACE", "pressed",
 741                    "released SPACE", "released"
 742                 }),
 743 
 744             "RadioButton.font", dialogPlain12,
 745             "RadioButton.background", control,
 746             "RadioButton.foreground", controlText,
 747             "RadioButton.shadow", controlShadow,
 748             "RadioButton.darkShadow", controlDkShadow,
 749             "RadioButton.light", controlHighlight,
 750             "RadioButton.highlight", controlLtHighlight,
 751             "RadioButton.border", radioButtonBorder,
 752             "RadioButton.margin", twoInsets,
 753             "RadioButton.textIconGap", 4,
 754             "RadioButton.textShiftOffset", zero,
 755             "RadioButton.icon", radioButtonIcon,
 756             "RadioButton.focusInputMap",
 757                new UIDefaults.LazyInputMap(new Object[] {
 758                           "SPACE", "pressed",
 759                  "released SPACE", "released",
 760                          "RETURN", "pressed"
 761               }),
 762 
 763             "CheckBox.font", dialogPlain12,
 764             "CheckBox.background", control,
 765             "CheckBox.foreground", controlText,
 766             "CheckBox.border", radioButtonBorder,
 767             "CheckBox.margin", twoInsets,
 768             "CheckBox.textIconGap", 4,
 769             "CheckBox.textShiftOffset", zero,
 770             "CheckBox.icon", checkBoxIcon,
 771             "CheckBox.focusInputMap",
 772                new UIDefaults.LazyInputMap(new Object[] {
 773                             "SPACE", "pressed",
 774                    "released SPACE", "released"
 775                  }),
 776             "FileChooser.useSystemExtensionHiding", Boolean.FALSE,
 777 
 778             // *** ColorChooser
 779             "ColorChooser.font", dialogPlain12,
 780             "ColorChooser.background", control,
 781             "ColorChooser.foreground", controlText,
 782 
 783             "ColorChooser.swatchesSwatchSize", new Dimension(10, 10),
 784             "ColorChooser.swatchesRecentSwatchSize", new Dimension(10, 10),
 785             "ColorChooser.swatchesDefaultRecentColor", control,
 786 
 787             // *** ComboBox
 788             "ComboBox.font", sansSerifPlain12,
 789             "ComboBox.background", window,
 790             "ComboBox.foreground", textText,
 791             "ComboBox.buttonBackground", control,
 792             "ComboBox.buttonShadow", controlShadow,
 793             "ComboBox.buttonDarkShadow", controlDkShadow,
 794             "ComboBox.buttonHighlight", controlLtHighlight,
 795             "ComboBox.selectionBackground", textHighlight,
 796             "ComboBox.selectionForeground", textHighlightText,
 797             "ComboBox.disabledBackground", control,
 798             "ComboBox.disabledForeground", textInactiveText,
 799             "ComboBox.timeFactor", oneThousand,
 800             "ComboBox.isEnterSelectablePopup", Boolean.FALSE,
 801             "ComboBox.ancestorInputMap",
 802                new UIDefaults.LazyInputMap(new Object[] {
 803                       "ESCAPE", "hidePopup",
 804                      "PAGE_UP", "pageUpPassThrough",
 805                    "PAGE_DOWN", "pageDownPassThrough",
 806                         "HOME", "homePassThrough",
 807                          "END", "endPassThrough",
 808                        "ENTER", "enterPressed"
 809                  }),
 810             "ComboBox.noActionOnKeyNavigation", Boolean.FALSE,
 811 
 812             // *** FileChooser
 813 
 814             "FileChooser.newFolderIcon", newFolderIcon,
 815             "FileChooser.upFolderIcon", upFolderIcon,
 816             "FileChooser.homeFolderIcon", homeFolderIcon,
 817             "FileChooser.detailsViewIcon", detailsViewIcon,
 818             "FileChooser.listViewIcon", listViewIcon,
 819             "FileChooser.readOnly", Boolean.FALSE,
 820             "FileChooser.usesSingleFilePane", Boolean.FALSE,
 821             "FileChooser.ancestorInputMap",
 822                new UIDefaults.LazyInputMap(new Object[] {
 823                      "ESCAPE", "cancelSelection",
 824                      "F5", "refresh",
 825                  }),
 826 
 827             "FileView.directoryIcon", directoryIcon,
 828             "FileView.fileIcon", fileIcon,
 829             "FileView.computerIcon", computerIcon,
 830             "FileView.hardDriveIcon", hardDriveIcon,
 831             "FileView.floppyDriveIcon", floppyDriveIcon,
 832 
 833             // *** InternalFrame
 834             "InternalFrame.titleFont", dialogBold12,
 835             "InternalFrame.borderColor", control,
 836             "InternalFrame.borderShadow", controlShadow,
 837             "InternalFrame.borderDarkShadow", controlDkShadow,
 838             "InternalFrame.borderHighlight", controlLtHighlight,
 839             "InternalFrame.borderLight", controlHighlight,
 840             "InternalFrame.border", internalFrameBorder,
 841             "InternalFrame.icon",   SwingUtilities2.makeIcon(getClass(),
 842                                                              BasicLookAndFeel.class,
 843                                                              "icons/JavaCup16.png"),
 844 
 845             /* Default frame icons are undefined for Basic. */
 846             "InternalFrame.maximizeIcon",
 847                (LazyValue) t -> BasicIconFactory.createEmptyFrameIcon(),
 848             "InternalFrame.minimizeIcon",
 849                (LazyValue) t -> BasicIconFactory.createEmptyFrameIcon(),
 850             "InternalFrame.iconifyIcon",
 851                (LazyValue) t -> BasicIconFactory.createEmptyFrameIcon(),
 852             "InternalFrame.closeIcon",
 853                (LazyValue) t -> BasicIconFactory.createEmptyFrameIcon(),
 854             // InternalFrame Auditory Cue Mappings
 855             "InternalFrame.closeSound", null,
 856             "InternalFrame.maximizeSound", null,
 857             "InternalFrame.minimizeSound", null,
 858             "InternalFrame.restoreDownSound", null,
 859             "InternalFrame.restoreUpSound", null,
 860 
 861             "InternalFrame.activeTitleBackground", table.get("activeCaption"),
 862             "InternalFrame.activeTitleForeground", table.get("activeCaptionText"),
 863             "InternalFrame.inactiveTitleBackground", table.get("inactiveCaption"),
 864             "InternalFrame.inactiveTitleForeground", table.get("inactiveCaptionText"),
 865             "InternalFrame.windowBindings", new Object[] {
 866               "shift ESCAPE", "showSystemMenu",
 867                 "ctrl SPACE", "showSystemMenu",
 868                     "ESCAPE", "hideSystemMenu"},
 869 
 870             "InternalFrameTitlePane.iconifyButtonOpacity", Boolean.TRUE,
 871             "InternalFrameTitlePane.maximizeButtonOpacity", Boolean.TRUE,
 872             "InternalFrameTitlePane.closeButtonOpacity", Boolean.TRUE,
 873 
 874         "DesktopIcon.border", internalFrameBorder,
 875 
 876             "Desktop.minOnScreenInsets", threeInsets,
 877             "Desktop.background", table.get("desktop"),
 878             "Desktop.ancestorInputMap",
 879                new UIDefaults.LazyInputMap(new Object[] {
 880                  "ctrl F5", "restore",
 881                  "ctrl F4", "close",
 882                  "ctrl F7", "move",
 883                  "ctrl F8", "resize",
 884                    "RIGHT", "right",
 885                 "KP_RIGHT", "right",
 886              "shift RIGHT", "shrinkRight",
 887           "shift KP_RIGHT", "shrinkRight",
 888                     "LEFT", "left",
 889                  "KP_LEFT", "left",
 890               "shift LEFT", "shrinkLeft",
 891            "shift KP_LEFT", "shrinkLeft",
 892                       "UP", "up",
 893                    "KP_UP", "up",
 894                 "shift UP", "shrinkUp",
 895              "shift KP_UP", "shrinkUp",
 896                     "DOWN", "down",
 897                  "KP_DOWN", "down",
 898               "shift DOWN", "shrinkDown",
 899            "shift KP_DOWN", "shrinkDown",
 900                   "ESCAPE", "escape",
 901                  "ctrl F9", "minimize",
 902                 "ctrl F10", "maximize",
 903                  "ctrl F6", "selectNextFrame",
 904                 "ctrl TAB", "selectNextFrame",
 905              "ctrl alt F6", "selectNextFrame",
 906        "shift ctrl alt F6", "selectPreviousFrame",
 907                 "ctrl F12", "navigateNext",
 908           "shift ctrl F12", "navigatePrevious"
 909               }),
 910 
 911             // *** Label
 912             "Label.font", dialogPlain12,
 913             "Label.background", control,
 914             "Label.foreground", controlText,
 915             "Label.disabledForeground", white,
 916             "Label.disabledShadow", controlShadow,
 917             "Label.border", null,
 918 
 919             // *** List
 920             "List.font", dialogPlain12,
 921             "List.background", window,
 922             "List.foreground", textText,
 923             "List.selectionBackground", textHighlight,
 924             "List.selectionForeground", textHighlightText,
 925             "List.noFocusBorder", noFocusBorder,
 926             "List.focusCellHighlightBorder", focusCellHighlightBorder,
 927             "List.dropLineColor", controlShadow,
 928             "List.border", null,
 929             "List.cellRenderer", listCellRendererActiveValue,
 930             "List.timeFactor", oneThousand,
 931             "List.focusInputMap",
 932                new UIDefaults.LazyInputMap(new Object[] {
 933                            "ctrl C", "copy",
 934                            "ctrl V", "paste",
 935                            "ctrl X", "cut",
 936                              "COPY", "copy",
 937                             "PASTE", "paste",
 938                               "CUT", "cut",
 939                    "control INSERT", "copy",
 940                      "shift INSERT", "paste",
 941                      "shift DELETE", "cut",
 942                                "UP", "selectPreviousRow",
 943                             "KP_UP", "selectPreviousRow",
 944                          "shift UP", "selectPreviousRowExtendSelection",
 945                       "shift KP_UP", "selectPreviousRowExtendSelection",
 946                     "ctrl shift UP", "selectPreviousRowExtendSelection",
 947                  "ctrl shift KP_UP", "selectPreviousRowExtendSelection",
 948                           "ctrl UP", "selectPreviousRowChangeLead",
 949                        "ctrl KP_UP", "selectPreviousRowChangeLead",
 950                              "DOWN", "selectNextRow",
 951                           "KP_DOWN", "selectNextRow",
 952                        "shift DOWN", "selectNextRowExtendSelection",
 953                     "shift KP_DOWN", "selectNextRowExtendSelection",
 954                   "ctrl shift DOWN", "selectNextRowExtendSelection",
 955                "ctrl shift KP_DOWN", "selectNextRowExtendSelection",
 956                         "ctrl DOWN", "selectNextRowChangeLead",
 957                      "ctrl KP_DOWN", "selectNextRowChangeLead",
 958                              "LEFT", "selectPreviousColumn",
 959                           "KP_LEFT", "selectPreviousColumn",
 960                        "shift LEFT", "selectPreviousColumnExtendSelection",
 961                     "shift KP_LEFT", "selectPreviousColumnExtendSelection",
 962                   "ctrl shift LEFT", "selectPreviousColumnExtendSelection",
 963                "ctrl shift KP_LEFT", "selectPreviousColumnExtendSelection",
 964                         "ctrl LEFT", "selectPreviousColumnChangeLead",
 965                      "ctrl KP_LEFT", "selectPreviousColumnChangeLead",
 966                             "RIGHT", "selectNextColumn",
 967                          "KP_RIGHT", "selectNextColumn",
 968                       "shift RIGHT", "selectNextColumnExtendSelection",
 969                    "shift KP_RIGHT", "selectNextColumnExtendSelection",
 970                  "ctrl shift RIGHT", "selectNextColumnExtendSelection",
 971               "ctrl shift KP_RIGHT", "selectNextColumnExtendSelection",
 972                        "ctrl RIGHT", "selectNextColumnChangeLead",
 973                     "ctrl KP_RIGHT", "selectNextColumnChangeLead",
 974                              "HOME", "selectFirstRow",
 975                        "shift HOME", "selectFirstRowExtendSelection",
 976                   "ctrl shift HOME", "selectFirstRowExtendSelection",
 977                         "ctrl HOME", "selectFirstRowChangeLead",
 978                               "END", "selectLastRow",
 979                         "shift END", "selectLastRowExtendSelection",
 980                    "ctrl shift END", "selectLastRowExtendSelection",
 981                          "ctrl END", "selectLastRowChangeLead",
 982                           "PAGE_UP", "scrollUp",
 983                     "shift PAGE_UP", "scrollUpExtendSelection",
 984                "ctrl shift PAGE_UP", "scrollUpExtendSelection",
 985                      "ctrl PAGE_UP", "scrollUpChangeLead",
 986                         "PAGE_DOWN", "scrollDown",
 987                   "shift PAGE_DOWN", "scrollDownExtendSelection",
 988              "ctrl shift PAGE_DOWN", "scrollDownExtendSelection",
 989                    "ctrl PAGE_DOWN", "scrollDownChangeLead",
 990                            "ctrl A", "selectAll",
 991                        "ctrl SLASH", "selectAll",
 992                   "ctrl BACK_SLASH", "clearSelection",
 993                             "SPACE", "addToSelection",
 994                        "ctrl SPACE", "toggleAndAnchor",
 995                       "shift SPACE", "extendTo",
 996                  "ctrl shift SPACE", "moveSelectionTo"
 997                  }),
 998             "List.focusInputMap.RightToLeft",
 999                new UIDefaults.LazyInputMap(new Object[] {
1000                              "LEFT", "selectNextColumn",
1001                           "KP_LEFT", "selectNextColumn",
1002                        "shift LEFT", "selectNextColumnExtendSelection",
1003                     "shift KP_LEFT", "selectNextColumnExtendSelection",
1004                   "ctrl shift LEFT", "selectNextColumnExtendSelection",
1005                "ctrl shift KP_LEFT", "selectNextColumnExtendSelection",
1006                         "ctrl LEFT", "selectNextColumnChangeLead",
1007                      "ctrl KP_LEFT", "selectNextColumnChangeLead",
1008                             "RIGHT", "selectPreviousColumn",
1009                          "KP_RIGHT", "selectPreviousColumn",
1010                       "shift RIGHT", "selectPreviousColumnExtendSelection",
1011                    "shift KP_RIGHT", "selectPreviousColumnExtendSelection",
1012                  "ctrl shift RIGHT", "selectPreviousColumnExtendSelection",
1013               "ctrl shift KP_RIGHT", "selectPreviousColumnExtendSelection",
1014                        "ctrl RIGHT", "selectPreviousColumnChangeLead",
1015                     "ctrl KP_RIGHT", "selectPreviousColumnChangeLead",
1016                  }),
1017 
1018             // *** Menus
1019             "MenuBar.font", dialogPlain12,
1020             "MenuBar.background", menu,
1021             "MenuBar.foreground", menuText,
1022             "MenuBar.shadow", controlShadow,
1023             "MenuBar.highlight", controlLtHighlight,
1024             "MenuBar.border", menuBarBorder,
1025             "MenuBar.windowBindings", new Object[] {
1026                 "F10", "takeFocus" },
1027 
1028             "MenuItem.font", dialogPlain12,
1029             "MenuItem.acceleratorFont", dialogPlain12,
1030             "MenuItem.background", menu,
1031             "MenuItem.foreground", menuText,
1032             "MenuItem.selectionForeground", textHighlightText,
1033             "MenuItem.selectionBackground", textHighlight,
1034             "MenuItem.disabledForeground", null,
1035             "MenuItem.acceleratorForeground", menuText,
1036             "MenuItem.acceleratorSelectionForeground", textHighlightText,
1037             "MenuItem.acceleratorDelimiter", menuItemAcceleratorDelimiter,
1038             "MenuItem.border", marginBorder,
1039             "MenuItem.borderPainted", Boolean.FALSE,
1040             "MenuItem.margin", twoInsets,
1041             "MenuItem.checkIcon", menuItemCheckIcon,
1042             "MenuItem.arrowIcon", menuItemArrowIcon,
1043             "MenuItem.commandSound", null,
1044 
1045             "RadioButtonMenuItem.font", dialogPlain12,
1046             "RadioButtonMenuItem.acceleratorFont", dialogPlain12,
1047             "RadioButtonMenuItem.background", menu,
1048             "RadioButtonMenuItem.foreground", menuText,
1049             "RadioButtonMenuItem.selectionForeground", textHighlightText,
1050             "RadioButtonMenuItem.selectionBackground", textHighlight,
1051             "RadioButtonMenuItem.disabledForeground", null,
1052             "RadioButtonMenuItem.acceleratorForeground", menuText,
1053             "RadioButtonMenuItem.acceleratorSelectionForeground", textHighlightText,
1054             "RadioButtonMenuItem.border", marginBorder,
1055             "RadioButtonMenuItem.borderPainted", Boolean.FALSE,
1056             "RadioButtonMenuItem.margin", twoInsets,
1057             "RadioButtonMenuItem.checkIcon", radioButtonMenuItemIcon,
1058             "RadioButtonMenuItem.arrowIcon", menuItemArrowIcon,
1059             "RadioButtonMenuItem.commandSound", null,
1060 
1061             "CheckBoxMenuItem.font", dialogPlain12,
1062             "CheckBoxMenuItem.acceleratorFont", dialogPlain12,
1063             "CheckBoxMenuItem.background", menu,
1064             "CheckBoxMenuItem.foreground", menuText,
1065             "CheckBoxMenuItem.selectionForeground", textHighlightText,
1066             "CheckBoxMenuItem.selectionBackground", textHighlight,
1067             "CheckBoxMenuItem.disabledForeground", null,
1068             "CheckBoxMenuItem.acceleratorForeground", menuText,
1069             "CheckBoxMenuItem.acceleratorSelectionForeground", textHighlightText,
1070             "CheckBoxMenuItem.border", marginBorder,
1071             "CheckBoxMenuItem.borderPainted", Boolean.FALSE,
1072             "CheckBoxMenuItem.margin", twoInsets,
1073             "CheckBoxMenuItem.checkIcon", checkBoxMenuItemIcon,
1074             "CheckBoxMenuItem.arrowIcon", menuItemArrowIcon,
1075             "CheckBoxMenuItem.commandSound", null,
1076 
1077             "Menu.font", dialogPlain12,
1078             "Menu.acceleratorFont", dialogPlain12,
1079             "Menu.background", menu,
1080             "Menu.foreground", menuText,
1081             "Menu.selectionForeground", textHighlightText,
1082             "Menu.selectionBackground", textHighlight,
1083             "Menu.disabledForeground", null,
1084             "Menu.acceleratorForeground", menuText,
1085             "Menu.acceleratorSelectionForeground", textHighlightText,
1086             "Menu.border", marginBorder,
1087             "Menu.borderPainted", Boolean.FALSE,
1088             "Menu.margin", twoInsets,
1089             "Menu.checkIcon", menuItemCheckIcon,
1090             "Menu.arrowIcon", menuArrowIcon,
1091             "Menu.menuPopupOffsetX", 0,
1092             "Menu.menuPopupOffsetY", 0,
1093             "Menu.submenuPopupOffsetX", 0,
1094             "Menu.submenuPopupOffsetY", 0,
1095             "Menu.shortcutKeys", new int[]{
1096                 SwingUtilities2.getSystemMnemonicKeyMask(),
1097                 SwingUtilities2.setAltGraphMask(
1098                         SwingUtilities2.getSystemMnemonicKeyMask())
1099             },
1100             "Menu.crossMenuMnemonic", Boolean.TRUE,
1101             // Menu.cancelMode affects the cancel menu action behaviour;
1102             // currently supports:
1103             // "hideLastSubmenu" (default)
1104             //     hides the last open submenu,
1105             //     and move selection one step back
1106             // "hideMenuTree"
1107             //     resets selection and
1108             //     hide the entire structure of open menu and its submenus
1109             "Menu.cancelMode", "hideLastSubmenu",
1110 
1111              // Menu.preserveTopLevelSelection affects
1112              // the cancel menu action behaviour
1113              // if set to true then top level menu selection
1114              // will be preserved when the last popup was cancelled;
1115              // the menu itself will be unselect with the next cancel action
1116              "Menu.preserveTopLevelSelection", Boolean.FALSE,
1117 
1118             // PopupMenu
1119             "PopupMenu.font", dialogPlain12,
1120             "PopupMenu.background", menu,
1121             "PopupMenu.foreground", menuText,
1122             "PopupMenu.border", popupMenuBorder,
1123                  // Internal Frame Auditory Cue Mappings
1124             "PopupMenu.popupSound", null,
1125             // These window InputMap bindings are used when the Menu is
1126             // selected.
1127             "PopupMenu.selectedWindowInputMapBindings", new Object[] {
1128                   "ESCAPE", "cancel",
1129                     "DOWN", "selectNext",
1130                  "KP_DOWN", "selectNext",
1131                       "UP", "selectPrevious",
1132                    "KP_UP", "selectPrevious",
1133                     "LEFT", "selectParent",
1134                  "KP_LEFT", "selectParent",
1135                    "RIGHT", "selectChild",
1136                 "KP_RIGHT", "selectChild",
1137                    "ENTER", "return",
1138               "ctrl ENTER", "return",
1139                    "SPACE", "return"
1140             },
1141             "PopupMenu.selectedWindowInputMapBindings.RightToLeft", new Object[] {
1142                     "LEFT", "selectChild",
1143                  "KP_LEFT", "selectChild",
1144                    "RIGHT", "selectParent",
1145                 "KP_RIGHT", "selectParent",
1146             },
1147             "PopupMenu.consumeEventOnClose", Boolean.FALSE,
1148 
1149             // *** OptionPane
1150             // You can additionaly define OptionPane.messageFont which will
1151             // dictate the fonts used for the message, and
1152             // OptionPane.buttonFont, which defines the font for the buttons.
1153             "OptionPane.font", dialogPlain12,
1154             "OptionPane.background", control,
1155             "OptionPane.foreground", controlText,
1156             "OptionPane.messageForeground", controlText,
1157             "OptionPane.border", optionPaneBorder,
1158             "OptionPane.messageAreaBorder", zeroBorder,
1159             "OptionPane.buttonAreaBorder", optionPaneButtonAreaBorder,
1160             "OptionPane.minimumSize", optionPaneMinimumSize,
1161             "OptionPane.errorIcon", SwingUtilities2.makeIcon(getClass(),
1162                                                              BasicLookAndFeel.class,
1163                                                              "icons/Error.gif"),
1164             "OptionPane.informationIcon", SwingUtilities2.makeIcon(getClass(),
1165                                                                    BasicLookAndFeel.class,
1166                                                                    "icons/Inform.gif"),
1167             "OptionPane.warningIcon", SwingUtilities2.makeIcon(getClass(),
1168                                                                BasicLookAndFeel.class,
1169                                                                "icons/Warn.gif"),
1170             "OptionPane.questionIcon", SwingUtilities2.makeIcon(getClass(),
1171                                                                 BasicLookAndFeel.class,
1172                                                                 "icons/Question.gif"),
1173             "OptionPane.windowBindings", new Object[] {
1174                 "ESCAPE", "close" },
1175                  // OptionPane Auditory Cue Mappings
1176             "OptionPane.errorSound", null,
1177             "OptionPane.informationSound", null, // Info and Plain
1178             "OptionPane.questionSound", null,
1179             "OptionPane.warningSound", null,
1180             "OptionPane.buttonClickThreshhold", fiveHundred,
1181 
1182             // *** Panel
1183             "Panel.font", dialogPlain12,
1184             "Panel.background", control,
1185             "Panel.foreground", textText,
1186 
1187             // *** ProgressBar
1188             "ProgressBar.font", dialogPlain12,
1189             "ProgressBar.foreground",  textHighlight,
1190             "ProgressBar.background", control,
1191             "ProgressBar.selectionForeground", control,
1192             "ProgressBar.selectionBackground", textHighlight,
1193             "ProgressBar.border", progressBarBorder,
1194             "ProgressBar.cellLength", 1,
1195             "ProgressBar.cellSpacing", zero,
1196             "ProgressBar.repaintInterval", 50,
1197             "ProgressBar.cycleTime", 3000,
1198             "ProgressBar.horizontalSize", new DimensionUIResource(146, 12),
1199             "ProgressBar.verticalSize", new DimensionUIResource(12, 146),
1200 
1201            // *** Separator
1202             "Separator.shadow", controlShadow,          // DEPRECATED - DO NOT USE!
1203             "Separator.highlight", controlLtHighlight,  // DEPRECATED - DO NOT USE!
1204 
1205             "Separator.background", controlLtHighlight,
1206             "Separator.foreground", controlShadow,
1207 
1208             // *** ScrollBar/ScrollPane/Viewport
1209             "ScrollBar.background", scrollBarTrack,
1210             "ScrollBar.foreground", control,
1211             "ScrollBar.track", table.get("scrollbar"),
1212             "ScrollBar.trackHighlight", controlDkShadow,
1213             "ScrollBar.thumb", control,
1214             "ScrollBar.thumbHighlight", controlLtHighlight,
1215             "ScrollBar.thumbDarkShadow", controlDkShadow,
1216             "ScrollBar.thumbShadow", controlShadow,
1217             "ScrollBar.border", null,
1218             "ScrollBar.minimumThumbSize", minimumThumbSize,
1219             "ScrollBar.maximumThumbSize", maximumThumbSize,
1220             "ScrollBar.ancestorInputMap",
1221                new UIDefaults.LazyInputMap(new Object[] {
1222                        "RIGHT", "positiveUnitIncrement",
1223                     "KP_RIGHT", "positiveUnitIncrement",
1224                         "DOWN", "positiveUnitIncrement",
1225                      "KP_DOWN", "positiveUnitIncrement",
1226                    "PAGE_DOWN", "positiveBlockIncrement",
1227                         "LEFT", "negativeUnitIncrement",
1228                      "KP_LEFT", "negativeUnitIncrement",
1229                           "UP", "negativeUnitIncrement",
1230                        "KP_UP", "negativeUnitIncrement",
1231                      "PAGE_UP", "negativeBlockIncrement",
1232                         "HOME", "minScroll",
1233                          "END", "maxScroll"
1234                  }),
1235             "ScrollBar.ancestorInputMap.RightToLeft",
1236                new UIDefaults.LazyInputMap(new Object[] {
1237                        "RIGHT", "negativeUnitIncrement",
1238                     "KP_RIGHT", "negativeUnitIncrement",
1239                         "LEFT", "positiveUnitIncrement",
1240                      "KP_LEFT", "positiveUnitIncrement",
1241                  }),
1242             "ScrollBar.width", 16,
1243 
1244             "ScrollPane.font", dialogPlain12,
1245             "ScrollPane.background", control,
1246             "ScrollPane.foreground", controlText,
1247             "ScrollPane.border", textFieldBorder,
1248             "ScrollPane.viewportBorder", null,
1249             "ScrollPane.ancestorInputMap",
1250                new UIDefaults.LazyInputMap(new Object[] {
1251                            "RIGHT", "unitScrollRight",
1252                         "KP_RIGHT", "unitScrollRight",
1253                             "DOWN", "unitScrollDown",
1254                          "KP_DOWN", "unitScrollDown",
1255                             "LEFT", "unitScrollLeft",
1256                          "KP_LEFT", "unitScrollLeft",
1257                               "UP", "unitScrollUp",
1258                            "KP_UP", "unitScrollUp",
1259                          "PAGE_UP", "scrollUp",
1260                        "PAGE_DOWN", "scrollDown",
1261                     "ctrl PAGE_UP", "scrollLeft",
1262                   "ctrl PAGE_DOWN", "scrollRight",
1263                        "ctrl HOME", "scrollHome",
1264                         "ctrl END", "scrollEnd"
1265                  }),
1266             "ScrollPane.ancestorInputMap.RightToLeft",
1267                new UIDefaults.LazyInputMap(new Object[] {
1268                     "ctrl PAGE_UP", "scrollRight",
1269                   "ctrl PAGE_DOWN", "scrollLeft",
1270                  }),
1271 
1272             "Viewport.font", dialogPlain12,
1273             "Viewport.background", control,
1274             "Viewport.foreground", textText,
1275 
1276             // *** Slider
1277             "Slider.font", dialogPlain12,
1278             "Slider.foreground", control,
1279             "Slider.background", control,
1280             "Slider.highlight", controlLtHighlight,
1281             "Slider.tickColor", Color.black,
1282             "Slider.shadow", controlShadow,
1283             "Slider.focus", controlDkShadow,
1284             "Slider.border", null,
1285             "Slider.horizontalSize", new Dimension(200, 21),
1286             "Slider.verticalSize", new Dimension(21, 200),
1287             "Slider.minimumHorizontalSize", new Dimension(36, 21),
1288             "Slider.minimumVerticalSize", new Dimension(21, 36),
1289             "Slider.focusInsets", sliderFocusInsets,
1290             "Slider.focusInputMap",
1291                new UIDefaults.LazyInputMap(new Object[] {
1292                        "RIGHT", "positiveUnitIncrement",
1293                     "KP_RIGHT", "positiveUnitIncrement",
1294                         "DOWN", "negativeUnitIncrement",
1295                      "KP_DOWN", "negativeUnitIncrement",
1296                    "PAGE_DOWN", "negativeBlockIncrement",
1297                         "LEFT", "negativeUnitIncrement",
1298                      "KP_LEFT", "negativeUnitIncrement",
1299                           "UP", "positiveUnitIncrement",
1300                        "KP_UP", "positiveUnitIncrement",
1301                      "PAGE_UP", "positiveBlockIncrement",
1302                         "HOME", "minScroll",
1303                          "END", "maxScroll"
1304                  }),
1305             "Slider.focusInputMap.RightToLeft",
1306                new UIDefaults.LazyInputMap(new Object[] {
1307                        "RIGHT", "negativeUnitIncrement",
1308                     "KP_RIGHT", "negativeUnitIncrement",
1309                         "LEFT", "positiveUnitIncrement",
1310                      "KP_LEFT", "positiveUnitIncrement",
1311                  }),
1312             "Slider.onlyLeftMouseButtonDrag", Boolean.TRUE,
1313 
1314             // *** Spinner
1315             "Spinner.font", monospacedPlain12,
1316             "Spinner.background", control,
1317             "Spinner.foreground", control,
1318             "Spinner.border", textFieldBorder,
1319             "Spinner.arrowButtonBorder", null,
1320             "Spinner.arrowButtonInsets", null,
1321             "Spinner.arrowButtonSize", new Dimension(16, 5),
1322             "Spinner.ancestorInputMap",
1323                new UIDefaults.LazyInputMap(new Object[] {
1324                                "UP", "increment",
1325                             "KP_UP", "increment",
1326                              "DOWN", "decrement",
1327                           "KP_DOWN", "decrement",
1328                }),
1329             "Spinner.editorBorderPainted", Boolean.FALSE,
1330             "Spinner.editorAlignment", JTextField.TRAILING,
1331 
1332             // *** SplitPane
1333             "SplitPane.background", control,
1334             "SplitPane.highlight", controlLtHighlight,
1335             "SplitPane.shadow", controlShadow,
1336             "SplitPane.darkShadow", controlDkShadow,
1337             "SplitPane.border", splitPaneBorder,
1338             "SplitPane.dividerSize", 7,
1339             "SplitPaneDivider.border", splitPaneDividerBorder,
1340             "SplitPaneDivider.draggingColor", darkGray,
1341             "SplitPane.ancestorInputMap",
1342                new UIDefaults.LazyInputMap(new Object[] {
1343                         "UP", "negativeIncrement",
1344                       "DOWN", "positiveIncrement",
1345                       "LEFT", "negativeIncrement",
1346                      "RIGHT", "positiveIncrement",
1347                      "KP_UP", "negativeIncrement",
1348                    "KP_DOWN", "positiveIncrement",
1349                    "KP_LEFT", "negativeIncrement",
1350                   "KP_RIGHT", "positiveIncrement",
1351                       "HOME", "selectMin",
1352                        "END", "selectMax",
1353                         "F8", "startResize",
1354                         "F6", "toggleFocus",
1355                   "ctrl TAB", "focusOutForward",
1356             "ctrl shift TAB", "focusOutBackward"
1357                  }),
1358 
1359             // *** TabbedPane
1360             "TabbedPane.font", dialogPlain12,
1361             "TabbedPane.background", control,
1362             "TabbedPane.foreground", controlText,
1363             "TabbedPane.highlight", controlLtHighlight,
1364             "TabbedPane.light", controlHighlight,
1365             "TabbedPane.shadow", controlShadow,
1366             "TabbedPane.darkShadow", controlDkShadow,
1367             "TabbedPane.selected", null,
1368             "TabbedPane.focus", controlText,
1369             "TabbedPane.textIconGap", 4,
1370 
1371             // Causes tabs to be painted on top of the content area border.
1372             // The amount of overlap is then controlled by tabAreaInsets.bottom,
1373             // which is zero by default
1374             "TabbedPane.tabsOverlapBorder", Boolean.FALSE,
1375             "TabbedPane.selectionFollowsFocus", Boolean.TRUE,
1376 
1377             "TabbedPane.labelShift", 1,
1378             "TabbedPane.selectedLabelShift", -1,
1379             "TabbedPane.tabInsets", tabbedPaneTabInsets,
1380             "TabbedPane.selectedTabPadInsets", tabbedPaneTabPadInsets,
1381             "TabbedPane.tabAreaInsets", tabbedPaneTabAreaInsets,
1382             "TabbedPane.contentBorderInsets", tabbedPaneContentBorderInsets,
1383             "TabbedPane.tabRunOverlay", 2,
1384             "TabbedPane.tabsOpaque", Boolean.TRUE,
1385             "TabbedPane.contentOpaque", Boolean.TRUE,
1386             "TabbedPane.focusInputMap",
1387               new UIDefaults.LazyInputMap(new Object[] {
1388                          "RIGHT", "navigateRight",
1389                       "KP_RIGHT", "navigateRight",
1390                           "LEFT", "navigateLeft",
1391                        "KP_LEFT", "navigateLeft",
1392                             "UP", "navigateUp",
1393                          "KP_UP", "navigateUp",
1394                           "DOWN", "navigateDown",
1395                        "KP_DOWN", "navigateDown",
1396                      "ctrl DOWN", "requestFocusForVisibleComponent",
1397                   "ctrl KP_DOWN", "requestFocusForVisibleComponent",
1398                 }),
1399             "TabbedPane.ancestorInputMap",
1400                new UIDefaults.LazyInputMap(new Object[] {
1401                    "ctrl PAGE_DOWN", "navigatePageDown",
1402                      "ctrl PAGE_UP", "navigatePageUp",
1403                           "ctrl UP", "requestFocus",
1404                        "ctrl KP_UP", "requestFocus",
1405                  }),
1406 
1407 
1408             // *** Table
1409             "Table.font", dialogPlain12,
1410             "Table.foreground", controlText,  // cell text color
1411             "Table.background", window,  // cell background color
1412             "Table.selectionForeground", textHighlightText,
1413             "Table.selectionBackground", textHighlight,
1414             "Table.dropLineColor", controlShadow,
1415             "Table.dropLineShortColor", black,
1416             "Table.gridColor", gray,  // grid line color
1417             "Table.focusCellBackground", window,
1418             "Table.focusCellForeground", controlText,
1419             "Table.focusCellHighlightBorder", focusCellHighlightBorder,
1420             "Table.scrollPaneBorder", loweredBevelBorder,
1421             "Table.ancestorInputMap",
1422                new UIDefaults.LazyInputMap(new Object[] {
1423                                "ctrl C", "copy",
1424                                "ctrl V", "paste",
1425                                "ctrl X", "cut",
1426                                  "COPY", "copy",
1427                                 "PASTE", "paste",
1428                                   "CUT", "cut",
1429                        "control INSERT", "copy",
1430                          "shift INSERT", "paste",
1431                          "shift DELETE", "cut",
1432                                 "RIGHT", "selectNextColumn",
1433                              "KP_RIGHT", "selectNextColumn",
1434                           "shift RIGHT", "selectNextColumnExtendSelection",
1435                        "shift KP_RIGHT", "selectNextColumnExtendSelection",
1436                      "ctrl shift RIGHT", "selectNextColumnExtendSelection",
1437                   "ctrl shift KP_RIGHT", "selectNextColumnExtendSelection",
1438                            "ctrl RIGHT", "selectNextColumnChangeLead",
1439                         "ctrl KP_RIGHT", "selectNextColumnChangeLead",
1440                                  "LEFT", "selectPreviousColumn",
1441                               "KP_LEFT", "selectPreviousColumn",
1442                            "shift LEFT", "selectPreviousColumnExtendSelection",
1443                         "shift KP_LEFT", "selectPreviousColumnExtendSelection",
1444                       "ctrl shift LEFT", "selectPreviousColumnExtendSelection",
1445                    "ctrl shift KP_LEFT", "selectPreviousColumnExtendSelection",
1446                             "ctrl LEFT", "selectPreviousColumnChangeLead",
1447                          "ctrl KP_LEFT", "selectPreviousColumnChangeLead",
1448                                  "DOWN", "selectNextRow",
1449                               "KP_DOWN", "selectNextRow",
1450                            "shift DOWN", "selectNextRowExtendSelection",
1451                         "shift KP_DOWN", "selectNextRowExtendSelection",
1452                       "ctrl shift DOWN", "selectNextRowExtendSelection",
1453                    "ctrl shift KP_DOWN", "selectNextRowExtendSelection",
1454                             "ctrl DOWN", "selectNextRowChangeLead",
1455                          "ctrl KP_DOWN", "selectNextRowChangeLead",
1456                                    "UP", "selectPreviousRow",
1457                                 "KP_UP", "selectPreviousRow",
1458                              "shift UP", "selectPreviousRowExtendSelection",
1459                           "shift KP_UP", "selectPreviousRowExtendSelection",
1460                         "ctrl shift UP", "selectPreviousRowExtendSelection",
1461                      "ctrl shift KP_UP", "selectPreviousRowExtendSelection",
1462                               "ctrl UP", "selectPreviousRowChangeLead",
1463                            "ctrl KP_UP", "selectPreviousRowChangeLead",
1464                                  "HOME", "selectFirstColumn",
1465                            "shift HOME", "selectFirstColumnExtendSelection",
1466                       "ctrl shift HOME", "selectFirstRowExtendSelection",
1467                             "ctrl HOME", "selectFirstRow",
1468                                   "END", "selectLastColumn",
1469                             "shift END", "selectLastColumnExtendSelection",
1470                        "ctrl shift END", "selectLastRowExtendSelection",
1471                              "ctrl END", "selectLastRow",
1472                               "PAGE_UP", "scrollUpChangeSelection",
1473                         "shift PAGE_UP", "scrollUpExtendSelection",
1474                    "ctrl shift PAGE_UP", "scrollLeftExtendSelection",
1475                          "ctrl PAGE_UP", "scrollLeftChangeSelection",
1476                             "PAGE_DOWN", "scrollDownChangeSelection",
1477                       "shift PAGE_DOWN", "scrollDownExtendSelection",
1478                  "ctrl shift PAGE_DOWN", "scrollRightExtendSelection",
1479                        "ctrl PAGE_DOWN", "scrollRightChangeSelection",
1480                                   "TAB", "selectNextColumnCell",
1481                             "shift TAB", "selectPreviousColumnCell",
1482                                 "ENTER", "selectNextRowCell",
1483                           "shift ENTER", "selectPreviousRowCell",
1484                                "ctrl A", "selectAll",
1485                            "ctrl SLASH", "selectAll",
1486                       "ctrl BACK_SLASH", "clearSelection",
1487                                "ESCAPE", "cancel",
1488                                    "F2", "startEditing",
1489                                 "SPACE", "addToSelection",
1490                            "ctrl SPACE", "toggleAndAnchor",
1491                           "shift SPACE", "extendTo",
1492                      "ctrl shift SPACE", "moveSelectionTo",
1493                                    "F8", "focusHeader"
1494                  }),
1495             "Table.ancestorInputMap.RightToLeft",
1496                new UIDefaults.LazyInputMap(new Object[] {
1497                                 "RIGHT", "selectPreviousColumn",
1498                              "KP_RIGHT", "selectPreviousColumn",
1499                           "shift RIGHT", "selectPreviousColumnExtendSelection",
1500                        "shift KP_RIGHT", "selectPreviousColumnExtendSelection",
1501                      "ctrl shift RIGHT", "selectPreviousColumnExtendSelection",
1502                   "ctrl shift KP_RIGHT", "selectPreviousColumnExtendSelection",
1503                            "ctrl RIGHT", "selectPreviousColumnChangeLead",
1504                         "ctrl KP_RIGHT", "selectPreviousColumnChangeLead",
1505                                  "LEFT", "selectNextColumn",
1506                               "KP_LEFT", "selectNextColumn",
1507                            "shift LEFT", "selectNextColumnExtendSelection",
1508                         "shift KP_LEFT", "selectNextColumnExtendSelection",
1509                       "ctrl shift LEFT", "selectNextColumnExtendSelection",
1510                    "ctrl shift KP_LEFT", "selectNextColumnExtendSelection",
1511                             "ctrl LEFT", "selectNextColumnChangeLead",
1512                          "ctrl KP_LEFT", "selectNextColumnChangeLead",
1513                          "ctrl PAGE_UP", "scrollRightChangeSelection",
1514                        "ctrl PAGE_DOWN", "scrollLeftChangeSelection",
1515                    "ctrl shift PAGE_UP", "scrollRightExtendSelection",
1516                  "ctrl shift PAGE_DOWN", "scrollLeftExtendSelection",
1517                  }),
1518             "Table.ascendingSortIcon", (LazyValue) t ->
1519                     new SortArrowIcon(true, "Table.sortIconColor"),
1520             "Table.descendingSortIcon", (LazyValue) t ->
1521                     new SortArrowIcon(false, "Table.sortIconColor"),
1522             "Table.sortIconColor", controlShadow,
1523 
1524             "TableHeader.font", dialogPlain12,
1525             "TableHeader.foreground", controlText, // header text color
1526             "TableHeader.background", control, // header background
1527             "TableHeader.cellBorder", tableHeaderBorder,
1528 
1529             // Support for changing the background/border of the currently
1530             // selected header column when the header has the keyboard focus.
1531             "TableHeader.focusCellBackground", table.getColor("text"), // like text component bg
1532             "TableHeader.focusCellForeground", null,
1533             "TableHeader.focusCellBorder", null,
1534             "TableHeader.ancestorInputMap",
1535                new UIDefaults.LazyInputMap(new Object[] {
1536                                 "SPACE", "toggleSortOrder",
1537                                  "LEFT", "selectColumnToLeft",
1538                               "KP_LEFT", "selectColumnToLeft",
1539                                 "RIGHT", "selectColumnToRight",
1540                              "KP_RIGHT", "selectColumnToRight",
1541                              "alt LEFT", "moveColumnLeft",
1542                           "alt KP_LEFT", "moveColumnLeft",
1543                             "alt RIGHT", "moveColumnRight",
1544                          "alt KP_RIGHT", "moveColumnRight",
1545                        "alt shift LEFT", "resizeLeft",
1546                     "alt shift KP_LEFT", "resizeLeft",
1547                       "alt shift RIGHT", "resizeRight",
1548                    "alt shift KP_RIGHT", "resizeRight",
1549                                "ESCAPE", "focusTable",
1550                }),
1551 
1552             // *** Text
1553             "TextField.font", sansSerifPlain12,
1554             "TextField.background", window,
1555             "TextField.foreground", textText,
1556             "TextField.shadow", controlShadow,
1557             "TextField.darkShadow", controlDkShadow,
1558             "TextField.light", controlHighlight,
1559             "TextField.highlight", controlLtHighlight,
1560             "TextField.inactiveForeground", textInactiveText,
1561             "TextField.inactiveBackground", control,
1562             "TextField.selectionBackground", textHighlight,
1563             "TextField.selectionForeground", textHighlightText,
1564             "TextField.caretForeground", textText,
1565             "TextField.caretBlinkRate", caretBlinkRate,
1566             "TextField.border", textFieldBorder,
1567             "TextField.margin", zeroInsets,
1568 
1569             "FormattedTextField.font", sansSerifPlain12,
1570             "FormattedTextField.background", window,
1571             "FormattedTextField.foreground", textText,
1572             "FormattedTextField.inactiveForeground", textInactiveText,
1573             "FormattedTextField.inactiveBackground", control,
1574             "FormattedTextField.selectionBackground", textHighlight,
1575             "FormattedTextField.selectionForeground", textHighlightText,
1576             "FormattedTextField.caretForeground", textText,
1577             "FormattedTextField.caretBlinkRate", caretBlinkRate,
1578             "FormattedTextField.border", textFieldBorder,
1579             "FormattedTextField.margin", zeroInsets,
1580             "FormattedTextField.focusInputMap",
1581               new UIDefaults.LazyInputMap(new Object[] {
1582                            "ctrl C", DefaultEditorKit.copyAction,
1583                            "ctrl V", DefaultEditorKit.pasteAction,
1584                            "ctrl X", DefaultEditorKit.cutAction,
1585                              "COPY", DefaultEditorKit.copyAction,
1586                             "PASTE", DefaultEditorKit.pasteAction,
1587                               "CUT", DefaultEditorKit.cutAction,
1588                    "control INSERT", DefaultEditorKit.copyAction,
1589                      "shift INSERT", DefaultEditorKit.pasteAction,
1590                      "shift DELETE", DefaultEditorKit.cutAction,
1591                        "shift LEFT", DefaultEditorKit.selectionBackwardAction,
1592                     "shift KP_LEFT", DefaultEditorKit.selectionBackwardAction,
1593                       "shift RIGHT", DefaultEditorKit.selectionForwardAction,
1594                    "shift KP_RIGHT", DefaultEditorKit.selectionForwardAction,
1595                         "ctrl LEFT", DefaultEditorKit.previousWordAction,
1596                      "ctrl KP_LEFT", DefaultEditorKit.previousWordAction,
1597                        "ctrl RIGHT", DefaultEditorKit.nextWordAction,
1598                     "ctrl KP_RIGHT", DefaultEditorKit.nextWordAction,
1599                   "ctrl shift LEFT", DefaultEditorKit.selectionPreviousWordAction,
1600                "ctrl shift KP_LEFT", DefaultEditorKit.selectionPreviousWordAction,
1601                  "ctrl shift RIGHT", DefaultEditorKit.selectionNextWordAction,
1602               "ctrl shift KP_RIGHT", DefaultEditorKit.selectionNextWordAction,
1603                            "ctrl A", DefaultEditorKit.selectAllAction,
1604                              "HOME", DefaultEditorKit.beginLineAction,
1605                               "END", DefaultEditorKit.endLineAction,
1606                        "shift HOME", DefaultEditorKit.selectionBeginLineAction,
1607                         "shift END", DefaultEditorKit.selectionEndLineAction,
1608                        "BACK_SPACE", DefaultEditorKit.deletePrevCharAction,
1609                  "shift BACK_SPACE", DefaultEditorKit.deletePrevCharAction,
1610                            "ctrl H", DefaultEditorKit.deletePrevCharAction,
1611                            "DELETE", DefaultEditorKit.deleteNextCharAction,
1612                       "ctrl DELETE", DefaultEditorKit.deleteNextWordAction,
1613                   "ctrl BACK_SPACE", DefaultEditorKit.deletePrevWordAction,
1614                             "RIGHT", DefaultEditorKit.forwardAction,
1615                              "LEFT", DefaultEditorKit.backwardAction,
1616                          "KP_RIGHT", DefaultEditorKit.forwardAction,
1617                           "KP_LEFT", DefaultEditorKit.backwardAction,
1618                             "ENTER", JTextField.notifyAction,
1619                   "ctrl BACK_SLASH", "unselect",
1620                   "control shift O", "toggle-componentOrientation",
1621                            "ESCAPE", "reset-field-edit",
1622                                "UP", "increment",
1623                             "KP_UP", "increment",
1624                              "DOWN", "decrement",
1625                           "KP_DOWN", "decrement",
1626               }),
1627 
1628             "PasswordField.font", monospacedPlain12,
1629             "PasswordField.background", window,
1630             "PasswordField.foreground", textText,
1631             "PasswordField.inactiveForeground", textInactiveText,
1632             "PasswordField.inactiveBackground", control,
1633             "PasswordField.selectionBackground", textHighlight,
1634             "PasswordField.selectionForeground", textHighlightText,
1635             "PasswordField.caretForeground", textText,
1636             "PasswordField.caretBlinkRate", caretBlinkRate,
1637             "PasswordField.border", textFieldBorder,
1638             "PasswordField.margin", zeroInsets,
1639             "PasswordField.echoChar", '*',
1640 
1641             "TextArea.font", monospacedPlain12,
1642             "TextArea.background", window,
1643             "TextArea.foreground", textText,
1644             "TextArea.inactiveForeground", textInactiveText,
1645             "TextArea.selectionBackground", textHighlight,
1646             "TextArea.selectionForeground", textHighlightText,
1647             "TextArea.caretForeground", textText,
1648             "TextArea.caretBlinkRate", caretBlinkRate,
1649             "TextArea.border", marginBorder,
1650             "TextArea.margin", zeroInsets,
1651 
1652             "TextPane.font", serifPlain12,
1653             "TextPane.background", white,
1654             "TextPane.foreground", textText,
1655             "TextPane.selectionBackground", textHighlight,
1656             "TextPane.selectionForeground", textHighlightText,
1657             "TextPane.caretForeground", textText,
1658             "TextPane.caretBlinkRate", caretBlinkRate,
1659             "TextPane.inactiveForeground", textInactiveText,
1660             "TextPane.border", marginBorder,
1661             "TextPane.margin", editorMargin,
1662 
1663             "EditorPane.font", serifPlain12,
1664             "EditorPane.background", white,
1665             "EditorPane.foreground", textText,
1666             "EditorPane.selectionBackground", textHighlight,
1667             "EditorPane.selectionForeground", textHighlightText,
1668             "EditorPane.caretForeground", textText,
1669             "EditorPane.caretBlinkRate", caretBlinkRate,
1670             "EditorPane.inactiveForeground", textInactiveText,
1671             "EditorPane.border", marginBorder,
1672             "EditorPane.margin", editorMargin,
1673 
1674             "html.pendingImage", SwingUtilities2.makeIcon(getClass(),
1675                                     BasicLookAndFeel.class,
1676                                     "icons/image-delayed.png"),
1677             "html.missingImage", SwingUtilities2.makeIcon(getClass(),
1678                                     BasicLookAndFeel.class,
1679                                     "icons/image-failed.png"),
1680             // *** TitledBorder
1681             "TitledBorder.font", dialogPlain12,
1682             "TitledBorder.titleColor", controlText,
1683             "TitledBorder.border", etchedBorder,
1684 
1685             // *** ToolBar
1686             "ToolBar.font", dialogPlain12,
1687             "ToolBar.background", control,
1688             "ToolBar.foreground", controlText,
1689             "ToolBar.shadow", controlShadow,
1690             "ToolBar.darkShadow", controlDkShadow,
1691             "ToolBar.light", controlHighlight,
1692             "ToolBar.highlight", controlLtHighlight,
1693             "ToolBar.dockingBackground", control,
1694             "ToolBar.dockingForeground", red,
1695             "ToolBar.floatingBackground", control,
1696             "ToolBar.floatingForeground", darkGray,
1697             "ToolBar.border", etchedBorder,
1698             "ToolBar.separatorSize", toolBarSeparatorSize,
1699             "ToolBar.ancestorInputMap",
1700                new UIDefaults.LazyInputMap(new Object[] {
1701                         "UP", "navigateUp",
1702                      "KP_UP", "navigateUp",
1703                       "DOWN", "navigateDown",
1704                    "KP_DOWN", "navigateDown",
1705                       "LEFT", "navigateLeft",
1706                    "KP_LEFT", "navigateLeft",
1707                      "RIGHT", "navigateRight",
1708                   "KP_RIGHT", "navigateRight"
1709                  }),
1710 
1711             // *** ToolTips
1712             "ToolTip.font", sansSerifPlain12,
1713             "ToolTip.background", table.get("info"),
1714             "ToolTip.foreground", table.get("infoText"),
1715             "ToolTip.border", blackLineBorder,
1716             // ToolTips also support backgroundInactive, borderInactive,
1717             // and foregroundInactive
1718 
1719         // *** ToolTipManager
1720             // ToolTipManager.enableToolTipMode currently supports:
1721             // "allWindows" (default):
1722             //     enables tool tips for all windows of all java applications,
1723             //     whether the windows are active or inactive
1724             // "activeApplication"
1725             //     enables tool tips for windows of an application only when
1726             //     the application has an active window
1727             "ToolTipManager.enableToolTipMode", "allWindows",
1728 
1729         // *** Tree
1730             "Tree.paintLines", Boolean.TRUE,
1731             "Tree.lineTypeDashed", Boolean.FALSE,
1732             "Tree.font", dialogPlain12,
1733             "Tree.background", window,
1734             "Tree.foreground", textText,
1735             "Tree.hash", gray,
1736             "Tree.textForeground", textText,
1737             "Tree.textBackground", table.get("text"),
1738             "Tree.selectionForeground", textHighlightText,
1739             "Tree.selectionBackground", textHighlight,
1740             "Tree.selectionBorderColor", black,
1741             "Tree.dropLineColor", controlShadow,
1742             "Tree.editorBorder", blackLineBorder,
1743             "Tree.leftChildIndent", 7,
1744             "Tree.rightChildIndent", 13,
1745             "Tree.rowHeight", 16,
1746             "Tree.scrollsOnExpand", Boolean.TRUE,
1747             "Tree.openIcon", SwingUtilities2.makeIcon(getClass(),
1748                                                       BasicLookAndFeel.class,
1749                                                       "icons/TreeOpen.gif"),
1750             "Tree.closedIcon", SwingUtilities2.makeIcon(getClass(),
1751                                                         BasicLookAndFeel.class,
1752                                                         "icons/TreeClosed.gif"),
1753             "Tree.leafIcon", SwingUtilities2.makeIcon(getClass(),
1754                                                       BasicLookAndFeel.class,
1755                                                       "icons/TreeLeaf.gif"),
1756             "Tree.expandedIcon", null,
1757             "Tree.collapsedIcon", null,
1758             "Tree.changeSelectionWithFocus", Boolean.TRUE,
1759             "Tree.drawsFocusBorderAroundIcon", Boolean.FALSE,
1760             "Tree.timeFactor", oneThousand,
1761             "Tree.focusInputMap",
1762                new UIDefaults.LazyInputMap(new Object[] {
1763                                  "ctrl C", "copy",
1764                                  "ctrl V", "paste",
1765                                  "ctrl X", "cut",
1766                                    "COPY", "copy",
1767                                   "PASTE", "paste",
1768                                     "CUT", "cut",
1769                          "control INSERT", "copy",
1770                            "shift INSERT", "paste",
1771                            "shift DELETE", "cut",
1772                                      "UP", "selectPrevious",
1773                                   "KP_UP", "selectPrevious",
1774                                "shift UP", "selectPreviousExtendSelection",
1775                             "shift KP_UP", "selectPreviousExtendSelection",
1776                           "ctrl shift UP", "selectPreviousExtendSelection",
1777                        "ctrl shift KP_UP", "selectPreviousExtendSelection",
1778                                 "ctrl UP", "selectPreviousChangeLead",
1779                              "ctrl KP_UP", "selectPreviousChangeLead",
1780                                    "DOWN", "selectNext",
1781                                 "KP_DOWN", "selectNext",
1782                              "shift DOWN", "selectNextExtendSelection",
1783                           "shift KP_DOWN", "selectNextExtendSelection",
1784                         "ctrl shift DOWN", "selectNextExtendSelection",
1785                      "ctrl shift KP_DOWN", "selectNextExtendSelection",
1786                               "ctrl DOWN", "selectNextChangeLead",
1787                            "ctrl KP_DOWN", "selectNextChangeLead",
1788                                   "RIGHT", "selectChild",
1789                                "KP_RIGHT", "selectChild",
1790                                    "LEFT", "selectParent",
1791                                 "KP_LEFT", "selectParent",
1792                                 "PAGE_UP", "scrollUpChangeSelection",
1793                           "shift PAGE_UP", "scrollUpExtendSelection",
1794                      "ctrl shift PAGE_UP", "scrollUpExtendSelection",
1795                            "ctrl PAGE_UP", "scrollUpChangeLead",
1796                               "PAGE_DOWN", "scrollDownChangeSelection",
1797                         "shift PAGE_DOWN", "scrollDownExtendSelection",
1798                    "ctrl shift PAGE_DOWN", "scrollDownExtendSelection",
1799                          "ctrl PAGE_DOWN", "scrollDownChangeLead",
1800                                    "HOME", "selectFirst",
1801                              "shift HOME", "selectFirstExtendSelection",
1802                         "ctrl shift HOME", "selectFirstExtendSelection",
1803                               "ctrl HOME", "selectFirstChangeLead",
1804                                     "END", "selectLast",
1805                               "shift END", "selectLastExtendSelection",
1806                          "ctrl shift END", "selectLastExtendSelection",
1807                                "ctrl END", "selectLastChangeLead",
1808                                      "F2", "startEditing",
1809                                  "ctrl A", "selectAll",
1810                              "ctrl SLASH", "selectAll",
1811                         "ctrl BACK_SLASH", "clearSelection",
1812                               "ctrl LEFT", "scrollLeft",
1813                            "ctrl KP_LEFT", "scrollLeft",
1814                              "ctrl RIGHT", "scrollRight",
1815                           "ctrl KP_RIGHT", "scrollRight",
1816                                   "SPACE", "addToSelection",
1817                              "ctrl SPACE", "toggleAndAnchor",
1818                             "shift SPACE", "extendTo",
1819                        "ctrl shift SPACE", "moveSelectionTo"
1820                  }),
1821             "Tree.focusInputMap.RightToLeft",
1822                new UIDefaults.LazyInputMap(new Object[] {
1823                                   "RIGHT", "selectParent",
1824                                "KP_RIGHT", "selectParent",
1825                                    "LEFT", "selectChild",
1826                                 "KP_LEFT", "selectChild",
1827                  }),
1828             "Tree.ancestorInputMap",
1829                new UIDefaults.LazyInputMap(new Object[] {
1830                      "ESCAPE", "cancel"
1831                  }),
1832             // Bind specific keys that can invoke popup on currently
1833             // focused JComponent
1834             "RootPane.ancestorInputMap",
1835                 new UIDefaults.LazyInputMap(new Object[] {
1836                      "shift F10", "postPopup",
1837                   "CONTEXT_MENU", "postPopup"
1838                   }),
1839 
1840             // These bindings are only enabled when there is a default
1841             // button set on the rootpane.
1842             "RootPane.defaultButtonWindowKeyBindings", new Object[] {
1843                              "ENTER", "press",
1844                     "released ENTER", "release",
1845                         "ctrl ENTER", "press",
1846                "ctrl released ENTER", "release"
1847               },
1848         };
1849 
1850         table.putDefaults(defaults);
1851     }
1852 
1853     static int getFocusAcceleratorKeyMask() {
1854         Toolkit tk = Toolkit.getDefaultToolkit();
1855         if (tk instanceof SunToolkit) {
1856             return ((SunToolkit)tk).getFocusAcceleratorKeyMask();
1857         }
1858         return ActionEvent.ALT_MASK;
1859     }
1860 
1861 
1862 
1863     /**
1864      * Returns the ui that is of type <code>klass</code>, or null if
1865      * one can not be found.
1866      */
1867     static Object getUIOfType(ComponentUI ui, Class<?> klass) {
1868         if (klass.isInstance(ui)) {
1869             return ui;
1870         }
1871         return null;
1872     }
1873 
1874     // ********* Auditory Cue support methods and objects *********
1875     // also see the "AuditoryCues" section of the defaults table
1876 
1877     /**
1878      * Returns an <code>ActionMap</code> containing the audio actions
1879      * for this look and feel.
1880      * <P>
1881      * The returned <code>ActionMap</code> contains <code>Actions</code> that
1882      * embody the ability to render an auditory cue. These auditory
1883      * cues map onto user and system activities that may be useful
1884      * for an end user to know about (such as a dialog box appearing).
1885      * <P>
1886      * At the appropriate time,
1887      * the {@code ComponentUI} is responsible for obtaining an
1888      * <code>Action</code> out of the <code>ActionMap</code> and passing
1889      * it to <code>playSound</code>.
1890      * <P>
1891      * This method first looks up the {@code ActionMap} from the
1892      * defaults using the key {@code "AuditoryCues.actionMap"}.
1893      * <p>
1894      * If the value is {@code non-null}, it is returned. If the value
1895      * of the default {@code "AuditoryCues.actionMap"} is {@code null}
1896      * and the value of the default {@code "AuditoryCues.cueList"} is
1897      * {@code non-null}, an {@code ActionMapUIResource} is created and
1898      * populated. Population is done by iterating over each of the
1899      * elements of the {@code "AuditoryCues.cueList"} array, and
1900      * invoking {@code createAudioAction()} to create an {@code
1901      * Action} for each element.  The resulting {@code Action} is
1902      * placed in the {@code ActionMapUIResource}, using the array
1903      * element as the key.  For example, if the {@code
1904      * "AuditoryCues.cueList"} array contains a single-element, {@code
1905      * "audioKey"}, the {@code ActionMapUIResource} is created, then
1906      * populated by way of {@code actionMap.put(cueList[0],
1907      * createAudioAction(cueList[0]))}.
1908      * <p>
1909      * If the value of the default {@code "AuditoryCues.actionMap"} is
1910      * {@code null} and the value of the default
1911      * {@code "AuditoryCues.cueList"} is {@code null}, an empty
1912      * {@code ActionMapUIResource} is created.
1913      *
1914      *
1915      * @return      an ActionMap containing {@code Actions}
1916      *              responsible for playing auditory cues
1917      * @throws ClassCastException if the value of the
1918      *         default {@code "AuditoryCues.actionMap"} is not an
1919      *         {@code ActionMap}, or the value of the default
1920      *         {@code "AuditoryCues.cueList"} is not an {@code Object[]}
1921      * @see #createAudioAction
1922      * @see #playSound(Action)
1923      * @since 1.4
1924      */
1925     protected ActionMap getAudioActionMap() {
1926         ActionMap audioActionMap = (ActionMap)UIManager.get(
1927                                               "AuditoryCues.actionMap");
1928         if (audioActionMap == null) {
1929             Object[] acList = (Object[])UIManager.get("AuditoryCues.cueList");
1930             if (acList != null) {
1931                 audioActionMap = new ActionMapUIResource();
1932                 for(int counter = acList.length-1; counter >= 0; counter--) {
1933                     audioActionMap.put(acList[counter],
1934                                        createAudioAction(acList[counter]));
1935                 }
1936             }
1937             UIManager.getLookAndFeelDefaults().put("AuditoryCues.actionMap",
1938                                                    audioActionMap);
1939         }
1940         return audioActionMap;
1941     }
1942 
1943     /**
1944      * Creates and returns an {@code Action} used to play a sound.
1945      * <p>
1946      * If {@code key} is {@code non-null}, an {@code Action} is created
1947      * using the value from the defaults with key {@code key}. The value
1948      * identifies the sound resource to load when
1949      * {@code actionPerformed} is invoked on the {@code Action}. The
1950      * sound resource is loaded into a {@code byte[]} by way of
1951      * {@code getClass().getResourceAsStream()}.
1952      *
1953      * @param key the key identifying the audio action
1954      * @return      an {@code Action} used to play the source, or {@code null}
1955      *              if {@code key} is {@code null}
1956      * @see #playSound(Action)
1957      * @since 1.4
1958      */
1959     protected Action createAudioAction(Object key) {
1960         if (key != null) {
1961             String audioKey = (String)key;
1962             String audioValue = (String)UIManager.get(key);
1963             return new AudioAction(audioKey, audioValue);
1964         } else {
1965             return null;
1966         }
1967     }
1968 
1969     /**
1970      * Pass the name String to the super constructor. This is used
1971      * later to identify the Action and decide whether to play it or
1972      * not. Store the resource String. I is used to get the audio
1973      * resource. In this case, the resource is an audio file.
1974      *
1975      * @since 1.4
1976      */
1977     private class AudioAction extends AbstractAction implements LineListener {
1978         // We strive to only play one sound at a time (other platforms
1979         // appear to do this). This is done by maintaining the field
1980         // clipPlaying. Every time a sound is to be played,
1981         // cancelCurrentSound is invoked to cancel any sound that may be
1982         // playing.
1983         private String audioResource;
1984         private byte[] audioBuffer;
1985 
1986         /**
1987          * The String is the name of the Action and
1988          * points to the audio resource.
1989          * The byte[] is a buffer of the audio bits.
1990          */
1991         public AudioAction(String name, String resource) {
1992             super(name);
1993             audioResource = resource;
1994         }
1995 
1996         public void actionPerformed(ActionEvent e) {
1997             if (audioBuffer == null) {
1998                 audioBuffer = loadAudioData(audioResource);
1999             }
2000             if (audioBuffer != null) {
2001                 cancelCurrentSound(null);
2002                 try {
2003                     AudioInputStream soundStream =
2004                         AudioSystem.getAudioInputStream(
2005                             new ByteArrayInputStream(audioBuffer));
2006                     DataLine.Info info =
2007                         new DataLine.Info(Clip.class, soundStream.getFormat());
2008                     Clip clip = (Clip) AudioSystem.getLine(info);
2009                     clip.open(soundStream);
2010                     clip.addLineListener(this);
2011 
2012                     synchronized(audioLock) {
2013                         clipPlaying = clip;
2014                     }
2015 
2016                     clip.start();
2017                 } catch (Exception ex) {}
2018             }
2019         }
2020 
2021         public void update(LineEvent event) {
2022             if (event.getType() == LineEvent.Type.STOP) {
2023                 cancelCurrentSound((Clip)event.getLine());
2024             }
2025         }
2026 
2027         /**
2028          * If the parameter is null, or equal to the currently
2029          * playing sound, then cancel the currently playing sound.
2030          */
2031         private void cancelCurrentSound(Clip clip) {
2032             Clip lastClip = null;
2033 
2034             synchronized(audioLock) {
2035                 if (clip == null || clip == clipPlaying) {
2036                     lastClip = clipPlaying;
2037                     clipPlaying = null;
2038                 }
2039             }
2040 
2041             if (lastClip != null) {
2042                 lastClip.removeLineListener(this);
2043                 lastClip.close();
2044             }
2045         }
2046     }
2047 
2048     /**
2049      * Utility method that loads audio bits for the specified
2050      * <code>soundFile</code> filename. If this method is unable to
2051      * build a viable path name from the <code>baseClass</code> and
2052      * <code>soundFile</code> passed into this method, it will
2053      * return <code>null</code>.
2054      *
2055      * @param soundFile    the name of the audio file to be retrieved
2056      *                     from disk
2057      * @return             A byte[] with audio data or null
2058      * @since 1.4
2059      */
2060     private byte[] loadAudioData(final String soundFile){
2061         if (soundFile == null) {
2062             return null;
2063         }
2064         /* Copy resource into a byte array.  This is
2065          * necessary because several browsers consider
2066          * Class.getResource a security risk since it
2067          * can be used to load additional classes.
2068          * Class.getResourceAsStream just returns raw
2069          * bytes, which we can convert to a sound.
2070          */
2071         byte[] buffer = AccessController.doPrivileged(
2072                                                  new PrivilegedAction<byte[]>() {
2073                 public byte[] run() {
2074                     try {
2075                         InputStream resource = BasicLookAndFeel.this.
2076                             getClass().getResourceAsStream(soundFile);
2077                         if (resource == null) {
2078                             return null;
2079                         }
2080                         BufferedInputStream in =
2081                             new BufferedInputStream(resource);
2082                         ByteArrayOutputStream out =
2083                             new ByteArrayOutputStream(1024);
2084                         byte[] buffer = new byte[1024];
2085                         int n;
2086                         while ((n = in.read(buffer)) > 0) {
2087                             out.write(buffer, 0, n);
2088                         }
2089                         in.close();
2090                         out.flush();
2091                         buffer = out.toByteArray();
2092                         return buffer;
2093                     } catch (IOException ioe) {
2094                         System.err.println(ioe.toString());
2095                         return null;
2096                     }
2097                 }
2098             });
2099         if (buffer == null) {
2100             System.err.println(getClass().getName() + "/" +
2101                                soundFile + " not found.");
2102             return null;
2103         }
2104         if (buffer.length == 0) {
2105             System.err.println("warning: " + soundFile +
2106                                " is zero-length");
2107             return null;
2108         }
2109         return buffer;
2110     }
2111 
2112     /**
2113      * If necessary, invokes {@code actionPerformed} on
2114      * {@code audioAction} to play a sound.
2115      * The {@code actionPerformed} method is invoked if the value of
2116      * the {@code "AuditoryCues.playList"} default is a {@code
2117      * non-null} {@code Object[]} containing a {@code String} entry
2118      * equal to the name of the {@code audioAction}.
2119      *
2120      * @param audioAction an Action that knows how to render the audio
2121      *                    associated with the system or user activity
2122      *                    that is occurring; a value of {@code null}, is
2123      *                    ignored
2124      * @throws ClassCastException if {@code audioAction} is {@code non-null}
2125      *         and the value of the default {@code "AuditoryCues.playList"}
2126      *         is not an {@code Object[]}
2127      * @since 1.4
2128      */
2129     protected void playSound(Action audioAction) {
2130         if (audioAction != null) {
2131             Object[] audioStrings = (Object[])
2132                                     UIManager.get("AuditoryCues.playList");
2133             if (audioStrings != null) {
2134                 // create a HashSet to help us decide to play or not
2135                 HashSet<Object> audioCues = new HashSet<Object>();
2136                 for (Object audioString : audioStrings) {
2137                     audioCues.add(audioString);
2138                 }
2139                 // get the name of the Action
2140                 String actionName = (String)audioAction.getValue(Action.NAME);
2141                 // if the actionName is in the audioCues HashSet, play it.
2142                 if (audioCues.contains(actionName)) {
2143                     audioAction.actionPerformed(new
2144                         ActionEvent(this, ActionEvent.ACTION_PERFORMED,
2145                                     actionName));
2146                 }
2147             }
2148         }
2149     }
2150 
2151 
2152     /**
2153      * Sets the parent of the passed in ActionMap to be the audio action
2154      * map.
2155      */
2156     static void installAudioActionMap(ActionMap map) {
2157         LookAndFeel laf = UIManager.getLookAndFeel();
2158         if (laf instanceof BasicLookAndFeel) {
2159             map.setParent(((BasicLookAndFeel)laf).getAudioActionMap());
2160         }
2161     }
2162 
2163 
2164     /**
2165      * Helper method to play a named sound.
2166      *
2167      * @param c JComponent to play the sound for.
2168      * @param actionKey Key for the sound.
2169      */
2170     static void playSound(JComponent c, Object actionKey) {
2171         LookAndFeel laf = UIManager.getLookAndFeel();
2172         if (laf instanceof BasicLookAndFeel) {
2173             ActionMap map = c.getActionMap();
2174             if (map != null) {
2175                 Action audioAction = map.get(actionKey);
2176                 if (audioAction != null) {
2177                     // pass off firing the Action to a utility method
2178                     ((BasicLookAndFeel)laf).playSound(audioAction);
2179                 }
2180             }
2181         }
2182     }
2183 
2184     /**
2185      * This class contains listener that watches for all the mouse
2186      * events that can possibly invoke popup on the component
2187      */
2188     class AWTEventHelper implements AWTEventListener,PrivilegedAction<Object> {
2189         AWTEventHelper() {
2190             super();
2191             AccessController.doPrivileged(this);
2192         }
2193 
2194         public Object run() {
2195             Toolkit tk = Toolkit.getDefaultToolkit();
2196             if(invocator == null) {
2197                 tk.addAWTEventListener(this, AWTEvent.MOUSE_EVENT_MASK);
2198             } else {
2199                 tk.removeAWTEventListener(invocator);
2200             }
2201             // Return value not used.
2202             return null;
2203         }
2204 
2205         public void eventDispatched(AWTEvent ev) {
2206             int eventID = ev.getID();
2207             if((eventID & AWTEvent.MOUSE_EVENT_MASK) != 0) {
2208                 MouseEvent me = (MouseEvent) ev;
2209                 if(me.isPopupTrigger()) {
2210                     MenuElement[] elems = MenuSelectionManager
2211                             .defaultManager()
2212                             .getSelectedPath();
2213                     if(elems != null && elems.length != 0) {
2214                         return;
2215                         // We shall not interfere with already opened menu
2216                     }
2217                     Object c = me.getSource();
2218                     JComponent src = null;
2219                     if(c instanceof JComponent) {
2220                         src = (JComponent) c;
2221                     } else if(c instanceof BasicSplitPaneDivider) {
2222                         // Special case - if user clicks on divider we must
2223                         // invoke popup from the SplitPane
2224                         src = (JComponent)
2225                             ((BasicSplitPaneDivider)c).getParent();
2226                     }
2227                     if(src != null) {
2228                         if(src.getComponentPopupMenu() != null) {
2229                             Point pt = src.getPopupLocation(me);
2230                             if(pt == null) {
2231                                 pt = me.getPoint();
2232                                 pt = SwingUtilities.convertPoint((Component)c,
2233                                                                   pt, src);
2234                             }
2235                             src.getComponentPopupMenu().show(src, pt.x, pt.y);
2236                             me.consume();
2237                         }
2238                     }
2239                 }
2240             }
2241             /* Activate a JInternalFrame if necessary. */
2242             if (eventID == MouseEvent.MOUSE_PRESSED) {
2243                 Object object = ev.getSource();
2244                 if (!(object instanceof Component)) {
2245                     return;
2246                 }
2247                 Component component = (Component)object;
2248                 if (component != null) {
2249                     Component parent = component;
2250                     while (parent != null && !(parent instanceof Window)) {
2251                         if (parent instanceof JInternalFrame) {
2252                             // Activate the frame.
2253                             try { ((JInternalFrame)parent).setSelected(true); }
2254                             catch (PropertyVetoException e1) { }
2255                         }
2256                         parent = parent.getParent();
2257                     }
2258                 }
2259             }
2260         }
2261     }
2262 }