Source Code Cross Referenced for EventQueue.java in  » 6.0-JDK-Modules » j2me » java » awt » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » 6.0 JDK Modules » j2me » java.awt 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * @(#)EventQueue.java	1.19 06/10/10
003:         *
004:         * Copyright  1990-2006 Sun Microsystems, Inc. All Rights Reserved.
005:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
006:         * 
007:         * This program is free software; you can redistribute it and/or
008:         * modify it under the terms of the GNU General Public License version
009:         * 2 only, as published by the Free Software Foundation. 
010:         * 
011:         * This program is distributed in the hope that it will be useful, but
012:         * WITHOUT ANY WARRANTY; without even the implied warranty of
013:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014:         * General Public License version 2 for more details (a copy is
015:         * included at /legal/license.txt). 
016:         * 
017:         * You should have received a copy of the GNU General Public License
018:         * version 2 along with this work; if not, write to the Free Software
019:         * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020:         * 02110-1301 USA 
021:         * 
022:         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
023:         * Clara, CA 95054 or visit www.sun.com if you need additional
024:         * information or have any questions. 
025:         *
026:         */
027:
028:        package java.awt;
029:
030:        import java.awt.event.PaintEvent;
031:        import java.awt.event.InvocationEvent;
032:        import java.awt.event.KeyEvent;
033:        import java.awt.event.ActionEvent;
034:        import java.awt.event.FocusEvent;
035:        import java.awt.event.InputEvent;
036:        import java.awt.event.WindowEvent;
037:        import java.awt.ActiveEvent;
038:        import java.util.EmptyStackException;
039:        import java.lang.reflect.InvocationTargetException;
040:        import java.lang.ref.WeakReference;
041:
042:        import sun.awt.AppContext;
043:        import sun.awt.SunToolkit;
044:
045:        /*
046:         * Fix for 6370528 - EventQueue race condition or synchronization bug
047:         * Both the EventQueue class and EventQueueProxy class were used for
048:         * synchronization, which caused the race condition. Fixed by changing
049:         * all synchronization using the EventQueueProxy class, since that is
050:         * the class that contains the core logic of EventQueue after the
051:         * refactoring to fix 6261461
052:         */
053:
054:        /**
055:         * EventQueue is a platform-independent class that queues events, both
056:         * from the underlying peer classes and from trusted application classes.
057:         * There is only one EventQueue for each AppContext.
058:         *
059:         * @author Thomas Ball
060:         * @author Fred Ecks
061:         * @author David Mendenhall
062:         *
063:         * @version 	1.67, 02/11/00
064:         * @since 	1.1
065:         */
066:        public class EventQueue {
067:            // From Thread.java
068:            private static int threadInitNumber;
069:
070:            private static synchronized int nextThreadNum() {
071:                return threadInitNumber++;
072:            }
073:
074:            private static final int LOW_PRIORITY = 0;
075:            private static final int NORM_PRIORITY = 1;
076:            private static final int HIGH_PRIORITY = 2;
077:            static final int NUM_PRIORITIES = HIGH_PRIORITY + 1; // 6261461
078:
079:            /*
080:             * We maintain one Queue for each priority that the EventQueue supports.
081:             * That is, the EventQueue object is actually implemented as
082:             * NUM_PRIORITIES queues and all Events on a particular internal Queue
083:             * have identical priority. Events are pulled off the EventQueue starting
084:             * with the Queue of highest priority. We progress in decreasing order
085:             * across all Queues.
086:             */
087:            Queue[] queues = new Queue[NUM_PRIORITIES]; // 6261461
088:
089:            /*
090:             * The next EventQueue on the stack, or null if this EventQueue is
091:             * on the top of the stack.  If nextQueue is non-null, requests to post
092:             * an event are forwarded to nextQueue.
093:             */
094:            private EventQueue nextQueue;
095:            /*
096:             * The previous EventQueue on the stack, or null if this is the
097:             * "base" EventQueue.
098:             */
099:            private EventQueue previousQueue;
100:            private EventDispatchThread dispatchThread;
101:            /*
102:             * Debugging flag -- set true and recompile to enable checking.
103:             */
104:            private final static boolean debug = false;
105:
106:            private WeakReference currentEvent;
107:            private long mostRecentEventTime = System.currentTimeMillis();
108:
109:            private EventQueueProxy proxy = null; // 6261461
110:
111:            public EventQueue() {
112:                for (int i = 0; i < NUM_PRIORITIES; i++) {
113:                    queues[i] = new Queue();
114:                }
115:                String name = "AWT-EventQueue-" + nextThreadNum();
116:                dispatchThread = new EventDispatchThread(name,
117:                        this .proxy = new EventQueueProxy(this )); // 6261461
118:                dispatchThread.setPriority(Thread.NORM_PRIORITY + 1);
119:                dispatchThread.start();
120:            }
121:
122:            /**
123:             * Post a 1.1-style event to the EventQueue.  If there is an
124:             * existing event on the queue with the same ID and event source,
125:             * the source Component's coalesceEvents method will be called.
126:             *
127:             * @param theEvent an instance of java.awt.AWTEvent, or a
128:             * subclass of it.
129:             */
130:            public void postEvent(AWTEvent theEvent) {
131:                postEventPrivate(theEvent);
132:            }
133:
134:            /**
135:             * Post a 1.1-style event to the EventQueue.  If there is an
136:             * existing event on the queue with the same ID and event source,
137:             * the source Component's coalesceEvents method will be called.
138:             *
139:             * @param theEvent an instance of java.awt.AWTEvent, or a
140:             * subclass of it.
141:             */
142:            final void postEventPrivate(AWTEvent theEvent) {
143:                synchronized (this .proxy) { // 6261461
144:                    int id = theEvent.getID();
145:                    if (nextQueue != null) {
146:                        // Forward event to top of EventQueue stack.
147:                        nextQueue.postEventPrivate(theEvent);
148:                    } else if (id == PaintEvent.PAINT
149:                            || id == PaintEvent.UPDATE) {
150:                        postEvent(theEvent, LOW_PRIORITY);
151:                    } else {
152:                        postEvent(theEvent, NORM_PRIORITY);
153:                    }
154:                }
155:            }
156:
157:            /**
158:             * Posts the event to the internal Queue of specified priority,
159:             * coalescing as appropriate.
160:             */
161:            private void postEvent(AWTEvent theEvent, int priority) {
162:                EventQueueItem newItem = new EventQueueItem(theEvent);
163:                boolean notifyID = (theEvent.getID() == this .proxy.waitForID);//6261461
164:                if (queues[priority].head == null) {
165:                    boolean shouldNotify = noEvents();
166:                    queues[priority].head = queues[priority].tail = newItem;
167:                    // This component doesn't have any events of this type on the
168:                    // queue, so we have to initialize the RepaintArea with theEvent
169:                    if (theEvent.getID() == PaintEvent.PAINT
170:                            || theEvent.getID() == PaintEvent.UPDATE) {
171:                        Object source = theEvent.getSource();
172:                        ((Component) source).coalesceEvents(theEvent, theEvent);
173:                    }
174:                    if (shouldNotify) {
175:                        proxy.notifyAll(); // 6261461
176:                    }
177:                    if (notifyID) {
178:                        proxy.notifyAll(); // 6261461
179:                    }
180:                } else {
181:                    Object source = theEvent.getSource();
182:                    // For Component source events, traverse the entire list,
183:                    // trying to coalesce events
184:                    if (source instanceof  Component) {
185:                        EventQueueItem q = queues[priority].head;
186:                        for (;;) {
187:                            if (q.id == newItem.id
188:                                    && q.event.getSource() == source) {
189:                                AWTEvent coalescedEvent;
190:                                coalescedEvent = ((Component) source)
191:                                        .coalesceEvents(q.event, theEvent);
192:                                if (coalescedEvent != null) {
193:                                    q.event = coalescedEvent;
194:                                    return;
195:                                }
196:                            }
197:                            if (q.next != null) {
198:                                q = q.next;
199:                            } else {
200:                                break;
201:                            }
202:                        }
203:                    }
204:                    // The event was not coalesced or has non-Component source.
205:                    // Insert it at the end of the appropriate Queue.
206:                    if (theEvent.getID() == PaintEvent.PAINT
207:                            || theEvent.getID() == PaintEvent.UPDATE) {
208:                        // This component doesn't have any events of this type on the
209:                        // queue, so we have to initialize the RepaintArea with theEvent
210:                        ((Component) source).coalesceEvents(theEvent, theEvent);
211:                    }
212:                    queues[priority].tail.next = newItem;
213:                    queues[priority].tail = newItem;
214:                    if (notifyID) {
215:                        proxy.notifyAll(); // 6261461
216:                    }
217:                }
218:            }
219:
220:            /**
221:             * @return whether an event is pending on any of the separate Queues
222:             */
223:            private boolean noEvents() {
224:                for (int i = 0; i < NUM_PRIORITIES; i++) {
225:                    if (queues[i].head != null) {
226:                        return false;
227:                    }
228:                }
229:                return true;
230:            }
231:
232:            /**
233:             * Remove an event from the EventQueue and return it.  This method will
234:             * block until an event has been posted by another thread.
235:             * @return the next AWTEvent
236:             * @exception InterruptedException
237:             *            if another thread has interrupted this thread.
238:             */
239:            public AWTEvent getNextEvent() throws InterruptedException {
240:                return this .proxy.getNextEvent(); // 6261461
241:            }
242:
243:            /**
244:             * Return the first event on the EventQueue without removing it.
245:             * @return the first event
246:             */
247:            public AWTEvent peekEvent() {
248:                synchronized (this .proxy) { // 6370528
249:                    for (int i = NUM_PRIORITIES - 1; i >= 0; i--) {
250:                        if (queues[i].head != null) {
251:                            return queues[i].head.event;
252:                        }
253:                    }
254:                    return null;
255:                }
256:            }
257:
258:            /**
259:             * Return the first event with the specified id, if any.
260:             * @param id the id of the type of event desired.
261:             * @return the first event of the specified id
262:             */
263:            public AWTEvent peekEvent(int id) {
264:                synchronized (this .proxy) { // 6370528
265:                    for (int i = NUM_PRIORITIES - 1; i >= 0; i--) {
266:                        EventQueueItem q = queues[i].head;
267:                        for (; q != null; q = q.next) {
268:                            if (q.id == id) {
269:                                return q.event;
270:                            }
271:                        }
272:                    }
273:                    return null;
274:                }
275:            }
276:
277:            /**
278:             * Dispatch an event. The manner in which the event is
279:             * dispatched depends upon the type of the event and the
280:             * type of the event's source
281:             * object:
282:             * <p> </p>
283:             * <table border>
284:             * <tr>
285:             *     <th>Event Type</th>
286:             *     <th>Source Type</th>
287:             *     <th>Dispatched To</th>
288:             * </tr>
289:             * <tr>
290:             *     <td>ActiveEvent</td>
291:             *     <td>Any</td>
292:             *     <td>event.dispatch()</td>
293:             * </tr>
294:             * <tr>
295:             *     <td>Other</td>
296:             *     <td>Component</td>
297:             *     <td>source.dispatchEvent(AWTEvent)</td>
298:             * </tr>
299:             * <tr>
300:             *     <td>Other</td>
301:             *     <td>MenuComponent</td>
302:             *     <td>source.dispatchEvent(AWTEvent)</td>
303:             * </tr>
304:             * <tr>
305:             *     <td>Other</td>
306:             *     <td>Other</td>
307:             *     <td>No action (ignored)</td>
308:             * </tr>
309:             * </table>
310:             * <p> </p>
311:             * @param theEvent an instance of java.awt.AWTEvent, or a
312:             * subclass of it.
313:             */
314:            protected void dispatchEvent(AWTEvent event) {
315:                Object src = event.getSource();
316:                if (event instanceof  ActiveEvent) {
317:                    // This could become the sole method of dispatching in time.
318:                    ((ActiveEvent) event).dispatch();
319:                } else if (src instanceof  Component) {
320:                    ((Component) src).dispatchEvent(event);
321:                } else if (src instanceof  MenuComponent) {
322:                    ((MenuComponent) src).dispatchEvent(event);
323:                } else {
324:                    System.err.println("unable to dispatch event: " + event);
325:                }
326:            }
327:
328:            /**
329:             * Replace the existing EventQueue with the specified one.
330:             * Any pending events are transferred to the new EventQueue
331:             * for processing by it.
332:             *
333:             * @param an EventQueue (or subclass thereof) instance to be used.
334:             * @see      java.awt.EventQueue#pop
335:             */
336:            public void push(EventQueue newEventQueue) {
337:                synchronized (this .proxy) { // 6370528
338:                    if (debug) {
339:                        System.out.println("EventQueue.push(" + newEventQueue
340:                                + ")");
341:                    }
342:                    if (nextQueue != null) {
343:                        nextQueue.push(newEventQueue);
344:                        return;
345:                    }
346:                    synchronized (newEventQueue.proxy) { // 6370528
347:                        // Transfer all events forward to new EventQueue.
348:                        while (peekEvent() != null) {
349:                            try {
350:                                newEventQueue.postEventPrivate(getNextEvent());
351:                            } catch (InterruptedException ie) {
352:                                if (debug) {
353:                                    System.err.println("interrupted push:");
354:                                    ie.printStackTrace(System.err);
355:                                }
356:                            }
357:                        }
358:                        newEventQueue.previousQueue = this ;
359:                    }
360:                    nextQueue = newEventQueue;
361:
362:                    AppContext appContext = AppContext.getAppContext();
363:                    if (appContext.get(AppContext.EVENT_QUEUE_KEY) == this ) {
364:                        appContext.put(AppContext.EVENT_QUEUE_KEY,
365:                                newEventQueue);
366:                    }
367:                }
368:
369:            }
370:
371:            /**
372:             * Stop dispatching events using this EventQueue instance.
373:             * Any pending events are transferred to the previous
374:             * EventQueue for processing by it.
375:             *
376:             * @exception if no previous push was made on this EventQueue.
377:             * @see      java.awt.EventQueue#push
378:             */
379:            protected void pop() throws EmptyStackException {
380:                if (debug) {
381:                    System.out.println("EventQueue.pop(" + this  + ")");
382:                }
383:                // To prevent deadlock, we lock on the previous EventQueue before
384:                // this one.  This uses the same locking order as everything else
385:                // in EventQueue.java, so deadlock isn't possible.
386:                EventQueue prev = previousQueue;
387:                synchronized ((prev != null) ? prev.proxy : this .proxy) { // 6370528
388:                    synchronized (this .proxy) { // 6370528
389:                        if (nextQueue != null) {
390:                            nextQueue.pop();
391:                            return;
392:                        }
393:                        if (previousQueue == null) {
394:                            throw new EmptyStackException();
395:                        }
396:                        // Transfer all events back to previous EventQueue.
397:                        previousQueue.nextQueue = null;
398:                        while (peekEvent() != null) {
399:                            try {
400:                                previousQueue.postEventPrivate(getNextEvent());
401:                            } catch (InterruptedException ie) {
402:                                if (debug) {
403:                                    System.err.println("interrupted pop:");
404:                                    ie.printStackTrace(System.err);
405:                                }
406:                            }
407:                        }
408:
409:                        AppContext appContext = AppContext.getAppContext();
410:                        if (appContext.get(AppContext.EVENT_QUEUE_KEY) == this ) {
411:                            appContext.put(AppContext.EVENT_QUEUE_KEY,
412:                                    previousQueue);
413:                        }
414:                        previousQueue = null;
415:                    }
416:                }
417:                dispatchThread.stopDispatching(); // Must be done outside synchronized
418:                // block to avoid possible deadlock
419:            }
420:
421:            /**
422:             * Returns true if the calling thread is the current AWT EventQueue's
423:             * dispatch thread.  Use this call the ensure that a given
424:             * task is being executed (or not being) on the current AWT
425:             * EventDispatchThread.
426:             *
427:             * @return true if running on the current AWT EventQueue's dispatch thread.
428:             */
429:            public static boolean isDispatchThread() {
430:                EventQueue eq = Toolkit.getEventQueue();
431:                EventQueue next = eq.nextQueue;
432:                while (next != null) {
433:                    eq = next;
434:                    next = eq.nextQueue;
435:                }
436:                return (Thread.currentThread() == eq.dispatchThread);
437:            }
438:
439:            /*
440:             * Get the EventDispatchThread for this EventQueue.
441:             */
442:            final EventDispatchThread getDispatchThread() {
443:                return dispatchThread;
444:            }
445:
446:            /*
447:             * Change the target of any pending KeyEvents because of a focus change.
448:             */
449:            final void changeKeyEventFocus(Object newSource) {
450:                synchronized (this .proxy) { // 6370528
451:                    for (int i = 0; i < NUM_PRIORITIES; i++) {
452:                        EventQueueItem q = queues[i].head;
453:                        for (; q != null; q = q.next) {
454:                            if (q.event instanceof  KeyEvent) {
455:                                q.event.setSource(newSource);
456:                            }
457:                        }
458:                    }
459:                }
460:            }
461:
462:            /*
463:             * Remove any pending events for the specified source object.
464:             * This method is normally called by the source's removeNotify method.
465:             */
466:            final void removeSourceEvents(Object source) {
467:                synchronized (this .proxy) { // 6370528
468:                    for (int i = 0; i < NUM_PRIORITIES; i++) {
469:                        EventQueueItem entry = queues[i].head;
470:                        EventQueueItem prev = null;
471:                        while (entry != null) {
472:                            if (entry.event.getSource() == source) {
473:                                if (entry.event instanceof  SequencedEvent) {
474:                                    ((SequencedEvent) entry.event).dispose();
475:                                }
476:                                if (entry.event instanceof  SentEvent) {
477:                                    ((SentEvent) entry.event).dispose();
478:                                }
479:                                if (prev == null) {
480:                                    queues[i].head = entry.next;
481:                                } else {
482:                                    prev.next = entry.next;
483:                                }
484:                            } else {
485:                                prev = entry;
486:                            }
487:                            entry = entry.next;
488:                        }
489:                        queues[i].tail = prev;
490:                    }
491:                }
492:            }
493:
494:            /*
495:             * Remove any pending events for the specified source object.
496:             * This method is normally called by the source's removeNotify method.
497:             */
498:            final void removeEvents(Class type, int id) {
499:                synchronized (this .proxy) { // 6370528
500:                    for (int i = 0; i < NUM_PRIORITIES; i++) {
501:                        EventQueueItem entry = queues[i].head;
502:                        EventQueueItem prev = null;
503:                        while (entry != null) {
504:                            if (entry.event.getClass().equals(type)
505:                                    && entry.event.id == id) {
506:                                if (prev == null) {
507:                                    queues[i].head = entry.next;
508:                                } else {
509:                                    prev.next = entry.next;
510:                                }
511:                            } else {
512:                                prev = entry;
513:                            }
514:                            entry = entry.next;
515:                        }
516:                        queues[i].tail = prev;
517:                    }
518:                }
519:            }
520:
521:            /**
522:             * Causes <i>runnable</i> to have its run() method called in the dispatch
523:             * thread of the EventQueue.  This will happen after all pending events
524:             * are processed.
525:             *
526:             * @param runnable  the Runnable whose run() method should be executed
527:             *                  synchronously on the EventQueue
528:             * @see             #invokeAndWait
529:             * @since           1.2
530:             */
531:            public static void invokeLater(Runnable runnable) {
532:                Toolkit.getEventQueue().postEvent(
533:                        new InvocationEvent(Toolkit.getDefaultToolkit(),
534:                                runnable));
535:            }
536:
537:            /**
538:             * Causes <i>runnable</i> to have its run() method called in the dispatch
539:             * thread of the EventQueue.  This will happen after all pending events
540:             * are processed.  The call blocks until this has happened.  This method
541:             * will throw an Error if called from the event dispatcher thread.
542:             *
543:             * @param runnable  the Runnable whose run() method should be executed
544:             *                  synchronously on the EventQueue
545:             * @exception       InterruptedException  if another thread has
546:             *                  interrupted this thread
547:             * @exception       InvocationTargetException  if an exception is thrown
548:             *                  when running <i>runnable</i>
549:             * @see             #invokeLater
550:             * @since           1.2
551:             */
552:            public static void invokeAndWait(Runnable runnable)
553:                    throws InterruptedException, InvocationTargetException {
554:                if (EventQueue.isDispatchThread()) {
555:                    throw new Error(
556:                            "Cannot call invokeAndWait from the event dispatcher thread");
557:                }
558:                class AWTInvocationLock {
559:                }
560:                Object lock = new AWTInvocationLock();
561:                EventQueue queue = Toolkit.getEventQueue();
562:                InvocationEvent event = new InvocationEvent(Toolkit
563:                        .getDefaultToolkit(), runnable, lock, true);
564:                synchronized (lock) {
565:                    Toolkit.getEventQueue().postEvent(event);
566:                    lock.wait();
567:                }
568:                Exception eventException = event.getException();
569:                if (eventException != null) {
570:                    throw new InvocationTargetException(eventException);
571:                }
572:            }
573:
574:            static void setCurrentEventAndMostRecentTime(AWTEvent e) {
575:                Toolkit.getEventQueue().setCurrentEventAndMostRecentTimeImpl(e);
576:            }
577:
578:            private void setCurrentEventAndMostRecentTimeImpl(AWTEvent e) {
579:                synchronized (this .proxy) { // 6370528
580:                    if (Thread.currentThread() != dispatchThread) {
581:                        return;
582:                    }
583:
584:                    currentEvent = new WeakReference(e);
585:
586:                    // This series of 'instanceof' checks should be replaced with a
587:                    // polymorphic type (for example, an interface which declares a
588:                    // getWhen() method). However, this would require us to make such
589:                    // a type public, or to place it in sun.awt. Both of these approaches
590:                    // have been frowned upon.
591:
592:                    // In tiger, we will probably give timestamps to all events, so this
593:                    // will no longer be an issue.
594:                    if (e instanceof  InputEvent) {
595:                        InputEvent ie = (InputEvent) e;
596:                        mostRecentEventTime = ie.getWhen();
597:                    } else if (e instanceof  ActionEvent) {
598:                        ActionEvent ae = (ActionEvent) e;
599:                        mostRecentEventTime = ae.getWhen();
600:                    } else if (e instanceof  InvocationEvent) {
601:                        InvocationEvent ie = (InvocationEvent) e;
602:                        mostRecentEventTime = ie.getWhen();
603:                    }
604:                }
605:            }
606:
607:            final void removeSourceEvents(Object source, boolean removeAllEvents) {
608:                synchronized (this .proxy) { // 6370528
609:                    for (int i = 0; i < NUM_PRIORITIES; i++) {
610:                        EventQueueItem entry = queues[i].head;
611:                        EventQueueItem prev = null;
612:                        while (entry != null) {
613:                            if ((entry.event.getSource() == source)
614:                                    && (removeAllEvents || !(entry.event instanceof  SentEvent
615:                                            || entry.event instanceof  SequencedEvent
616:                                            || entry.event instanceof  FocusEvent
617:                                            || entry.event instanceof  WindowEvent || entry.event instanceof  KeyEvent))) {
618:                                if (entry.event instanceof  SequencedEvent) {
619:                                    ((SequencedEvent) entry.event).dispose();
620:                                }
621:                                if (entry.event instanceof  SentEvent) {
622:                                    ((SentEvent) entry.event).dispose();
623:                                }
624:                                if (prev == null) {
625:                                    queues[i].head = entry.next;
626:                                } else {
627:                                    prev.next = entry.next;
628:                                }
629:                            } else {
630:                                prev = entry;
631:                            }
632:                            entry = entry.next;
633:                        }
634:                        queues[i].tail = prev;
635:                    }
636:                }
637:            }
638:
639:            public static long getMostRecentEventTime() {
640:                return Toolkit.getEventQueue().getMostRecentEventTimeImpl();
641:            }
642:
643:            private long getMostRecentEventTimeImpl() {
644:                synchronized (this .proxy) { // 6370528
645:                    return (Thread.currentThread() == dispatchThread) ? mostRecentEventTime
646:                            : System.currentTimeMillis();
647:                }
648:            }
649:
650:            /**
651:             * Returns the the event currently being dispatched by the
652:             * <code>EventQueue</code> associated with the calling thread. This is
653:             * useful if a method needs access to the event, but was not designed to
654:             * receive a reference to it as an argument. Note that this method should
655:             * only be invoked from an application's event dispatching thread. If this
656:             * method is invoked from another thread, null will be returned.
657:             *
658:             * @return the event currently being dispatched, or null if this method is
659:             *         invoked on a thread other than an event dispatching thread
660:             * @since 1.4
661:             */
662:            public static AWTEvent getCurrentEvent() {
663:                return Toolkit.getEventQueue().getCurrentEventImpl();
664:            }
665:
666:            private AWTEvent getCurrentEventImpl() {
667:                synchronized (this .proxy) { // 6370528
668:
669:                    return (Thread.currentThread() == dispatchThread) ? ((AWTEvent) currentEvent
670:                            .get())
671:                            : null;
672:                }
673:            }
674:
675:            AWTEvent getNextEvent(int id) throws InterruptedException {
676:                return this .proxy.getNextEvent(id); // 6261461
677:            }
678:
679:            // 6261461
680:            // EffectiveJava Pattern : Finalizer Guardian Idiom.
681:            private final Object finalizerGuardian = new Object() {
682:                protected void finalize() throws Throwable {
683:                    try {
684:                        EventQueue.this .dispatchThread.stopDispatching();
685:                    } finally {
686:                        super .finalize();
687:                    }
688:                }
689:            };
690:            // 6261461
691:        }
692:
693:        /**
694:         * The Queue object holds pointers to the beginning and end of one internal
695:         * queue. An EventQueue object is composed of multiple internal Queues, one
696:         * for each priority supported by the EventQueue. All Events on a particular
697:         * internal Queue have identical priority.
698:         */
699:        class Queue {
700:            EventQueueItem head;
701:            EventQueueItem tail;
702:        }
703:
704:        class EventQueueItem {
705:            AWTEvent event;
706:            int id;
707:            EventQueueItem next;
708:
709:            EventQueueItem(AWTEvent evt) {
710:                event = evt;
711:                id = evt.getID();
712:            }
713:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.