--- old/src/java.desktop/share/classes/java/awt/event/FocusEvent.java 2015-10-15 09:31:59.375368700 +0300 +++ new/src/java.desktop/share/classes/java/awt/event/FocusEvent.java 2015-10-15 09:31:58.988346500 +0300 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,18 +25,19 @@ package java.awt.event; -import java.awt.Component; import sun.awt.AppContext; import sun.awt.SunToolkit; +import java.awt.*; + /** * A low-level event which indicates that a Component has gained or lost the * input focus. This low-level event is generated by a Component (such as a - * TextField). The event is passed to every FocusListener or - * FocusAdapter object which registered to receive such events - * using the Component's addFocusListener method. ( - * FocusAdapter objects implement the FocusListener - * interface.) Each such listener object gets this FocusEvent when + * TextField). The event is passed to every {@code FocusListener} or + * {@code FocusAdapter} object which registered to receive such events + * using the Component's {@code addFocusListener} method. ({@code + * FocusAdapter} objects implement the {@code FocusListener} + * interface.) Each such listener object gets this {@code FocusEvent} when * the event occurs. *

* There are two levels of focus events: permanent and temporary. Permanent @@ -51,6 +52,10 @@ * the FOCUS_GAINED and FOCUS_LOST event ids; the level may be distinguished in * the event using the isTemporary() method. *

+ * Every {@code FocusEvent} records its cause - the reason why this event was + * generated. The cause is assigned during the focus event creation and may be + * retrieved by calling {@link #getCause}. + *

* An unspecified behavior will be caused if the {@code id} parameter * of any particular {@code FocusEvent} instance is not * in the range from {@code FOCUS_FIRST} to {@code FOCUS_LAST}. @@ -66,6 +71,61 @@ public class FocusEvent extends ComponentEvent { /** + * This enum represents the cause of a {@code FocusEvent}- the reason why it + * occurred. Possible reasons include mouse events, keyboard focus + * traversal, window activation. + * If no cause is provided then the reason is {@code UNKNOWN}. + * + * @since 1.9 + */ + public enum Cause { + /** + * The default value. + */ + UNKNOWN, + /** + * An activating mouse event. + */ + MOUSE_EVENT, + /** + * A focus traversal action with unspecified direction. + */ + TRAVERSAL, + /** + * An up-cycle focus traversal action. + */ + TRAVERSAL_UP, + /** + * A down-cycle focus traversal action. + */ + TRAVERSAL_DOWN, + /** + * A forward focus traversal action. + */ + TRAVERSAL_FORWARD, + /** + * A backward focus traversal action. + */ + TRAVERSAL_BACKWARD, + /** + * Restoring focus after a focus request has been rejected. + */ + ROLLBACK, + /** + * A system action causing an unexpected focus change. + */ + UNEXPECTED, + /** + * An activation of a toplevel window. + */ + ACTIVATION, + /** + * Clearing global focus owner. + */ + CLEAR_GLOBAL_FOCUS_OWNER + } + + /** * The first number in the range of ids used for focus events. */ public static final int FOCUS_FIRST = 1004; @@ -85,6 +145,8 @@ */ public static final int FOCUS_LOST = 1 + FOCUS_FIRST; //Event.LOST_FOCUS + private final Cause cause; + /** * A focus event can have two different levels, permanent and temporary. * It will be set to true if some operation takes away the focus @@ -111,60 +173,102 @@ /* * JDK 1.1 serialVersionUID */ - private static final long serialVersionUID = 523753786457416396L; + private static final long serialVersionUID = 523753786457416397L; /** - * Constructs a FocusEvent object with the - * specified temporary state and opposite Component. - * The opposite Component is the other - * Component involved in this focus change. - * For a FOCUS_GAINED event, this is the - * Component that lost focus. For a - * FOCUS_LOST event, this is the Component + * Constructs a {@code FocusEvent} object with the + * specified temporary state and opposite {@code Component} and the + * {@code Cause.UNKNOWN} cause. + * The opposite {@code Component} is the other + * {@code Component} involved in this focus change. + * For a {@code FOCUS_GAINED} event, this is the + * {@code Component} that lost focus. For a + * {@code FOCUS_LOST} event, this is the {@code Component} * that gained focus. If this focus change occurs with a native * application, with a Java application in a different VM, - * or with no other Component, then the opposite - * Component is null. + * or with no other {@code Component}, then the opposite + * {@code Component} is {@code null}. *

This method throws an - * IllegalArgumentException if source - * is null. + * {@code IllegalArgumentException} if {@code source} + * is {@code null}. * - * @param source The Component that originated the event + * @param source The {@code Component} that originated the event * @param id An integer indicating the type of event. * For information on allowable values, see * the class description for {@link FocusEvent} - * @param temporary Equals true if the focus change is temporary; - * false otherwise + * @param temporary Equals {@code true} if the focus change is temporary; + * {@code false} otherwise * @param opposite The other Component involved in the focus change, - * or null - * @throws IllegalArgumentException if source equals {@code null} + * or {@code null} + * @throws IllegalArgumentException if {@code source} equals {@code null} * @see #getSource() * @see #getID() * @see #isTemporary() * @see #getOppositeComponent() + * @see Cause#UNKNOWN * @since 1.4 */ public FocusEvent(Component source, int id, boolean temporary, Component opposite) { + this(source, id, temporary, opposite, Cause.UNKNOWN); + } + + /** + * Constructs a {@code FocusEvent} object with the + * specified temporary state, opposite {@code Component} and the cause. + * The opposite {@code Component} is the other + * {@code Component} involved in this focus change. + * For a {@code FOCUS_GAINED} event, this is the + * {@code Component} that lost focus. For a + * {@code FOCUS_LOST} event, this is the {@code Component} + * that gained focus. If this focus change occurs with a native + * application, with a Java application in a different VM, + * or with no other {@code Component}, then the opposite + * {@code Component} is {@code null}. + *

This method throws an + * {@code IllegalArgumentException} if {@code source} + * is {@code null}. + * + * @param source The {@code Component} that originated the event + * @param id An integer indicating the type of event. + * For information on allowable values, see + * the class description for {@link FocusEvent} + * @param temporary Equals {@code true} if the focus change is temporary; + * {@code false} otherwise + * @param opposite The other Component involved in the focus change, + * or {@code null} + * @param cause The focus event cause. + * @throws IllegalArgumentException if {@code source} equals {@code null} + * or if {@code cause} equals {@code null} + * @see #getSource() + * @see #getID() + * @see #isTemporary() + * @see #getOppositeComponent() + * @see Cause + * @since 1.9 + */ + public FocusEvent(Component source, int id, boolean temporary, + Component opposite, Cause cause) { super(source, id); this.temporary = temporary; this.opposite = opposite; + this.cause = cause; } /** - * Constructs a FocusEvent object and identifies + * Constructs a {@code FocusEvent} object and identifies * whether or not the change is temporary. *

This method throws an - * IllegalArgumentException if source - * is null. + * {@code IllegalArgumentException} if {@code source} + * is {@code null}. * - * @param source The Component that originated the event + * @param source The {@code Component} that originated the event * @param id An integer indicating the type of event. * For information on allowable values, see * the class description for {@link FocusEvent} - * @param temporary Equals true if the focus change is temporary; - * false otherwise - * @throws IllegalArgumentException if source equals {@code null} + * @param temporary Equals {@code true} if the focus change is temporary; + * {@code false} otherwise + * @throws IllegalArgumentException if {@code source} equals {@code null} * @see #getSource() * @see #getID() * @see #isTemporary() @@ -174,17 +278,17 @@ } /** - * Constructs a FocusEvent object and identifies it + * Constructs a {@code FocusEvent} object and identifies it * as a permanent change in focus. *

This method throws an - * IllegalArgumentException if source - * is null. + * {@code IllegalArgumentException} if {@code source} + * is {@code null}. * - * @param source The Component that originated the event + * @param source The {@code Component} that originated the event * @param id An integer indicating the type of event. * For information on allowable values, see * the class description for {@link FocusEvent} - * @throws IllegalArgumentException if source equals {@code null} + * @throws IllegalArgumentException if {@code source} equals {@code null} * @see #getSource() * @see #getID() */ @@ -195,8 +299,8 @@ /** * Identifies the focus change event as temporary or permanent. * - * @return true if the focus change is temporary; - * false otherwise + * @return {@code true} if the focus change is temporary; + * {@code false} otherwise */ public boolean isTemporary() { return temporary; @@ -243,7 +347,16 @@ typeStr = "unknown type"; } return typeStr + (temporary ? ",temporary" : ",permanent") + - ",opposite=" + getOppositeComponent(); + ",opposite=" + getOppositeComponent() + ",cause=" + getCause(); } + /** + * Returns the event cause. + * + * @return one of {@link Cause} values + * @since 1.9 + */ + public final Cause getCause() { + return cause; + } }