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
26package javax.swing.plaf.basic;
27
28import java.awt.Font;
29import java.awt.Color;
30import java.awt.SystemColor;
31import java.awt.event.*;
32import java.awt.Insets;
33import java.awt.Component;
34import java.awt.Container;
35import java.awt.FocusTraversalPolicy;
36import java.awt.AWTEvent;
37import java.awt.Toolkit;
38import java.awt.Point;
39import java.net.URL;
40import java.io.*;
41import java.awt.Dimension;
42import java.awt.KeyboardFocusManager;
43import java.security.AccessController;
44import java.security.PrivilegedAction;
45import java.util.*;
46import java.lang.reflect.*;
47import javax.sound.sampled.*;
48
49import sun.awt.AppContext;
50import sun.awt.SunToolkit;
51import sun.swing.SwingAccessor;
52import sun.swing.SwingUtilities2;
53import sun.swing.icon.SortArrowIcon;
54
55import javax.swing.LookAndFeel;
56import javax.swing.AbstractAction;
57import javax.swing.Action;
58import javax.swing.ActionMap;
59import javax.swing.BorderFactory;
60import javax.swing.JComponent;
61import javax.swing.ImageIcon;
62import javax.swing.UIDefaults;
63import javax.swing.UIManager;
64import javax.swing.KeyStroke;
65import javax.swing.JTextField;
66import javax.swing.DefaultListCellRenderer;
67import javax.swing.FocusManager;
68import javax.swing.LayoutFocusTraversalPolicy;
69import javax.swing.SwingUtilities;
70import javax.swing.MenuSelectionManager;
71import javax.swing.MenuElement;
72import javax.swing.border.*;
73import javax.swing.plaf.*;
74import javax.swing.text.JTextComponent;
75import javax.swing.text.DefaultEditorKit;
76import javax.swing.JInternalFrame;
77import static javax.swing.UIDefaults.LazyValue;
78import java.beans.PropertyVetoException;
79import java.awt.Window;
80import java.beans.PropertyChangeListener;
81import 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
107public 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}
2261