/*
 * Copyright (c) 1998, 2013, 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
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package java.awt.event;

import sun.awt.AWTAccessor;

import java.awt.ActiveEvent;
import java.awt.AWTEvent;

An event which executes the run() method on a Runnable when dispatched by the AWT event dispatcher thread. This class can be used as a reference implementation of ActiveEvent rather than declaring a new class and defining dispatch().

Instances of this class are placed on the EventQueue by calls to invokeLater and invokeAndWait. Client code can use this fact to write replacement functions for invokeLater and invokeAndWait without writing special-case code in any AWTEventListener objects.

An unspecified behavior will be caused if the id parameter of any particular InvocationEvent instance is not in the range from INVOCATION_FIRST to INVOCATION_LAST.

Author: Fred Ecks, David Mendenhall
See Also:
Since: 1.2
/** * An event which executes the {@code run()} method on a {@code Runnable * } when dispatched by the AWT event dispatcher thread. This class can * be used as a reference implementation of {@code ActiveEvent} rather * than declaring a new class and defining {@code dispatch()}.<p> * * Instances of this class are placed on the {@code EventQueue} by calls * to {@code invokeLater} and {@code invokeAndWait}. Client code * can use this fact to write replacement functions for {@code invokeLater * } and {@code invokeAndWait} without writing special-case code * in any {@code AWTEventListener} objects. * <p> * An unspecified behavior will be caused if the {@code id} parameter * of any particular {@code InvocationEvent} instance is not * in the range from {@code INVOCATION_FIRST} to {@code INVOCATION_LAST}. * * @author Fred Ecks * @author David Mendenhall * * @see java.awt.ActiveEvent * @see java.awt.EventQueue#invokeLater * @see java.awt.EventQueue#invokeAndWait * @see AWTEventListener * * @since 1.2 */
public class InvocationEvent extends AWTEvent implements ActiveEvent { static { AWTAccessor.setInvocationEventAccessor(new AWTAccessor.InvocationEventAccessor() { @Override public void dispose(InvocationEvent invocationEvent) { invocationEvent.finishedDispatching(false); } }); }
Marks the first integer id for the range of invocation event ids.
/** * Marks the first integer id for the range of invocation event ids. */
public static final int INVOCATION_FIRST = 1200;
The default id for all InvocationEvents.
/** * The default id for all InvocationEvents. */
public static final int INVOCATION_DEFAULT = INVOCATION_FIRST;
Marks the last integer id for the range of invocation event ids.
/** * Marks the last integer id for the range of invocation event ids. */
public static final int INVOCATION_LAST = INVOCATION_DEFAULT;
The Runnable whose run() method will be called.
/** * The Runnable whose run() method will be called. */
protected Runnable runnable;
The (potentially null) Object whose notifyAll() method will be called immediately after the Runnable.run() method has returned or thrown an exception or after the event was disposed.
See Also:
  • isDispatched
/** * The (potentially null) Object whose notifyAll() method will be called * immediately after the Runnable.run() method has returned or thrown an exception * or after the event was disposed. * * @see #isDispatched */
protected volatile Object notifier;
The (potentially null) Runnable whose run() method will be called immediately after the event was dispatched or disposed.
See Also:
  • isDispatched
Since:1.8
/** * The (potentially null) Runnable whose run() method will be called * immediately after the event was dispatched or disposed. * * @see #isDispatched * @since 1.8 */
private final Runnable listener;
Indicates whether the run() method of the runnable was executed or not.
See Also:
Since:1.7
/** * Indicates whether the {@code run()} method of the {@code runnable} * was executed or not. * * @see #isDispatched * @since 1.7 */
private volatile boolean dispatched = false;
Set to true if dispatch() catches Throwable and stores it in the exception instance variable. If false, Throwables are propagated up to the EventDispatchThread's dispatch loop.
/** * Set to true if dispatch() catches Throwable and stores it in the * exception instance variable. If false, Throwables are propagated up * to the EventDispatchThread's dispatch loop. */
protected boolean catchExceptions;
The (potentially null) Exception thrown during execution of the Runnable.run() method. This variable will also be null if a particular instance does not catch exceptions.
/** * The (potentially null) Exception thrown during execution of the * Runnable.run() method. This variable will also be null if a particular * instance does not catch exceptions. */
private Exception exception = null;
The (potentially null) Throwable thrown during execution of the Runnable.run() method. This variable will also be null if a particular instance does not catch exceptions.
/** * The (potentially null) Throwable thrown during execution of the * Runnable.run() method. This variable will also be null if a particular * instance does not catch exceptions. */
private Throwable throwable = null;
The timestamp of when this event occurred.
See Also:
@serial
/** * The timestamp of when this event occurred. * * @serial * @see #getWhen */
private long when; /* * JDK 1.1 serialVersionUID. */ private static final long serialVersionUID = 436056344909459450L;
Constructs an InvocationEvent with the specified source which will execute the runnable's run method when dispatched.

This is a convenience constructor. An invocation of the form InvocationEvent(source, runnable) behaves in exactly the same way as the invocation of InvocationEvent(source, runnable, null, false).

This method throws an IllegalArgumentException if source is null.

Params:
  • source – The Object that originated the event
  • runnable – The Runnable whose run method will be executed
Throws:
See Also:
/** * Constructs an {@code InvocationEvent} with the specified * source which will execute the runnable's {@code run} * method when dispatched. * <p>This is a convenience constructor. An invocation of the form * {@code InvocationEvent(source, runnable)} * behaves in exactly the same way as the invocation of * {@link #InvocationEvent(Object, Runnable, Object, boolean) * InvocationEvent(source, runnable, null, false)}. * <p> This method throws an {@code IllegalArgumentException} * if {@code source} is {@code null}. * * @param source The {@code Object} that originated the event * @param runnable The {@code Runnable} whose {@code run} * method will be executed * @throws IllegalArgumentException if {@code source} is null * * @see #getSource() * @see #InvocationEvent(Object, Runnable, Object, boolean) */
public InvocationEvent(Object source, Runnable runnable) { this(source, INVOCATION_DEFAULT, runnable, null, null, false); }
Constructs an InvocationEvent with the specified source which will execute the runnable's run method when dispatched. If notifier is non-null, notifyAll() will be called on it immediately after run has returned or thrown an exception.

An invocation of the form InvocationEvent(source, runnable, notifier, catchThrowables) behaves in exactly the same way as the invocation of InvocationEvent(source, InvocationEvent.INVOCATION_DEFAULT, runnable, notifier, catchThrowables).

This method throws an IllegalArgumentException if source is null.

Params:
  • source – The Object that originated the event
  • runnable – The Runnable whose run method will be executed
  • notifier – The Object whose notifyAll method will be called after Runnable.run has returned or thrown an exception or after the event was disposed
  • catchThrowables – Specifies whether dispatch should catch Throwable when executing the Runnable's run method, or should instead propagate those Throwables to the EventDispatchThread's dispatch loop
Throws:
See Also:
/** * Constructs an {@code InvocationEvent} with the specified * source which will execute the runnable's {@code run} * method when dispatched. If notifier is non-{@code null}, * {@code notifyAll()} will be called on it * immediately after {@code run} has returned or thrown an exception. * <p>An invocation of the form * {@code InvocationEvent(source, runnable, notifier, catchThrowables)} * behaves in exactly the same way as the invocation of * {@link #InvocationEvent(Object, int, Runnable, Object, boolean) * InvocationEvent(source, InvocationEvent.INVOCATION_DEFAULT, runnable, notifier, catchThrowables)}. * <p>This method throws an {@code IllegalArgumentException} * if {@code source} is {@code null}. * * @param source The {@code Object} that originated * the event * @param runnable The {@code Runnable} whose * {@code run} method will be * executed * @param notifier The {@code Object} whose {@code notifyAll} * method will be called after * {@code Runnable.run} has returned or * thrown an exception or after the event was * disposed * @param catchThrowables Specifies whether {@code dispatch} * should catch Throwable when executing * the {@code Runnable}'s {@code run} * method, or should instead propagate those * Throwables to the EventDispatchThread's * dispatch loop * @throws IllegalArgumentException if {@code source} is null * * @see #getSource() * @see #InvocationEvent(Object, int, Runnable, Object, boolean) */
public InvocationEvent(Object source, Runnable runnable, Object notifier, boolean catchThrowables) { this(source, INVOCATION_DEFAULT, runnable, notifier, null, catchThrowables); }
Constructs an InvocationEvent with the specified source which will execute the runnable's run method when dispatched. If listener is non-null, listener.run() will be called immediately after run has returned, thrown an exception or the event was disposed.

This method throws an IllegalArgumentException if source is null.

Params:
  • source – The Object that originated the event
  • runnable – The Runnable whose run method will be executed
  • listener – The RunnableRunnable whose run() method will be called after the InvocationEvent was dispatched or disposed
  • catchThrowables – Specifies whether dispatch should catch Throwable when executing the Runnable's run method, or should instead propagate those Throwables to the EventDispatchThread's dispatch loop
Throws:
/** * Constructs an {@code InvocationEvent} with the specified * source which will execute the runnable's {@code run} * method when dispatched. If listener is non-{@code null}, * {@code listener.run()} will be called immediately after * {@code run} has returned, thrown an exception or the event * was disposed. * <p>This method throws an {@code IllegalArgumentException} * if {@code source} is {@code null}. * * @param source The {@code Object} that originated * the event * @param runnable The {@code Runnable} whose * {@code run} method will be * executed * @param listener The {@code Runnable}Runnable whose * {@code run()} method will be called * after the {@code InvocationEvent} * was dispatched or disposed * @param catchThrowables Specifies whether {@code dispatch} * should catch Throwable when executing * the {@code Runnable}'s {@code run} * method, or should instead propagate those * Throwables to the EventDispatchThread's * dispatch loop * @throws IllegalArgumentException if {@code source} is null */
public InvocationEvent(Object source, Runnable runnable, Runnable listener, boolean catchThrowables) { this(source, INVOCATION_DEFAULT, runnable, null, listener, catchThrowables); }
Constructs an InvocationEvent with the specified source and ID which will execute the runnable's run method when dispatched. If notifier is non-null, notifyAll will be called on it immediately after run has returned or thrown an exception.

This method throws an IllegalArgumentException if source is null.

Params:
  • source – The Object that originated the event
  • id – An integer indicating the type of event. For information on allowable values, see the class description for InvocationEvent
  • runnable – The Runnable whose run method will be executed
  • notifier – The Object whose notifyAll method will be called after Runnable.run has returned or thrown an exception or after the event was disposed
  • catchThrowables – Specifies whether dispatch should catch Throwable when executing the Runnable's run method, or should instead propagate those Throwables to the EventDispatchThread's dispatch loop
Throws:
See Also:
/** * Constructs an {@code InvocationEvent} with the specified * source and ID which will execute the runnable's {@code run} * method when dispatched. If notifier is non-{@code null}, * {@code notifyAll} will be called on it immediately after * {@code run} has returned or thrown an exception. * <p>This method throws an * {@code IllegalArgumentException} if {@code source} * is {@code null}. * * @param source The {@code Object} that originated * the event * @param id An integer indicating the type of event. * For information on allowable values, see * the class description for {@link InvocationEvent} * @param runnable The {@code Runnable} whose * {@code run} method will be executed * @param notifier The {@code Object} whose {@code notifyAll} * method will be called after * {@code Runnable.run} has returned or * thrown an exception or after the event was * disposed * @param catchThrowables Specifies whether {@code dispatch} * should catch Throwable when executing the * {@code Runnable}'s {@code run} * method, or should instead propagate those * Throwables to the EventDispatchThread's * dispatch loop * @throws IllegalArgumentException if {@code source} is null * @see #getSource() * @see #getID() */
protected InvocationEvent(Object source, int id, Runnable runnable, Object notifier, boolean catchThrowables) { this(source, id, runnable, notifier, null, catchThrowables); } private InvocationEvent(Object source, int id, Runnable runnable, Object notifier, Runnable listener, boolean catchThrowables) { super(source, id); this.runnable = runnable; this.notifier = notifier; this.listener = listener; this.catchExceptions = catchThrowables; this.when = System.currentTimeMillis(); }
Executes the Runnable's run() method and notifies the notifier (if any) when run() has returned or thrown an exception.
See Also:
/** * Executes the Runnable's {@code run()} method and notifies the * notifier (if any) when {@code run()} has returned or thrown an exception. * * @see #isDispatched */
public void dispatch() { try { if (catchExceptions) { try { runnable.run(); } catch (Throwable t) { if (t instanceof Exception) { exception = (Exception) t; } throwable = t; } } else { runnable.run(); } } finally { finishedDispatching(true); } }
Returns any Exception caught while executing the Runnable's run() method.
Returns: A reference to the Exception if one was thrown; null if no Exception was thrown or if this InvocationEvent does not catch exceptions
/** * Returns any Exception caught while executing * the Runnable's {@code run()} method. * * @return A reference to the Exception if one was thrown; null if no * Exception was thrown or if this InvocationEvent does not * catch exceptions */
public Exception getException() { return (catchExceptions) ? exception : null; }
Returns any Throwable caught while executing the Runnable's run() method.
Returns: A reference to the Throwable if one was thrown; null if no Throwable was thrown or if this InvocationEvent does not catch Throwables
Since:1.5
/** * Returns any Throwable caught while executing * the Runnable's {@code run()} method. * * @return A reference to the Throwable if one was thrown; null if no * Throwable was thrown or if this InvocationEvent does not * catch Throwables * @since 1.5 */
public Throwable getThrowable() { return (catchExceptions) ? throwable : null; }
Returns the timestamp of when this event occurred.
Returns:this event's timestamp
Since:1.4
/** * Returns the timestamp of when this event occurred. * * @return this event's timestamp * @since 1.4 */
public long getWhen() { return when; }
Returns true if the event is dispatched or any exception is thrown while dispatching, false otherwise. The method should be called by a waiting thread that calls the notifier.wait() method. Since spurious wakeups are possible (as explained in Object.wait()), this method should be used in a waiting loop to ensure that the event got dispatched:
    while (!event.isDispatched()) {
        notifier.wait();
    }
If the waiting thread wakes up without dispatching the event, the isDispatched() method returns false, and the while loop executes once more, thus, causing the awakened thread to revert to the waiting mode.

If the notifier.notifyAll() happens before the waiting thread enters the notifier.wait() method, the while loop ensures that the waiting thread will not enter the notifier.wait() method. Otherwise, there is no guarantee that the waiting thread will ever be woken from the wait.

See Also:
Returns:true if the event has been dispatched, or any exception has been thrown while dispatching, false otherwise
Since:1.7
/** * Returns {@code true} if the event is dispatched or any exception is * thrown while dispatching, {@code false} otherwise. The method should * be called by a waiting thread that calls the {@code notifier.wait()} method. * Since spurious wakeups are possible (as explained in {@link Object#wait()}), * this method should be used in a waiting loop to ensure that the event * got dispatched: * <pre> * while (!event.isDispatched()) { * notifier.wait(); * } * </pre> * If the waiting thread wakes up without dispatching the event, * the {@code isDispatched()} method returns {@code false}, and * the {@code while} loop executes once more, thus, causing * the awakened thread to revert to the waiting mode. * <p> * If the {@code notifier.notifyAll()} happens before the waiting thread * enters the {@code notifier.wait()} method, the {@code while} loop ensures * that the waiting thread will not enter the {@code notifier.wait()} method. * Otherwise, there is no guarantee that the waiting thread will ever be woken * from the wait. * * @return {@code true} if the event has been dispatched, or any exception * has been thrown while dispatching, {@code false} otherwise * @see #dispatch * @see #notifier * @see #catchExceptions * @since 1.7 */
public boolean isDispatched() { return dispatched; }
Called when the event was dispatched or disposed
Params:
  • dispatched – true if the event was dispatched false if the event was disposed
/** * Called when the event was dispatched or disposed * @param dispatched true if the event was dispatched * false if the event was disposed */
private void finishedDispatching(boolean dispatched) { this.dispatched = dispatched; if (notifier != null) { synchronized (notifier) { notifier.notifyAll(); } } if (listener != null) { listener.run(); } }
Returns a parameter string identifying this event. This method is useful for event-logging and for debugging.
Returns: A string identifying the event and its attributes
/** * Returns a parameter string identifying this event. * This method is useful for event-logging and for debugging. * * @return A string identifying the event and its attributes */
public String paramString() { String typeStr; switch(id) { case INVOCATION_DEFAULT: typeStr = "INVOCATION_DEFAULT"; break; default: typeStr = "unknown type"; } return typeStr + ",runnable=" + runnable + ",notifier=" + notifier + ",catchExceptions=" + catchExceptions + ",when=" + when; } }