Keyboard Navigation Hiding

One of the new features that was introduced in Windows 2000 has been a display property which will hide the keyboard mnemonic for a menu item or a dialog control until the Alt key is pressed. In other words, all the underlined characters which represent an Alt key combination to invoke that menu or control will not be drawn until the user indicates the intention to invoke a command with the keyboard rather than the mouse. The result of this behavior is to provide an interface which is not visually cluttered with underlined characters for people who choose to navigate the user interface with the mouse.

The keyboard navigation hiding feature will be automatically enabled on Windows 2000 if the application uses the Windows look and feel and the "Hide keyboard navigation indicators until I use the Alt key" property is enabled in the Windows 2000 "Display Properties" control panel applet.

Implementation Details

These details will be of use to developers who are extending look and feels. The keyboard navigation hiding feature will automatically be enabled when a Windows Look and Feel Java application is run on Windows 2000.

When the WindowsLookAndFeel is instantiated, it will read the DesktopProperty "win.menu.keyboardCuesOn". This value is stored in the UIManager and can be referenced using the key: "Button.isMnemonicHidingEnabled". The static methods setMnemonicHidden and isMnemonicHidden in WindowsLookAndFeelprovide access to this value.

Hiding the mnemonics in the menus

The existing BasicMenuItemUI.paintMenuItem() method is responsible for rendering the background, text, icon and mnemonic of a menu item. A new protected method, paintText() was extracted from paintMenuItem(), which is consistent in name and signature to a similar method in the BasicButtonUI hierarchy.

The paintText() methods are overloaded in WindowsMenuItemUI and WindowsMenuUI. The body of the overloaded paintText method checks the isMnemonicEnabled flag in the WindowsLookAndFeel class to determine if the mnemonic should be hidden and then appropriately renders the text.

Hiding the mnemonic in controls

BasicButtonUI already defined a protected method paintText. The WindowsButtonUI and similar classes overloaded this method in much the same manner. A new class was introduced, WindowsGraphicsUtils, to consolidate all the paintText methods. This was done because the Windows...UI classes don't follow the same inheritance hierarchy as the Basic..UI classes.

A new RootPaneUI delegate called WindowsRootPaneUI was created for the Windows look and feel. This class had an action registered to reset the mnemonic hidden bit and repaint the ui when the Alt key was pressed.

New API

All these methods were added as result of implementing this feature. These methods will only have value to developers who wish to extend or create a Look and Feel.

New method for BasicMenuItemUI:

    /**
     * Renders the text of the current menu item.
     *
     * @param g graphics context
     * @param menuItem menu item to render
     * @param textRect bounding rectangle for rendering the text
     * @param text String to render
     * @since 1.4
     */
     protected void paintText(Graphics g, JMenuItem menuItem, Rectangle textRect, String text)

New class WindowsRootPaneUI:

    /**
     * Windows implementation of RootPaneUI. One WindowsRootPaneUI
     * object is shared between all JRootPane instances.
     *
     * @version 1.1 08/16/00
     * @author Mark Davidson
     * @since 1.4
     */
     public class WindowsRootPaneUI extends BasicRootPaneUI

New class WindowsGraphicsUtils:

    /**
     * A collection of static utility methods used for rendering the
     * Windows look and feel.
     *
     * @Version 1.1 08/16/00 
     * @author Mark Davidson
     * @since 1.4
     */
     public class WindowsGraphicsUtils 

New methods for WindowsLookAndFeel:

    /**
     * Sets the state of the hide mnemonic flag. This flag is used by the
     * component UI delegates to determine if the mnemonic should be rendered.
     * This method is a non operation if the underlying operating system
     * does not support the mnemonic hiding feature.
     *
     * @param hide true if mnemonics should be hidden
     * @since 1.4
     */
     public static void setMnemonicHidden(boolean hide)

    /**
     * Gets the state of the hide mnemonic flag. This only has meaning
     * if this feature is supported by the underlying OS.
     *
     * @return true if mnemonics are hidden, otherwise, false
     * @see #setMnemonicHidden
     * @since 1.4
     */
     public static Boolean isMnemonicHidden()

    /**
     * Gets the state of the flag which indicates if the old Windows
     * look and feel should be rendered. This flag is used by the
     * component UI delegates as a hint to determine which style the component
     * should be rendered.
     *
     * @return true if Windows 95 and Windows NT 4 look and feel should
     *     be rendered
     * @since 1.4
     */
     public static Boolean isClassicWindows()