Java AWT: Mouseless Operation


Last Updated: February 3, 1997

Purpose

Although typical GUIs today are designed to be driven with a mouse, there are numerous circumstances where mouseless operation in a GUI becomes important (and sometimes even critical) for usability. Some of those circumstances include:

AWT1.0 does not provide any explicit facilities for building mouseless operation into Java programs, except where the native peers components provide it by default (i.e. tabbed focus traversal, space-bar activation, etc.). For JDK1.1, the AWT will add some baseline support to better enable mouseless mode in Java programs, although it by no means provides a 100% solution to this problem. This support will be expanded in subsequent releases. The two features that will be in 1.1 are:


Focus Traversal

Focus traversal is defined to be the ability to use keystrokes (not the mouse) to traverse components capable of accepting keyboard focus. Those keystrokes are defined to be <Tab> to move forward and <Shift-Tab> to move backward. Once the focus is owned by a component then it should be possible to activate/drive that component with further defined keystrokes (such as <space> to press a Button). It is the responsibility of the component (not the AWT), to implement the proper activation once it has focus

A component which is capable of accepting focus in this way should always render some form of visual feedback when it gets focus so that the user can easily see which component has focus as the user traverses using Tab/Shift-Tab. Typically this feedback takes the form of a colored bounding box drawn around the component.

The native toolkits on each platform provide varying degrees of support for focus traversal by default. However, explicit support for this has been implemented in the common java AWT code so that the behavior is more consistent across platforms.

The Focus Traversal API

The API is extremely simple; it consists of a new method on java.awt.Component and java.awt.peer.ComponentPeer:
	public boolean isFocusTraversable()

This method returns true if the component is a type inherently capable of accepting keyboard focus and returns false otherwise.

The reason this method also exists for the peer class is because the native peer components that are created by the AWT components have different traversal rules on different platforms. This allows the tailoring of this attribute appropriately on each platform (for example, on the Mac, Buttons cannot take focus, but on Motif and Win32, they can).

All existing AWT components should have this attribute set properly by default, but there is the option to subclass a component and override this method to return a value appropriate for your program. In particular, if you are subclassing java.awt.Canvas to build your own custom component that is designed to take keyboard focus, then you should do the following three things:

  1. override isFocusTraversable() to return true (Canvas returns false by default)
  2. catch the mouse-down event on the component and invoke requestFocus() (to implement click-to-type for your component)
  3. when your component gets focus, provide visual feedback indicating it has the focus

If your component does not adhere to the above steps, users may have trouble getting focus into your component.

The AWT internally tracks which component has the focus so that it can move the focus forward or backward in response to a Tab or Shift-Tab keyboard event. This is handled by a private FocusManager object that is registered on the Window. The FocusManager can manage this focus migration correctly, no matter how deeply nested a window's containers are. The order of this traversal will be equal to the order of the components contained in the containers; by default this will be equal to the order the children were added to the container, however the Container's add(Component c, int pos) method can be used to control this ordering. The FocusManager automatically checks to see if a "focusTraversable" component is both visible and active before it assigns it the focus (hence, the isFocusTraversable() method need not take this state into account for its return value).

Note: We realize that a more flexible mechanism for configuring the order of traversal is needed and we are currently working on a solution to that problem.


Menu Shortcuts

The goal for the AWT Shortcut API is to provide an easy way for application developers to provide shortcuts as an aid to menu navigation. This API only addresses menu shortcuts, and does not touch on any other mouseless menu navigation issues.

A Shortcut is defined to be a keyboard equivalent of a menu command, such that invoking the appropriate key combination will cause the same action to be initiated as if the menu item had been selected. Shortcuts are also known as keyboard equivalents or accelerators.

The Shortcuts API

The API consists of a class:
	java.awt.MenuShortcut

java.awt.MenuItem then has the following additional methods:

	public MenuItem(String label, MenuShortcut s)
	public MenuShortcut getShortcut()
	public void setShortcut(MenuShortcut s)
	public void deleteShortcut();

java.awt.MenuBar has the following additional methods:

	public MenuItem getShortcutMenuItem(MenuShortcut s);
	public Enumeration shortcuts();
	boolean handleShortcut(KeyEvent e);
	public void deleteShortcut(MenuShortcut s);

Modifiers

Application shortcuts all have a common key modifier per-platform:

Note: ALT isn't supposed to be used for application shortcuts, other than QUIT, which is already mapped by the AWT.

Although most of the shortcut API is implemented in shared code, one method has been added to java.awt.Toolkit to return the appropriate modifier per platform:

	    public int getMenuShortcutKeyMask();

Visual Indicators

In order for users to learn and use menu shortcuts, it's important that a menu item display some visual indicator for the shortcut it supports. This will be handled automatically by the AWT, in a manner most appropriate for the given platform.

Sample Code

The code to create menu-items in 1.0:
	    menu.add(new MenuItem("Save..."));
	    menu.add(new MenuItem("Send..."));

The code to create menu-items with shortcuts in 1.1:

	    // Specify an 's' shortcut for save, and 'shift-s' for send.
	    menu.add(new MenuItem("Save...", new MenuShortcut('s'));
	    menu.add(new MenuItem("Send...", new MenuShortcut('s', true));



Send feedback to:java-awt@java.sun.com
Copyright © 1996, 1997 Sun Microsystems, Inc. All rights reserved.