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