< prev index next >

src/java.desktop/share/classes/java/awt/event/InvocationEvent.java

Print this page




  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package java.awt.event;
  27 
  28 import sun.awt.AWTAccessor;
  29 
  30 import java.awt.ActiveEvent;
  31 import java.awt.AWTEvent;
  32 
  33 /**
  34  * An event which executes the <code>run()</code> method on a <code>Runnable
  35  * </code> when dispatched by the AWT event dispatcher thread. This class can
  36  * be used as a reference implementation of <code>ActiveEvent</code> rather
  37  * than declaring a new class and defining <code>dispatch()</code>.<p>
  38  *
  39  * Instances of this class are placed on the <code>EventQueue</code> by calls
  40  * to <code>invokeLater</code> and <code>invokeAndWait</code>. Client code
  41  * can use this fact to write replacement functions for <code>invokeLater
  42  * </code> and <code>invokeAndWait</code> without writing special-case code
  43  * in any <code>AWTEventListener</code> objects.
  44  * <p>
  45  * An unspecified behavior will be caused if the {@code id} parameter
  46  * of any particular {@code InvocationEvent} instance is not
  47  * in the range from {@code INVOCATION_FIRST} to {@code INVOCATION_LAST}.
  48  *
  49  * @author      Fred Ecks
  50  * @author      David Mendenhall
  51  *
  52  * @see         java.awt.ActiveEvent
  53  * @see         java.awt.EventQueue#invokeLater
  54  * @see         java.awt.EventQueue#invokeAndWait
  55  * @see         AWTEventListener
  56  *
  57  * @since       1.2
  58  */
  59 public class InvocationEvent extends AWTEvent implements ActiveEvent {
  60 
  61     static {
  62         AWTAccessor.setInvocationEventAccessor(new AWTAccessor.InvocationEventAccessor() {
  63             @Override


  89 
  90     /**
  91      * The (potentially null) Object whose notifyAll() method will be called
  92      * immediately after the Runnable.run() method has returned or thrown an exception
  93      * or after the event was disposed.
  94      *
  95      * @see #isDispatched
  96      */
  97     protected volatile Object notifier;
  98 
  99     /**
 100      * The (potentially null) Runnable whose run() method will be called
 101      * immediately after the event was dispatched or disposed.
 102      *
 103      * @see #isDispatched
 104      * @since 1.8
 105      */
 106     private final Runnable listener;
 107 
 108     /**
 109      * Indicates whether the <code>run()</code> method of the <code>runnable</code>
 110      * was executed or not.
 111      *
 112      * @see #isDispatched
 113      * @since 1.7
 114      */
 115     private volatile boolean dispatched = false;
 116 
 117     /**
 118      * Set to true if dispatch() catches Throwable and stores it in the
 119      * exception instance variable. If false, Throwables are propagated up
 120      * to the EventDispatchThread's dispatch loop.
 121      */
 122     protected boolean catchExceptions;
 123 
 124     /**
 125      * The (potentially null) Exception thrown during execution of the
 126      * Runnable.run() method. This variable will also be null if a particular
 127      * instance does not catch exceptions.
 128      */
 129     private Exception exception = null;


 132      * The (potentially null) Throwable thrown during execution of the
 133      * Runnable.run() method. This variable will also be null if a particular
 134      * instance does not catch exceptions.
 135      */
 136     private Throwable throwable = null;
 137 
 138     /**
 139      * The timestamp of when this event occurred.
 140      *
 141      * @serial
 142      * @see #getWhen
 143      */
 144     private long when;
 145 
 146     /*
 147      * JDK 1.1 serialVersionUID.
 148      */
 149     private static final long serialVersionUID = 436056344909459450L;
 150 
 151     /**
 152      * Constructs an <code>InvocationEvent</code> with the specified
 153      * source which will execute the runnable's <code>run</code>
 154      * method when dispatched.
 155      * <p>This is a convenience constructor.  An invocation of the form
 156      * <tt>InvocationEvent(source, runnable)</tt>
 157      * behaves in exactly the same way as the invocation of
 158      * <tt>{@link #InvocationEvent(Object, Runnable, Object, boolean) InvocationEvent}(source, runnable, null, false)</tt>.
 159      * <p> This method throws an <code>IllegalArgumentException</code>
 160      * if <code>source</code> is <code>null</code>.

 161      *
 162      * @param source    The <code>Object</code> that originated the event
 163      * @param runnable  The <code>Runnable</code> whose <code>run</code>
 164      *                  method will be executed
 165      * @throws IllegalArgumentException if <code>source</code> is null
 166      *
 167      * @see #getSource()
 168      * @see #InvocationEvent(Object, Runnable, Object, boolean)
 169      */
 170     public InvocationEvent(Object source, Runnable runnable) {
 171         this(source, INVOCATION_DEFAULT, runnable, null, null, false);
 172     }
 173 
 174     /**
 175      * Constructs an <code>InvocationEvent</code> with the specified
 176      * source which will execute the runnable's <code>run</code>
 177      * method when dispatched.  If notifier is non-<code>null</code>,
 178      * <code>notifyAll()</code> will be called on it
 179      * immediately after <code>run</code> has returned or thrown an exception.
 180      * <p>An invocation of the form <tt>InvocationEvent(source,
 181      * runnable, notifier, catchThrowables)</tt>
 182      * behaves in exactly the same way as the invocation of
 183      * <tt>{@link #InvocationEvent(Object, int, Runnable, Object, boolean) InvocationEvent}(source, InvocationEvent.INVOCATION_DEFAULT, runnable, notifier, catchThrowables)</tt>.
 184      * <p>This method throws an <code>IllegalArgumentException</code>
 185      * if <code>source</code> is <code>null</code>.

 186      *
 187      * @param source            The <code>Object</code> that originated
 188      *                          the event
 189      * @param runnable          The <code>Runnable</code> whose
 190      *                          <code>run</code> method will be
 191      *                          executed
 192      * @param notifier          The {@code Object} whose <code>notifyAll</code>
 193      *                          method will be called after
 194      *                          <code>Runnable.run</code> has returned or
 195      *                          thrown an exception or after the event was
 196      *                          disposed
 197      * @param catchThrowables   Specifies whether <code>dispatch</code>
 198      *                          should catch Throwable when executing
 199      *                          the <code>Runnable</code>'s <code>run</code>
 200      *                          method, or should instead propagate those
 201      *                          Throwables to the EventDispatchThread's
 202      *                          dispatch loop
 203      * @throws IllegalArgumentException if <code>source</code> is null
 204      *
 205      * @see #getSource()
 206      * @see     #InvocationEvent(Object, int, Runnable, Object, boolean)
 207      */
 208     public InvocationEvent(Object source, Runnable runnable, Object notifier,
 209                            boolean catchThrowables) {
 210         this(source, INVOCATION_DEFAULT, runnable, notifier, null, catchThrowables);
 211     }
 212 
 213     /**
 214      * Constructs an <code>InvocationEvent</code> with the specified
 215      * source which will execute the runnable's <code>run</code>
 216      * method when dispatched.  If listener is non-<code>null</code>,
 217      * <code>listener.run()</code> will be called immediately after
 218      * <code>run</code> has returned, thrown an exception or the event
 219      * was disposed.
 220      * <p>This method throws an <code>IllegalArgumentException</code>
 221      * if <code>source</code> is <code>null</code>.
 222      *
 223      * @param source            The <code>Object</code> that originated
 224      *                          the event
 225      * @param runnable          The <code>Runnable</code> whose
 226      *                          <code>run</code> method will be
 227      *                          executed
 228      * @param listener          The <code>Runnable</code>Runnable whose
 229      *                          <code>run()</code> method will be called
 230      *                          after the {@code InvocationEvent}
 231      *                          was dispatched or disposed
 232      * @param catchThrowables   Specifies whether <code>dispatch</code>
 233      *                          should catch Throwable when executing
 234      *                          the <code>Runnable</code>'s <code>run</code>
 235      *                          method, or should instead propagate those
 236      *                          Throwables to the EventDispatchThread's
 237      *                          dispatch loop
 238      * @throws IllegalArgumentException if <code>source</code> is null
 239      */
 240     public InvocationEvent(Object source, Runnable runnable, Runnable listener,
 241                            boolean catchThrowables)  {
 242         this(source, INVOCATION_DEFAULT, runnable, null, listener, catchThrowables);
 243     }
 244 
 245     /**
 246      * Constructs an <code>InvocationEvent</code> with the specified
 247      * source and ID which will execute the runnable's <code>run</code>
 248      * method when dispatched.  If notifier is non-<code>null</code>,
 249      * <code>notifyAll</code> will be called on it immediately after
 250      * <code>run</code> has returned or thrown an exception.
 251      * <p>This method throws an
 252      * <code>IllegalArgumentException</code> if <code>source</code>
 253      * is <code>null</code>.
 254      *
 255      * @param source            The <code>Object</code> that originated
 256      *                          the event
 257      * @param id     An integer indicating the type of event.
 258      *                     For information on allowable values, see
 259      *                     the class description for {@link InvocationEvent}
 260      * @param runnable          The <code>Runnable</code> whose
 261      *                          <code>run</code> method will be executed
 262      * @param notifier          The <code>Object</code> whose <code>notifyAll</code>
 263      *                          method will be called after
 264      *                          <code>Runnable.run</code> has returned or
 265      *                          thrown an exception or after the event was
 266      *                          disposed
 267      * @param catchThrowables   Specifies whether <code>dispatch</code>
 268      *                          should catch Throwable when executing the
 269      *                          <code>Runnable</code>'s <code>run</code>
 270      *                          method, or should instead propagate those
 271      *                          Throwables to the EventDispatchThread's
 272      *                          dispatch loop
 273      * @throws IllegalArgumentException if <code>source</code> is null
 274      * @see #getSource()
 275      * @see #getID()
 276      */
 277     protected InvocationEvent(Object source, int id, Runnable runnable,
 278                               Object notifier, boolean catchThrowables) {
 279         this(source, id, runnable, notifier, null, catchThrowables);
 280     }
 281 
 282     private InvocationEvent(Object source, int id, Runnable runnable,
 283                             Object notifier, Runnable listener, boolean catchThrowables) {
 284         super(source, id);
 285         this.runnable = runnable;
 286         this.notifier = notifier;
 287         this.listener = listener;
 288         this.catchExceptions = catchThrowables;
 289         this.when = System.currentTimeMillis();
 290     }
 291     /**
 292      * Executes the Runnable's <code>run()</code> method and notifies the
 293      * notifier (if any) when <code>run()</code> has returned or thrown an exception.
 294      *
 295      * @see #isDispatched
 296      */
 297     public void dispatch() {
 298         try {
 299             if (catchExceptions) {
 300                 try {
 301                     runnable.run();
 302                 }
 303                 catch (Throwable t) {
 304                     if (t instanceof Exception) {
 305                         exception = (Exception) t;
 306                     }
 307                     throwable = t;
 308                 }
 309             }
 310             else {
 311                 runnable.run();
 312             }
 313         } finally {
 314             finishedDispatching(true);
 315         }
 316     }
 317 
 318     /**
 319      * Returns any Exception caught while executing the Runnable's <code>run()
 320      * </code> method.
 321      *
 322      * @return  A reference to the Exception if one was thrown; null if no
 323      *          Exception was thrown or if this InvocationEvent does not
 324      *          catch exceptions
 325      */
 326     public Exception getException() {
 327         return (catchExceptions) ? exception : null;
 328     }
 329 
 330     /**
 331      * Returns any Throwable caught while executing the Runnable's <code>run()
 332      * </code> method.
 333      *
 334      * @return  A reference to the Throwable if one was thrown; null if no
 335      *          Throwable was thrown or if this InvocationEvent does not
 336      *          catch Throwables
 337      * @since 1.5
 338      */
 339     public Throwable getThrowable() {
 340         return (catchExceptions) ? throwable : null;
 341     }
 342 
 343     /**
 344      * Returns the timestamp of when this event occurred.
 345      *
 346      * @return this event's timestamp
 347      * @since 1.4
 348      */
 349     public long getWhen() {
 350         return when;
 351     }
 352 




  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package java.awt.event;
  27 
  28 import sun.awt.AWTAccessor;
  29 
  30 import java.awt.ActiveEvent;
  31 import java.awt.AWTEvent;
  32 
  33 /**
  34  * An event which executes the {@code run()} method on a {@code Runnable
  35  * } when dispatched by the AWT event dispatcher thread. This class can
  36  * be used as a reference implementation of {@code ActiveEvent} rather
  37  * than declaring a new class and defining {@code dispatch()}.<p>
  38  *
  39  * Instances of this class are placed on the {@code EventQueue} by calls
  40  * to {@code invokeLater} and {@code invokeAndWait}. Client code
  41  * can use this fact to write replacement functions for {@code invokeLater
  42  * } and {@code invokeAndWait} without writing special-case code
  43  * in any {@code AWTEventListener} objects.
  44  * <p>
  45  * An unspecified behavior will be caused if the {@code id} parameter
  46  * of any particular {@code InvocationEvent} instance is not
  47  * in the range from {@code INVOCATION_FIRST} to {@code INVOCATION_LAST}.
  48  *
  49  * @author      Fred Ecks
  50  * @author      David Mendenhall
  51  *
  52  * @see         java.awt.ActiveEvent
  53  * @see         java.awt.EventQueue#invokeLater
  54  * @see         java.awt.EventQueue#invokeAndWait
  55  * @see         AWTEventListener
  56  *
  57  * @since       1.2
  58  */
  59 public class InvocationEvent extends AWTEvent implements ActiveEvent {
  60 
  61     static {
  62         AWTAccessor.setInvocationEventAccessor(new AWTAccessor.InvocationEventAccessor() {
  63             @Override


  89 
  90     /**
  91      * The (potentially null) Object whose notifyAll() method will be called
  92      * immediately after the Runnable.run() method has returned or thrown an exception
  93      * or after the event was disposed.
  94      *
  95      * @see #isDispatched
  96      */
  97     protected volatile Object notifier;
  98 
  99     /**
 100      * The (potentially null) Runnable whose run() method will be called
 101      * immediately after the event was dispatched or disposed.
 102      *
 103      * @see #isDispatched
 104      * @since 1.8
 105      */
 106     private final Runnable listener;
 107 
 108     /**
 109      * Indicates whether the {@code run()} method of the {@code runnable}
 110      * was executed or not.
 111      *
 112      * @see #isDispatched
 113      * @since 1.7
 114      */
 115     private volatile boolean dispatched = false;
 116 
 117     /**
 118      * Set to true if dispatch() catches Throwable and stores it in the
 119      * exception instance variable. If false, Throwables are propagated up
 120      * to the EventDispatchThread's dispatch loop.
 121      */
 122     protected boolean catchExceptions;
 123 
 124     /**
 125      * The (potentially null) Exception thrown during execution of the
 126      * Runnable.run() method. This variable will also be null if a particular
 127      * instance does not catch exceptions.
 128      */
 129     private Exception exception = null;


 132      * The (potentially null) Throwable thrown during execution of the
 133      * Runnable.run() method. This variable will also be null if a particular
 134      * instance does not catch exceptions.
 135      */
 136     private Throwable throwable = null;
 137 
 138     /**
 139      * The timestamp of when this event occurred.
 140      *
 141      * @serial
 142      * @see #getWhen
 143      */
 144     private long when;
 145 
 146     /*
 147      * JDK 1.1 serialVersionUID.
 148      */
 149     private static final long serialVersionUID = 436056344909459450L;
 150 
 151     /**
 152      * Constructs an {@code InvocationEvent} with the specified
 153      * source which will execute the runnable's {@code run}
 154      * method when dispatched.
 155      * <p>This is a convenience constructor.  An invocation of the form
 156      * {@code InvocationEvent(source, runnable)}
 157      * behaves in exactly the same way as the invocation of
 158      * {@link #InvocationEvent(Object, Runnable, Object, boolean) 
 159      * InvocationEvent(source, runnable, null, false)}.
 160      * <p> This method throws an {@code IllegalArgumentException}
 161      * if {@code source} is {@code null}.
 162      *
 163      * @param source    The {@code Object} that originated the event
 164      * @param runnable  The {@code Runnable} whose {@code run}
 165      *                  method will be executed
 166      * @throws IllegalArgumentException if {@code source} is null
 167      *
 168      * @see #getSource()
 169      * @see #InvocationEvent(Object, Runnable, Object, boolean)
 170      */
 171     public InvocationEvent(Object source, Runnable runnable) {
 172         this(source, INVOCATION_DEFAULT, runnable, null, null, false);
 173     }
 174 
 175     /**
 176      * Constructs an {@code InvocationEvent} with the specified
 177      * source which will execute the runnable's {@code run}
 178      * method when dispatched.  If notifier is non-{@code null},
 179      * {@code notifyAll()} will be called on it
 180      * immediately after {@code run} has returned or thrown an exception.
 181      * <p>An invocation of the form 
 182      * {@code InvocationEvent(source, runnable, notifier, catchThrowables)}
 183      * behaves in exactly the same way as the invocation of
 184      * {@link #InvocationEvent(Object, int, Runnable, Object, boolean)
 185      * InvocationEvent(source, InvocationEvent.INVOCATION_DEFAULT, runnable, notifier, catchThrowables)}.
 186      * <p>This method throws an {@code IllegalArgumentException}
 187      * if {@code source} is {@code null}.
 188      *
 189      * @param source            The {@code Object} that originated
 190      *                          the event
 191      * @param runnable          The {@code Runnable} whose
 192      *                          {@code run} method will be
 193      *                          executed
 194      * @param notifier          The {@code Object} whose {@code notifyAll}
 195      *                          method will be called after
 196      *                          {@code Runnable.run} has returned or
 197      *                          thrown an exception or after the event was
 198      *                          disposed
 199      * @param catchThrowables   Specifies whether {@code dispatch}
 200      *                          should catch Throwable when executing
 201      *                          the {@code Runnable}'s {@code run}
 202      *                          method, or should instead propagate those
 203      *                          Throwables to the EventDispatchThread's
 204      *                          dispatch loop
 205      * @throws IllegalArgumentException if {@code source} is null
 206      *
 207      * @see #getSource()
 208      * @see     #InvocationEvent(Object, int, Runnable, Object, boolean)
 209      */
 210     public InvocationEvent(Object source, Runnable runnable, Object notifier,
 211                            boolean catchThrowables) {
 212         this(source, INVOCATION_DEFAULT, runnable, notifier, null, catchThrowables);
 213     }
 214 
 215     /**
 216      * Constructs an {@code InvocationEvent} with the specified
 217      * source which will execute the runnable's {@code run}
 218      * method when dispatched.  If listener is non-{@code null},
 219      * {@code listener.run()} will be called immediately after
 220      * {@code run} has returned, thrown an exception or the event
 221      * was disposed.
 222      * <p>This method throws an {@code IllegalArgumentException}
 223      * if {@code source} is {@code null}.
 224      *
 225      * @param source            The {@code Object} that originated
 226      *                          the event
 227      * @param runnable          The {@code Runnable} whose
 228      *                          {@code run} method will be
 229      *                          executed
 230      * @param listener          The {@code Runnable}Runnable whose
 231      *                          {@code run()} method will be called
 232      *                          after the {@code InvocationEvent}
 233      *                          was dispatched or disposed
 234      * @param catchThrowables   Specifies whether {@code dispatch}
 235      *                          should catch Throwable when executing
 236      *                          the {@code Runnable}'s {@code run}
 237      *                          method, or should instead propagate those
 238      *                          Throwables to the EventDispatchThread's
 239      *                          dispatch loop
 240      * @throws IllegalArgumentException if {@code source} is null
 241      */
 242     public InvocationEvent(Object source, Runnable runnable, Runnable listener,
 243                            boolean catchThrowables)  {
 244         this(source, INVOCATION_DEFAULT, runnable, null, listener, catchThrowables);
 245     }
 246 
 247     /**
 248      * Constructs an {@code InvocationEvent} with the specified
 249      * source and ID which will execute the runnable's {@code run}
 250      * method when dispatched.  If notifier is non-{@code null},
 251      * {@code notifyAll} will be called on it immediately after
 252      * {@code run} has returned or thrown an exception.
 253      * <p>This method throws an
 254      * {@code IllegalArgumentException} if {@code source}
 255      * is {@code null}.
 256      *
 257      * @param source            The {@code Object} that originated
 258      *                          the event
 259      * @param id     An integer indicating the type of event.
 260      *                     For information on allowable values, see
 261      *                     the class description for {@link InvocationEvent}
 262      * @param runnable          The {@code Runnable} whose
 263      *                          {@code run} method will be executed
 264      * @param notifier          The {@code Object} whose {@code notifyAll}
 265      *                          method will be called after
 266      *                          {@code Runnable.run} has returned or
 267      *                          thrown an exception or after the event was
 268      *                          disposed
 269      * @param catchThrowables   Specifies whether {@code dispatch}
 270      *                          should catch Throwable when executing the
 271      *                          {@code Runnable}'s {@code run}
 272      *                          method, or should instead propagate those
 273      *                          Throwables to the EventDispatchThread's
 274      *                          dispatch loop
 275      * @throws IllegalArgumentException if {@code source} is null
 276      * @see #getSource()
 277      * @see #getID()
 278      */
 279     protected InvocationEvent(Object source, int id, Runnable runnable,
 280                               Object notifier, boolean catchThrowables) {
 281         this(source, id, runnable, notifier, null, catchThrowables);
 282     }
 283 
 284     private InvocationEvent(Object source, int id, Runnable runnable,
 285                             Object notifier, Runnable listener, boolean catchThrowables) {
 286         super(source, id);
 287         this.runnable = runnable;
 288         this.notifier = notifier;
 289         this.listener = listener;
 290         this.catchExceptions = catchThrowables;
 291         this.when = System.currentTimeMillis();
 292     }
 293     /**
 294      * Executes the Runnable's {@code run()} method and notifies the
 295      * notifier (if any) when {@code run()} has returned or thrown an exception.
 296      *
 297      * @see #isDispatched
 298      */
 299     public void dispatch() {
 300         try {
 301             if (catchExceptions) {
 302                 try {
 303                     runnable.run();
 304                 }
 305                 catch (Throwable t) {
 306                     if (t instanceof Exception) {
 307                         exception = (Exception) t;
 308                     }
 309                     throwable = t;
 310                 }
 311             }
 312             else {
 313                 runnable.run();
 314             }
 315         } finally {
 316             finishedDispatching(true);
 317         }
 318     }
 319 
 320     /**
 321      * Returns any Exception caught while executing
 322      * the Runnable's {@code run()} method.
 323      *
 324      * @return  A reference to the Exception if one was thrown; null if no
 325      *          Exception was thrown or if this InvocationEvent does not
 326      *          catch exceptions
 327      */
 328     public Exception getException() {
 329         return (catchExceptions) ? exception : null;
 330     }
 331 
 332     /**
 333      * Returns any Throwable caught while executing
 334      * the Runnable's {@code run()} method.
 335      *
 336      * @return  A reference to the Throwable if one was thrown; null if no
 337      *          Throwable was thrown or if this InvocationEvent does not
 338      *          catch Throwables
 339      * @since 1.5
 340      */
 341     public Throwable getThrowable() {
 342         return (catchExceptions) ? throwable : null;
 343     }
 344 
 345     /**
 346      * Returns the timestamp of when this event occurred.
 347      *
 348      * @return this event's timestamp
 349      * @since 1.4
 350      */
 351     public long getWhen() {
 352         return when;
 353     }
 354 


< prev index next >