jdk/src/share/classes/java/awt/event/InvocationEvent.java
changeset 4264 40c232605c68
parent 440 a3dac373f62d
child 5506 202f599c92aa
equal deleted inserted replaced
4263:db2d1f69a60e 4264:40c232605c68
    76      */
    76      */
    77     protected Runnable runnable;
    77     protected Runnable runnable;
    78 
    78 
    79     /**
    79     /**
    80      * The (potentially null) Object whose notifyAll() method will be called
    80      * The (potentially null) Object whose notifyAll() method will be called
    81      * immediately after the Runnable.run() method returns.
    81      * immediately after the Runnable.run() method has returned or thrown an exception.
       
    82      *
       
    83      * @see #isDispatched
    82      */
    84      */
    83     protected Object notifier;
    85     protected Object notifier;
       
    86 
       
    87     /**
       
    88      * Indicates whether the <code>run()</code> method of the <code>runnable</code>
       
    89      * was executed or not.
       
    90      *
       
    91      * @see #isDispatched
       
    92      * @since 1.7
       
    93      */
       
    94     private volatile boolean dispatched = false;
    84 
    95 
    85     /**
    96     /**
    86      * Set to true if dispatch() catches Throwable and stores it in the
    97      * Set to true if dispatch() catches Throwable and stores it in the
    87      * exception instance variable. If false, Throwables are propagated up
    98      * exception instance variable. If false, Throwables are propagated up
    88      * to the EventDispatchThread's dispatch loop.
    99      * to the EventDispatchThread's dispatch loop.
   142     /**
   153     /**
   143      * Constructs an <code>InvocationEvent</code> with the specified
   154      * Constructs an <code>InvocationEvent</code> with the specified
   144      * source which will execute the runnable's <code>run</code>
   155      * source which will execute the runnable's <code>run</code>
   145      * method when dispatched.  If notifier is non-<code>null</code>,
   156      * method when dispatched.  If notifier is non-<code>null</code>,
   146      * <code>notifyAll()</code> will be called on it
   157      * <code>notifyAll()</code> will be called on it
   147      * immediately after <code>run</code> returns.
   158      * immediately after <code>run</code> has returned or thrown an exception.
   148      * <p>An invocation of the form <tt>InvocationEvent(source,
   159      * <p>An invocation of the form <tt>InvocationEvent(source,
   149      * runnable, notifier, catchThrowables)</tt>
   160      * runnable, notifier, catchThrowables)</tt>
   150      * behaves in exactly the same way as the invocation of
   161      * behaves in exactly the same way as the invocation of
   151      * <tt>{@link #InvocationEvent(Object, int, Runnable, Object, boolean) InvocationEvent}(source, InvocationEvent.INVOCATION_DEFAULT, runnable, notifier, catchThrowables)</tt>.
   162      * <tt>{@link #InvocationEvent(Object, int, Runnable, Object, boolean) InvocationEvent}(source, InvocationEvent.INVOCATION_DEFAULT, runnable, notifier, catchThrowables)</tt>.
   152      * <p>This method throws an <code>IllegalArgumentException</code>
   163      * <p>This method throws an <code>IllegalArgumentException</code>
   157      * @param runnable          The <code>Runnable</code> whose
   168      * @param runnable          The <code>Runnable</code> whose
   158      *                          <code>run</code> method will be
   169      *                          <code>run</code> method will be
   159      *                          executed
   170      *                          executed
   160      * @param notifier          The {@code Object} whose <code>notifyAll</code>
   171      * @param notifier          The {@code Object} whose <code>notifyAll</code>
   161      *                          method will be called after
   172      *                          method will be called after
   162      *                          <code>Runnable.run</code> has returned
   173      *                          <code>Runnable.run</code> has returned or
       
   174      *                          thrown an exception
   163      * @param catchThrowables   Specifies whether <code>dispatch</code>
   175      * @param catchThrowables   Specifies whether <code>dispatch</code>
   164      *                          should catch Throwable when executing
   176      *                          should catch Throwable when executing
   165      *                          the <code>Runnable</code>'s <code>run</code>
   177      *                          the <code>Runnable</code>'s <code>run</code>
   166      *                          method, or should instead propagate those
   178      *                          method, or should instead propagate those
   167      *                          Throwables to the EventDispatchThread's
   179      *                          Throwables to the EventDispatchThread's
   178 
   190 
   179     /**
   191     /**
   180      * Constructs an <code>InvocationEvent</code> with the specified
   192      * Constructs an <code>InvocationEvent</code> with the specified
   181      * source and ID which will execute the runnable's <code>run</code>
   193      * source and ID which will execute the runnable's <code>run</code>
   182      * method when dispatched.  If notifier is non-<code>null</code>,
   194      * method when dispatched.  If notifier is non-<code>null</code>,
   183      * <code>notifyAll</code> will be called on it
   195      * <code>notifyAll</code> will be called on it immediately after
   184      * immediately after <code>run</code> returns.
   196      * <code>run</code> has returned or thrown an exception.
   185      * <p>This method throws an
   197      * <p>This method throws an
   186      * <code>IllegalArgumentException</code> if <code>source</code>
   198      * <code>IllegalArgumentException</code> if <code>source</code>
   187      * is <code>null</code>.
   199      * is <code>null</code>.
   188      *
   200      *
   189      * @param source            The <code>Object</code> that originated
   201      * @param source            The <code>Object</code> that originated
   193      *                     the class description for {@link InvocationEvent}
   205      *                     the class description for {@link InvocationEvent}
   194      * @param runnable          The <code>Runnable</code> whose
   206      * @param runnable          The <code>Runnable</code> whose
   195      *                          <code>run</code> method will be executed
   207      *                          <code>run</code> method will be executed
   196      * @param notifier          The <code>Object</code> whose <code>notifyAll</code>
   208      * @param notifier          The <code>Object</code> whose <code>notifyAll</code>
   197      *                          method will be called after
   209      *                          method will be called after
   198      *                          <code>Runnable.run</code> has returned
   210      *                          <code>Runnable.run</code> has returned or
       
   211      *                          thrown an exception
   199      * @param catchThrowables   Specifies whether <code>dispatch</code>
   212      * @param catchThrowables   Specifies whether <code>dispatch</code>
   200      *                          should catch Throwable when executing the
   213      *                          should catch Throwable when executing the
   201      *                          <code>Runnable</code>'s <code>run</code>
   214      *                          <code>Runnable</code>'s <code>run</code>
   202      *                          method, or should instead propagate those
   215      *                          method, or should instead propagate those
   203      *                          Throwables to the EventDispatchThread's
   216      *                          Throwables to the EventDispatchThread's
   215         this.when = System.currentTimeMillis();
   228         this.when = System.currentTimeMillis();
   216     }
   229     }
   217 
   230 
   218     /**
   231     /**
   219      * Executes the Runnable's <code>run()</code> method and notifies the
   232      * Executes the Runnable's <code>run()</code> method and notifies the
   220      * notifier (if any) when <code>run()</code> returns.
   233      * notifier (if any) when <code>run()</code> has returned or thrown an exception.
       
   234      *
       
   235      * @see #isDispatched
   221      */
   236      */
   222     public void dispatch() {
   237     public void dispatch() {
   223         if (catchExceptions) {
   238         try {
   224             try {
   239             if (catchExceptions) {
       
   240                 try {
       
   241                     runnable.run();
       
   242                 }
       
   243                 catch (Throwable t) {
       
   244                     if (t instanceof Exception) {
       
   245                         exception = (Exception) t;
       
   246                     }
       
   247                     throwable = t;
       
   248                 }
       
   249             }
       
   250             else {
   225                 runnable.run();
   251                 runnable.run();
   226             }
   252             }
   227             catch (Throwable t) {
   253         } finally {
   228                 if (t instanceof Exception) {
   254             dispatched = true;
   229                     exception = (Exception) t;
   255 
       
   256             if (notifier != null) {
       
   257                 synchronized (notifier) {
       
   258                     notifier.notifyAll();
   230                 }
   259                 }
   231                 throwable = t;
       
   232             }
       
   233         }
       
   234         else {
       
   235             runnable.run();
       
   236         }
       
   237 
       
   238         if (notifier != null) {
       
   239             synchronized (notifier) {
       
   240                 notifier.notifyAll();
       
   241             }
   260             }
   242         }
   261         }
   243     }
   262     }
   244 
   263 
   245     /**
   264     /**
   273      * @return this event's timestamp
   292      * @return this event's timestamp
   274      * @since 1.4
   293      * @since 1.4
   275      */
   294      */
   276     public long getWhen() {
   295     public long getWhen() {
   277         return when;
   296         return when;
       
   297     }
       
   298 
       
   299     /**
       
   300      * Returns {@code true} if the event is dispatched or any exception is
       
   301      * thrown while dispatching, {@code false} otherwise. The method should
       
   302      * be called by a waiting thread that calls the {@code notifier.wait()} method.
       
   303      * Since spurious wakeups are possible (as explained in {@link Object#wait()}),
       
   304      * this method should be used in a waiting loop to ensure that the event
       
   305      * got dispatched:
       
   306      * <pre>
       
   307      *     while (!event.isDispatched()) {
       
   308      *         notifier.wait();
       
   309      *     }
       
   310      * </pre>
       
   311      * If the waiting thread wakes up without dispatching the event,
       
   312      * the {@code isDispatched()} method returns {@code false}, and
       
   313      * the {@code while} loop executes once more, thus, causing
       
   314      * the awakened thread to revert to the waiting mode.
       
   315      * <p>
       
   316      * If the {@code notifier.notifyAll()} happens before the waiting thread
       
   317      * enters the {@code notifier.wait()} method, the {@code while} loop ensures
       
   318      * that the waiting thread will not enter the {@code notifier.wait()} method.
       
   319      * Otherwise, there is no guarantee that the waiting thread will ever be woken
       
   320      * from the wait.
       
   321      *
       
   322      * @return {@code true} if the event has been dispatched, or any exception
       
   323      * has been thrown while dispatching, {@code false} otherwise
       
   324      * @see #dispatch
       
   325      * @see #notifier
       
   326      * @see #catchExceptions
       
   327      * @since 1.7
       
   328      */
       
   329     public boolean isDispatched() {
       
   330         return dispatched;
   278     }
   331     }
   279 
   332 
   280     /**
   333     /**
   281      * Returns a parameter string identifying this event.
   334      * Returns a parameter string identifying this event.
   282      * This method is useful for event-logging and for debugging.
   335      * This method is useful for event-logging and for debugging.