# Focus API changes

This document outlines the API changes that have been done to AWT and Swing to accomodate the new focus model. For a general overview of the changes, you may want to first read this.

Modifications to existing classes:

- java.awt.AWTEvent
- java.awt.Component
- java.awt.Container
- java.awt.Window
- java.awt.Frame
- java.awt.Dialog
- java.awt.FocusEvent
- java.awt.event.WindowEvent
- java.awt.event.WindowListener
- java.awt.event.WindowAdapter
- java.awt.AWTEventMulticaster
- javax.swing.FocusManager
- javax.swing.DefaultFocusManager
- javax.swing.JComponent
- javax.swing.JWindow
- javax.swing.JInternalFrame
- javax.swing.KeyStroke
- javax.swing.SwingUtilities

New classes:

- java.awt.KeyboardFocusManager
- java.awt.KeyEventDispatcher
- java.awt.DefaultKeyboardFocusManager
- java.awt.FocusTraversalPolicy
- java.awt.ContainerOrderFocusTraversalPolicy
- java.awt.DefaultFocusTraversalPolicy
- java.awt.AWTKeyStroke
- java.awt.event.WindowFocusListener
- javax.swing.SortingFocusTraversalPolicy
- javax.swing.LayoutFocusTraversalPolicy
- javax.swing.InternalFrameFocusTraversalPolicy

#### Add the following to `java.awt.AWTEvent`:

        public void setSource(Object newSource)

#### Changes to `java.awt.Component`:

        public boolean isFocusTraversable()

        public boolean isFocusable()

        public void setFocusable(boolean focusable)

        public void setFocusTraversalKeys(int id, Set keystroke)

        public Set getFocusTraversalKeys(int id)

        public void setFocusTraversalKeysEnabled(boolean focusTraversalKeysEnabled)

        public boolean getFocusTraversalKeysEnabled()

        public void requestFocus()

        protected boolean requestFocus(boolean temporary)

        public boolean requestFocusInWindow()

        protected boolean requestFocusInWindow(boolean temporary)

        public void transferFocus()

        public void transferFocusBackward()

        public void transferFocusUpCycle()

        public Container getFocusCycleRootAncestor()

        public boolean isFocusCycleRoot(Container container)

        public boolean hasFocus()

        public boolean isFocusOwner()

        public void addPropertyChangeListener(PropertyChangeListener listener)

        public void removePropertyChangeListener(PropertyChangeListener listener)

        public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener)

        public void removePropertyChangeListener(String propertyName, PropertyChangeListener listener)

        public void firePropertyChange(String propertyName, boolean oldValue, boolean newValue)

        public void firePropertyChange(String propertyName, int oldValue, int newValue)

        public boolean isFontSet()

        public boolean isBackgroundSet()

        public boolean isForegroundSet()

        public boolean isCursorSet()

        public boolean areFocusTraversalKeysSet(int id)

#### Changes to `java.awt.Container`:

        public void setFocusTraversalKeys(int id, Set keystroke)

        public Set getFocusTraversalKeys(int id)

        public void setFocusTraversalPolicy(FocusTraversalPolicy policy)

        public FocusTraversalPolicy getFocusTraversalPolicy()

        public void setFocusCycleRoot(boolean focusCycleRoot)

        public boolean isFocusCycleRoot()

        public boolean isFocusCycleRoot(Container container)

        public void transferFocusDownCycle()

        public void addPropertyChangeListener(PropertyChangeListener listener)

        public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener)

        public boolean areFocusTraversalKeysSet(int id)

        public boolean isFocusTraversalPolicySet()

#### Changes to `java.awt.Window`:

        public void toFront()

        public void toBack()

        public Component getFocusOwner()

        public Component getMostRecentFocusOwner()

        public boolean isActive()

        public boolean isFocused()

        public final void setFocusCycleRoot(boolean focusCycleRoot)

        public final boolean isFocusCycleRoot()

        public final Container getFocusCycleRootAncestor()

        public boolean isFocusableWindow()

        public void setFocusableWindow(boolean focusableWindow)

        public void addPropertyChangeListener(PropertyChangeListener listener)

        public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener)

#### Add the following to the javadoc of `java.awt.Frame`:

    /**
     * Frames are capable of generating the following types of WindowEvents:
     * WindowOpened, WindowClosing, WindowClosed, WindowIconified,
     * WindowDeiconified, WindowActivated, WindowDeactivated, WindowGainedFocus,
     * WindowLostFocus.
     */

#### Add the following to the javadoc of `java.awt.Dialog`:

    /**
     * Dialogs are capable of generating the following WindowEvents:
     * WindowOpened, WindowClosing, WindowClosed, WindowActivated,
     * WindowDeactivated, WindowGainedFocus, WindowLostFocus.
     */

#### Add the following to `java.awt.event.FocusEvent`:

        public FocusEvent(Component source, int id, boolean temporary, Component opposite)

        public Component getOppositeComponent()

#### Add the following to the javadoc of `java.awt.event.WindowEvent`:

    /**
     * A low-level event that indicates that a window has changed its status. This
     * low-level event is generated by a Window object when it is opened, closed,
     * activated, deactivated, iconified, or deiconified, or when focus is
     * transfered into or out of the Window.
     */

#### Add the following to `java.awt.event.WindowEvent`:

        public static final int WINDOW_ACTIVATED

        public static final int WINDOW_DEACTIVATED

        public static final int WINDOW_GAINED_FOCUS

        public static final int WINDOW_LOST_FOCUS

        public WindowEvent(Window source, int id, Window opposite)

        public Window getOppositeWindow()

#### Add the following to `java.awt.event.WindowListener`:

        public void windowActivated(WindowEvent e)

        public void windowDeactivated(WindowEvent e)

#### Add the following to `java.awt.event.WindowAdapter`:

        public void windowGainedFocus(WindowEvent e)

        public void windowLostFocus(WindowEvent e)

#### Add the following to `java.awt.AWTEventMulticaster`:

        public void windowGainedFocus(WindowEvent e)

        public void windowLostFocus(WindowEvent e)

#### Modifications to `javax.swing.FocusManager`

This class has been obsoleted. New applications should use `java.awt.KeyboardFocusManager` exclusively. Nevertheless, we have preserved backward compatibility for existing applications (but not applets) which define their own `FocusManager`.

The Swing `FocusManager` has been changed to be a subclass of the new, AWT `KeyboardFocusManager`. `FocusManager.setCurrentManager(FocusManager)` and `FocusManager.getCurrentManager()` have been changed to wrappers around `KeyboardFocusManager.setCurrentKeyboardFocusManager(KeyboardFocusManager)` and `KeyboardFocusManager.getCurrentKeyboardFocusManager()`, respectively.

There was much discussion over these changes because `KeyboardFocusManager.setCurrentKeyboardFocusManager(KeyboardFocusManager)` will throw a `SecurityException` if the calling thread was not granted the `"replaceKeyboardFocusManager"` permission. Previously, `FocusManager.setCurrentManager(FocusManager)` would never throw a `SecurityException`. Although we were able to design a convoluted class organization which avoided this problem, we felt that the elegance and simplicity of the proposed design outweighed the rather small backward compatibility concern.

`disableSwingFocusManager()` and `isFocusManagerEnabled()` should not be used. Disabling the Swing `FocusManager` now has the semantics of reverting the default `FocusTraversalPolicy` from the Swing default of `javax.swing.LayoutFocusTraversalPolicy` to the AWT default of `java.awt.DefaultFocusTraversalPolicy`.

#### Modifications to `javax.swing.DefaultFocusManager`

This class has been obsoleted. New applications should use `java.awt.KeyboardFocusManager` exclusively. Nevertheless, we have preserved backward compatibility for existing applications (but not applets) which define their own `DefaultFocusManager`.

If client code installs a legacy `DefaultFocusManager`, we provide backward compatibility by installing a non-public `LegacyGlueFocusTraversalPolicy` which routes `FocusTraversalPolicy` method invocations to the corresponding methods on `DefaultFocusManager`.

#### Modifications to `javax.swing.JComponent`

`isManagingFocus`: This method has been obsoleted. It changed a `JComponent`'s focus traversal keys from TAB and SHIFT-TAB to CTRL-TAB and CTRL-SHIFT-TAB. It also marked the `JComponent` in such a way that focus traversal would not automatically enter the `JComponent`. This was similar to, but different from, marking a `JComponent` as a focus cycle root. Its functionality is superseded by the `FocusTraversalPolicy` class, per-`Component` focus traversal keys, and the ability to disable a `Component`'s focus traversal keys en masse.

`setNextFocusableComponent/getNextFocusableComponents`: These methods have been obsoleted `FocusTraversalPolicies` are more reliable because they allow an algorithmic expression of focus traversal. These methods force applications to hard-code focus traversal `Component` by `Component`.

The spec for `setRequestFocusEnabled/isRequestFocusEnabled` has changed, such that the `requestFocusEnabled` property is now a hint to the current look and feel.

`requestDefaultFocus`: This method has been obsoleted. Its functionality is superseded by `FocusTraversalPolicy.getDefaultComponent(Container).requestFocus()`.

#### Modifications to `javax.swing.JWindow`

`setFocusableWindow/isFocusableWindow`: These methods are declared final in `JWindow` to enforce the restriction that all `JWindows` constructed with a 'null' owner must be non-focusable. This restriction is necessary because Swing constructs such `JWindows` so that they are owned by a private, hidden `Frame`, and the new focus implementation requires that `KeyEvents` intended for a `Window` or its descendants be proxied through that `Frame`. Since X11 requires a `window` to be mapped in order to be focused, a `JWindow` with a 'null' owner could never receive `KeyEvents` on X11.

#### Modifications to `javax.swing.JInternalFrame`

`getMostRecentFocusOwner`: Like `java.awt.Window`, `JInternalFrame` has a `getFocusOwner()` method left over from before centralization of focus management in `java.awt.KeyboardFocusManager`. To round out the API, and to remain consistent with Window, `getMostRecentFocusOwner()` has been added to `JInternalFrame` with the same specification as the corresponding method on `Window`.

`setFocusCycleRoot/isFocusCycleRoot`: These methods give `JInternalFrames` similar semantics to top-level `Windows` in AWT. Since a `JInternalFrame` must always be a focus cycle root, these methods are overridden and declared final to enforce that restriction. However, unlike an AWT `Window`, a `JInternalFrame` can have a focus-cycle-root ancestor, such as a `JDesktopPane`. Thus, `Component.getFocusCycleRootAncestor()` is not declared final in `JInternalFrame` as it is in `Window`.

#### Modifications to `javax.swing.KeyStroke`

Because the existing `KeyStroke` class was useful for designing per-`Component` focus traversal key APIs, this class was promoted with minor modifications to AWT as `java.awt.AWTKeyStroke`. The Swing class is now a subclass of the AWT class.

The one deprecated method in `KeyStroke`, `getKeyStroke(char, boolean)`, was not promoted to AWT. Because of this, there is no simple way for this method to participate in the standard `AWTKeyStroke` caching scheme. The specification of this method has been changed to note that implementations need not cache the instances returned by this method.

#### Modifications to `javax.swing.SwingUtilities`

`findFocusOwner:` This method has been obsoleted. Its functionality is superseded by `KeyboardFocusManager.getFocusOwner()`.