blob: 705f87a12e437cdc206db500276359d919994be6 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 1998-2006 Sun Microsystems, Inc. All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25
26package java.awt.event;
27
28import java.awt.ActiveEvent;
29import java.awt.AWTEvent;
30
31/**
32 * An event which executes the <code>run()</code> method on a <code>Runnable
33 * </code> when dispatched by the AWT event dispatcher thread. This class can
34 * be used as a reference implementation of <code>ActiveEvent</code> rather
35 * than declaring a new class and defining <code>dispatch()</code>.<p>
36 *
37 * Instances of this class are placed on the <code>EventQueue</code> by calls
38 * to <code>invokeLater</code> and <code>invokeAndWait</code>. Client code
39 * can use this fact to write replacement functions for <code>invokeLater
40 * </code> and <code>invokeAndWait</code> without writing special-case code
41 * in any <code>AWTEventListener</code> objects.
42 *
43 * @author Fred Ecks
44 * @author David Mendenhall
45 *
46 * @see java.awt.ActiveEvent
47 * @see java.awt.EventQueue#invokeLater
48 * @see java.awt.EventQueue#invokeAndWait
49 * @see AWTEventListener
50 *
51 * @since 1.2
52 */
53public class InvocationEvent extends AWTEvent implements ActiveEvent {
54
55 /**
56 * Marks the first integer id for the range of invocation event ids.
57 */
58 public static final int INVOCATION_FIRST = 1200;
59
60 /**
61 * The default id for all InvocationEvents.
62 */
63 public static final int INVOCATION_DEFAULT = INVOCATION_FIRST;
64
65 /**
66 * Marks the last integer id for the range of invocation event ids.
67 */
68 public static final int INVOCATION_LAST = INVOCATION_DEFAULT;
69
70 /**
71 * The Runnable whose run() method will be called.
72 */
73 protected Runnable runnable;
74
75 /**
76 * The (potentially null) Object whose notifyAll() method will be called
77 * immediately after the Runnable.run() method returns.
78 */
79 protected Object notifier;
80
81 /**
82 * Set to true if dispatch() catches Throwable and stores it in the
83 * exception instance variable. If false, Throwables are propagated up
84 * to the EventDispatchThread's dispatch loop.
85 */
86 protected boolean catchExceptions;
87
88 /**
89 * The (potentially null) Exception thrown during execution of the
90 * Runnable.run() method. This variable will also be null if a particular
91 * instance does not catch exceptions.
92 */
93 private Exception exception = null;
94
95 /**
96 * The (potentially null) Throwable thrown during execution of the
97 * Runnable.run() method. This variable will also be null if a particular
98 * instance does not catch exceptions.
99 */
100 private Throwable throwable = null;
101
102 /**
103 * The timestamp of when this event occurred.
104 *
105 * @serial
106 * @see #getWhen
107 */
108 private long when;
109
110 /*
111 * JDK 1.1 serialVersionUID.
112 */
113 private static final long serialVersionUID = 436056344909459450L;
114
115 /**
116 * Constructs an <code>InvocationEvent</code> with the specified
117 * source which will execute the runnable's <code>run</code>
118 * method when dispatched.
119 * <p>This is a convenience constructor. An invocation of the form
120 * <tt>InvocationEvent(source, runnable)</tt>
121 * behaves in exactly the same way as the invocation of
122 * <tt>{@link #InvocationEvent(Object, Runnable, Object, boolean) InvocationEvent}(source, runnable, null, false)</tt>.
123 * <p> This method throws an <code>IllegalArgumentException</code>
124 * if <code>source</code> is <code>null</code>.
125 *
126 * @param source the <code>Object</code> that originated the event
127 * @param runnable the <code>Runnable</code> whose <code>run</code>
128 * method will be executed
129 * @throws IllegalArgumentException if <code>source</code> is null
130 *
131 * @see #InvocationEvent(Object, Runnable, Object, boolean)
132 */
133 public InvocationEvent(Object source, Runnable runnable) {
134 this(source, runnable, null, false);
135 }
136
137 /**
138 * Constructs an <code>InvocationEvent</code> with the specified
139 * source which will execute the runnable's <code>run</code>
140 * method when dispatched. If notifier is non-<code>null</code>,
141 * <code>notifyAll()</code> will be called on it
142 * immediately after <code>run</code> returns.
143 * <p>An invocation of the form <tt>InvocationEvent(source,
144 * runnable, notifier, catchThrowables)</tt>
145 * behaves in exactly the same way as the invocation of
146 * <tt>{@link #InvocationEvent(Object, int, Runnable, Object, boolean) InvocationEvent}(source, InvocationEvent.INVOCATION_DEFAULT, runnable, notifier, catchThrowables)</tt>.
147 * <p>This method throws an <code>IllegalArgumentException</code>
148 * if <code>source</code> is <code>null</code>.
149 *
150 * @param source the <code>Object</code> that originated
151 * the event
152 * @param runnable the <code>Runnable</code> whose
153 * <code>run</code> method will be
154 * executed
155 * @param notifier the Object whose <code>notifyAll</code>
156 * method will be called after
157 * <code>Runnable.run</code> has returned
158 * @param catchThrowables specifies whether <code>dispatch</code>
159 * should catch Throwable when executing
160 * the <code>Runnable</code>'s <code>run</code>
161 * method, or should instead propagate those
162 * Throwables to the EventDispatchThread's
163 * dispatch loop
164 * @throws IllegalArgumentException if <code>source</code> is null
165 *
166 * @see #InvocationEvent(Object, int, Runnable, Object, boolean)
167 */
168 public InvocationEvent(Object source, Runnable runnable, Object notifier,
169 boolean catchThrowables) {
170 this(source, INVOCATION_DEFAULT, runnable, notifier, catchThrowables);
171 }
172
173 /**
174 * Constructs an <code>InvocationEvent</code> with the specified
175 * source and ID which will execute the runnable's <code>run</code>
176 * method when dispatched. If notifier is non-<code>null</code>,
177 * <code>notifyAll</code> will be called on it
178 * immediately after <code>run</code> returns.
179 * <p>Note that passing in an invalid <code>id</code> results in
180 * unspecified behavior. This method throws an
181 * <code>IllegalArgumentException</code> if <code>source</code>
182 * is <code>null</code>.
183 *
184 * @param source the <code>Object</code> that originated
185 * the event
186 * @param id the ID for the event
187 * @param runnable the <code>Runnable</code> whose
188 * <code>run</code> method will be executed
189 * @param notifier the <code>Object</code> whose <code>notifyAll</code>
190 * method will be called after
191 * <code>Runnable.run</code> has returned
192 * @param catchThrowables specifies whether <code>dispatch</code>
193 * should catch Throwable when executing the
194 * <code>Runnable</code>'s <code>run</code>
195 * method, or should instead propagate those
196 * Throwables to the EventDispatchThread's
197 * dispatch loop
198 * @throws IllegalArgumentException if <code>source</code> is null
199 */
200 protected InvocationEvent(Object source, int id, Runnable runnable,
201 Object notifier, boolean catchThrowables) {
202 super(source, id);
203 this.runnable = runnable;
204 this.notifier = notifier;
205 this.catchExceptions = catchThrowables;
206 this.when = System.currentTimeMillis();
207 }
208
209 /**
210 * Executes the Runnable's <code>run()</code> method and notifies the
211 * notifier (if any) when <code>run()</code> returns.
212 */
213 public void dispatch() {
214 if (catchExceptions) {
215 try {
216 runnable.run();
217 }
218 catch (Throwable t) {
219 if (t instanceof Exception) {
220 exception = (Exception) t;
221 }
222 throwable = t;
223 }
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=" + notifier +
287 ",catchExceptions=" + catchExceptions + ",when=" + when;
288 }
289}