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