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