001 /*
002 * Copyright 1998-2006 Sun Microsystems, Inc. All Rights Reserved.
003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004 *
005 * This code is free software; you can redistribute it and/or modify it
006 * under the terms of the GNU General Public License version 2 only, as
007 * published by the Free Software Foundation. Sun designates this
008 * particular file as subject to the "Classpath" exception as provided
009 * by Sun in the LICENSE file that accompanied this code.
010 *
011 * This code is distributed in the hope that it will be useful, but WITHOUT
012 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014 * version 2 for more details (a copy is included in the LICENSE file that
015 * accompanied this code).
016 *
017 * You should have received a copy of the GNU General Public License version
018 * 2 along with this work; if not, write to the Free Software Foundation,
019 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020 *
021 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022 * CA 95054 USA or visit www.sun.com if you need additional information or
023 * have any questions.
024 */
025
026 package java.awt.event;
027
028 import java.awt.ActiveEvent;
029 import java.awt.AWTEvent;
030
031 /**
032 * An event which executes the <code>run()</code> method on a <code>Runnable
033 * </code> when dispatched by the AWT event dispatcher thread. This class can
034 * be used as a reference implementation of <code>ActiveEvent</code> rather
035 * than declaring a new class and defining <code>dispatch()</code>.<p>
036 *
037 * Instances of this class are placed on the <code>EventQueue</code> by calls
038 * to <code>invokeLater</code> and <code>invokeAndWait</code>. Client code
039 * can use this fact to write replacement functions for <code>invokeLater
040 * </code> and <code>invokeAndWait</code> without writing special-case code
041 * in any <code>AWTEventListener</code> objects.
042 *
043 * @author Fred Ecks
044 * @author David Mendenhall
045 * @version 1.27, 05/05/07
046 *
047 * @see java.awt.ActiveEvent
048 * @see java.awt.EventQueue#invokeLater
049 * @see java.awt.EventQueue#invokeAndWait
050 * @see AWTEventListener
051 *
052 * @since 1.2
053 */
054 public class InvocationEvent extends AWTEvent implements ActiveEvent {
055
056 /**
057 * Marks the first integer id for the range of invocation event ids.
058 */
059 public static final int INVOCATION_FIRST = 1200;
060
061 /**
062 * The default id for all InvocationEvents.
063 */
064 public static final int INVOCATION_DEFAULT = INVOCATION_FIRST;
065
066 /**
067 * Marks the last integer id for the range of invocation event ids.
068 */
069 public static final int INVOCATION_LAST = INVOCATION_DEFAULT;
070
071 /**
072 * The Runnable whose run() method will be called.
073 */
074 protected Runnable runnable;
075
076 /**
077 * The (potentially null) Object whose notifyAll() method will be called
078 * immediately after the Runnable.run() method returns.
079 */
080 protected Object notifier;
081
082 /**
083 * Set to true if dispatch() catches Throwable and stores it in the
084 * exception instance variable. If false, Throwables are propagated up
085 * to the EventDispatchThread's dispatch loop.
086 */
087 protected boolean catchExceptions;
088
089 /**
090 * The (potentially null) Exception thrown during execution of the
091 * Runnable.run() method. This variable will also be null if a particular
092 * instance does not catch exceptions.
093 */
094 private Exception exception = null;
095
096 /**
097 * The (potentially null) Throwable thrown during execution of the
098 * Runnable.run() method. This variable will also be null if a particular
099 * instance does not catch exceptions.
100 */
101 private Throwable throwable = null;
102
103 /**
104 * The timestamp of when this event occurred.
105 *
106 * @serial
107 * @see #getWhen
108 */
109 private long when;
110
111 /*
112 * JDK 1.1 serialVersionUID.
113 */
114 private static final long serialVersionUID = 436056344909459450L;
115
116 /**
117 * Constructs an <code>InvocationEvent</code> with the specified
118 * source which will execute the runnable's <code>run</code>
119 * method when dispatched.
120 * <p>This is a convenience constructor. An invocation of the form
121 * <tt>InvocationEvent(source, runnable)</tt>
122 * behaves in exactly the same way as the invocation of
123 * <tt>{@link #InvocationEvent(Object, Runnable, Object, boolean) InvocationEvent}(source, runnable, null, false)</tt>.
124 * <p> This method throws an <code>IllegalArgumentException</code>
125 * if <code>source</code> is <code>null</code>.
126 *
127 * @param source the <code>Object</code> that originated the event
128 * @param runnable the <code>Runnable</code> whose <code>run</code>
129 * method will be executed
130 * @throws IllegalArgumentException if <code>source</code> is null
131 *
132 * @see #InvocationEvent(Object, Runnable, Object, boolean)
133 */
134 public InvocationEvent(Object source, Runnable runnable) {
135 this (source, runnable, null, false);
136 }
137
138 /**
139 * Constructs an <code>InvocationEvent</code> with the specified
140 * source which will execute the runnable's <code>run</code>
141 * method when dispatched. If notifier is non-<code>null</code>,
142 * <code>notifyAll()</code> will be called on it
143 * immediately after <code>run</code> returns.
144 * <p>An invocation of the form <tt>InvocationEvent(source,
145 * runnable, notifier, catchThrowables)</tt>
146 * behaves in exactly the same way as the invocation of
147 * <tt>{@link #InvocationEvent(Object, int, Runnable, Object, boolean) InvocationEvent}(source, InvocationEvent.INVOCATION_DEFAULT, runnable, notifier, catchThrowables)</tt>.
148 * <p>This method throws an <code>IllegalArgumentException</code>
149 * if <code>source</code> is <code>null</code>.
150 *
151 * @param source the <code>Object</code> that originated
152 * the event
153 * @param runnable the <code>Runnable</code> whose
154 * <code>run</code> method will be
155 * executed
156 * @param notifier the Object whose <code>notifyAll</code>
157 * method will be called after
158 * <code>Runnable.run</code> has returned
159 * @param catchThrowables specifies whether <code>dispatch</code>
160 * should catch Throwable when executing
161 * the <code>Runnable</code>'s <code>run</code>
162 * method, or should instead propagate those
163 * Throwables to the EventDispatchThread's
164 * dispatch loop
165 * @throws IllegalArgumentException if <code>source</code> is null
166 *
167 * @see #InvocationEvent(Object, int, Runnable, Object, boolean)
168 */
169 public InvocationEvent(Object source, Runnable runnable,
170 Object notifier, boolean catchThrowables) {
171 this (source, INVOCATION_DEFAULT, runnable, notifier,
172 catchThrowables);
173 }
174
175 /**
176 * Constructs an <code>InvocationEvent</code> with the specified
177 * source and ID which will execute the runnable's <code>run</code>
178 * method when dispatched. If notifier is non-<code>null</code>,
179 * <code>notifyAll</code> will be called on it
180 * immediately after <code>run</code> returns.
181 * <p>Note that passing in an invalid <code>id</code> results in
182 * unspecified behavior. This method throws an
183 * <code>IllegalArgumentException</code> if <code>source</code>
184 * is <code>null</code>.
185 *
186 * @param source the <code>Object</code> that originated
187 * the event
188 * @param id the ID for the event
189 * @param runnable the <code>Runnable</code> whose
190 * <code>run</code> method will be executed
191 * @param notifier the <code>Object</code> whose <code>notifyAll</code>
192 * method will be called after
193 * <code>Runnable.run</code> has returned
194 * @param catchThrowables specifies whether <code>dispatch</code>
195 * should catch Throwable when executing the
196 * <code>Runnable</code>'s <code>run</code>
197 * method, or should instead propagate those
198 * Throwables to the EventDispatchThread's
199 * dispatch loop
200 * @throws IllegalArgumentException if <code>source</code> is null
201 */
202 protected InvocationEvent(Object source, int id, Runnable runnable,
203 Object notifier, boolean catchThrowables) {
204 super (source, id);
205 this .runnable = runnable;
206 this .notifier = notifier;
207 this .catchExceptions = catchThrowables;
208 this .when = System.currentTimeMillis();
209 }
210
211 /**
212 * Executes the Runnable's <code>run()</code> method and notifies the
213 * notifier (if any) when <code>run()</code> returns.
214 */
215 public void dispatch() {
216 if (catchExceptions) {
217 try {
218 runnable.run();
219 } catch (Throwable t) {
220 if (t instanceof Exception) {
221 exception = (Exception) t;
222 }
223 throwable = t;
224 }
225 } else {
226 runnable.run();
227 }
228
229 if (notifier != null) {
230 synchronized (notifier) {
231 notifier.notifyAll();
232 }
233 }
234 }
235
236 /**
237 * Returns any Exception caught while executing the Runnable's <code>run()
238 * </code> method.
239 *
240 * @return A reference to the Exception if one was thrown; null if no
241 * Exception was thrown or if this InvocationEvent does not
242 * catch exceptions
243 */
244 public Exception getException() {
245 return (catchExceptions) ? exception : null;
246 }
247
248 /**
249 * Returns any Throwable caught while executing the Runnable's <code>run()
250 * </code> method.
251 *
252 * @return A reference to the Throwable if one was thrown; null if no
253 * Throwable was thrown or if this InvocationEvent does not
254 * catch Throwables
255 * @since 1.5
256 */
257 public Throwable getThrowable() {
258 return (catchExceptions) ? throwable : null;
259 }
260
261 /**
262 * Returns the timestamp of when this event occurred.
263 *
264 * @return this event's timestamp
265 * @since 1.4
266 */
267 public long getWhen() {
268 return when;
269 }
270
271 /**
272 * Returns a parameter string identifying this event.
273 * This method is useful for event-logging and for debugging.
274 *
275 * @return A string identifying the event and its attributes
276 */
277 public String paramString() {
278 String typeStr;
279 switch (id) {
280 case INVOCATION_DEFAULT:
281 typeStr = "INVOCATION_DEFAULT";
282 break;
283 default:
284 typeStr = "unknown type";
285 }
286 return typeStr + ",runnable=" + runnable + ",notifier="
287 + notifier + ",catchExceptions=" + catchExceptions
288 + ",when=" + when;
289 }
290 }
|