1 7 8 package java.awt; 9 10 import java.awt.event.ActionEvent ; 11 import java.awt.event.FocusEvent ; 12 import java.awt.event.InputEvent ; 13 import java.awt.event.InputMethodEvent ; 14 import java.awt.event.InvocationEvent ; 15 import java.awt.event.KeyEvent ; 16 import java.awt.event.MouseEvent ; 17 import java.awt.event.PaintEvent ; 18 import java.awt.event.WindowEvent ; 19 import java.awt.ActiveEvent ; 20 import java.awt.peer.ComponentPeer; 21 import java.awt.peer.LightweightPeer; 22 import java.util.EmptyStackException ; 23 import java.lang.ref.WeakReference ; 24 import java.lang.reflect.InvocationTargetException ; 25 import java.security.AccessController ; 26 import java.security.PrivilegedAction ; 27 import sun.awt.PeerEvent; 28 import sun.awt.SunToolkit; 29 import sun.awt.DebugHelper; 30 import sun.awt.AWTAutoShutdown; 31 import sun.awt.AppContext; 32 33 79 public class EventQueue { 80 private static final DebugHelper dbg = DebugHelper.create(EventQueue .class); 81 82 private static int threadInitNumber; 84 private static synchronized int nextThreadNum() { 85 return threadInitNumber++; 86 } 87 88 private static final int LOW_PRIORITY = 0; 89 private static final int NORM_PRIORITY = 1; 90 private static final int HIGH_PRIORITY = 2; 91 private static final int ULTIMATE_PRIORITY = 3; 92 93 private static final int NUM_PRIORITIES = ULTIMATE_PRIORITY + 1; 94 95 103 private Queue[] queues = new Queue[NUM_PRIORITIES]; 104 105 110 private EventQueue nextQueue; 111 112 116 private EventQueue previousQueue; 117 118 private EventDispatchThread dispatchThread; 119 120 private final ThreadGroup threadGroup = 121 Thread.currentThread().getThreadGroup(); 122 private final ClassLoader classLoader = 123 Thread.currentThread().getContextClassLoader(); 124 125 128 private final static boolean debug = false; 129 130 133 private long mostRecentEventTime = System.currentTimeMillis(); 134 135 139 private WeakReference currentEvent; 140 141 145 private int waitForID; 146 147 private final String name = "AWT-EventQueue-" + nextThreadNum(); 148 149 public EventQueue() { 150 for (int i = 0; i < NUM_PRIORITIES; i++) { 151 queues[i] = new Queue(); 152 } 153 161 } 162 163 173 public void postEvent(AWTEvent theEvent) { 174 SunToolkit.flushPendingEvents(); 175 postEventPrivate(theEvent); 176 } 177 178 187 final void postEventPrivate(AWTEvent theEvent) { 188 theEvent.isPosted = true; 189 synchronized(this) { 190 int id = theEvent.getID(); 191 if (nextQueue != null) { 192 nextQueue.postEventPrivate(theEvent); 194 } else if (theEvent instanceof PeerEvent && 195 (((PeerEvent)theEvent).getFlags() & 196 PeerEvent.ULTIMATE_PRIORITY_EVENT) != 0) { 197 postEvent(theEvent, ULTIMATE_PRIORITY); 198 } else if (theEvent instanceof PeerEvent && 199 (((PeerEvent)theEvent).getFlags() & 200 PeerEvent.PRIORITY_EVENT) != 0) { 201 postEvent(theEvent, HIGH_PRIORITY); 202 } else if (id == PaintEvent.PAINT || 203 id == PaintEvent.UPDATE) { 204 postEvent(theEvent, LOW_PRIORITY); 205 } else { 206 postEvent(theEvent, NORM_PRIORITY); 207 } 208 } 209 } 210 211 219 private void postEvent(AWTEvent theEvent, int priority) { 220 221 if (dispatchThread == null) { 222 if (theEvent.getSource() == AWTAutoShutdown.getInstance()) { 223 return; 224 } else { 225 initDispatchThread(); 226 } 227 } 228 229 Object source = theEvent.getSource(); 230 231 if (source instanceof Component ) { 233 ComponentPeer sourcePeer = ((Component )source).peer; 234 if (sourcePeer != null && theEvent instanceof PaintEvent && 235 !(sourcePeer instanceof LightweightPeer)) { 236 sourcePeer.coalescePaintEvent((PaintEvent )theEvent); 237 } 238 } 239 240 EventQueueItem newItem = new EventQueueItem(theEvent); 241 242 boolean notifyID = (theEvent.getID() == this.waitForID); 243 244 if (queues[priority].head == null) { 245 boolean shouldNotify = noEvents(); 246 queues[priority].head = queues[priority].tail = newItem; 247 248 if (shouldNotify) { 249 if (theEvent.getSource() != AWTAutoShutdown.getInstance()) { 250 AWTAutoShutdown.getInstance().notifyThreadBusy(dispatchThread); 251 } 252 notifyAll(); 253 } else if (notifyID) { 254 notifyAll(); 255 } 256 } else { 257 boolean isPeerEvent = theEvent instanceof PeerEvent; 258 259 if (source instanceof Component ) { 262 EventQueueItem q = queues[priority].head; 263 264 if (theEvent.id == Event.MOUSE_MOVE || 265 theEvent.id == Event.MOUSE_DRAG) { 266 EventQueueItem qm; 267 for(qm = q; qm != null; qm = qm.next) { 268 if ((qm.event instanceof MouseEvent ) && 269 qm.id != theEvent.id) { 270 q = qm; 271 } 272 } 273 } 274 275 for (; q != null; q = q.next) { 276 if (q.event.getSource() == source && q.id == newItem.id) { 278 AWTEvent coalescedEvent = ((Component )source).coalesceEvents(q.event, theEvent); 279 if (isPeerEvent && coalescedEvent == null && q.event instanceof PeerEvent) { 280 coalescedEvent = ((PeerEvent)q.event).coalesceEvents((PeerEvent)theEvent); 281 } 282 if (coalescedEvent != null) { 283 q.event = coalescedEvent; 287 return; 288 } 289 } 290 } 291 } 292 queues[priority].tail.next = newItem; 295 queues[priority].tail = newItem; 296 if (notifyID) { 297 notifyAll(); 298 } 299 } 300 } 301 302 307 private boolean noEvents() { 308 for (int i = 0; i < NUM_PRIORITIES; i++) { 309 if (queues[i].head != null) { 310 return false; 311 } 312 } 313 314 return true; 315 } 316 317 325 public AWTEvent getNextEvent() throws InterruptedException { 326 do { 327 332 SunToolkit.flushPendingEvents(); 333 synchronized (this) { 334 for (int i = NUM_PRIORITIES - 1; i >= 0; i--) { 335 if (queues[i].head != null) { 336 EventQueueItem eqi = queues[i].head; 337 queues[i].head = eqi.next; 338 if (eqi.next == null) { 339 queues[i].tail = null; 340 } 341 return eqi.event; 342 } 343 } 344 AWTAutoShutdown.getInstance().notifyThreadFree(dispatchThread); 345 wait(); 346 } 347 } while(true); 348 } 349 350 AWTEvent getNextEvent(int id) throws InterruptedException { 351 do { 352 357 SunToolkit.flushPendingEvents(); 358 synchronized (this) { 359 for (int i = 0; i < NUM_PRIORITIES; i++) { 360 for (EventQueueItem entry = queues[i].head, prev = null; 361 entry != null; prev = entry, entry = entry.next) 362 { 363 if (entry.id == id) { 364 if (prev == null) { 365 queues[i].head = entry.next; 366 } else { 367 prev.next = entry.next; 368 } 369 if (queues[i].tail == entry) { 370 queues[i].tail = prev; 371 } 372 return entry.event; 373 } 374 } 375 } 376 this.waitForID = id; 377 wait(); 378 this.waitForID = 0; 379 } 380 } while(true); 381 } 382 383 388 public synchronized AWTEvent peekEvent() { 389 for (int i = NUM_PRIORITIES - 1; i >= 0; i--) { 390 if (queues[i].head != null) { 391 return queues[i].head.event; 392 } 393 } 394 395 return null; 396 } 397 398 404 public synchronized AWTEvent peekEvent(int id) { 405 for (int i = NUM_PRIORITIES - 1; i >= 0; i--) { 406 EventQueueItem q = queues[i].head; 407 for (; q != null; q = q.next) { 408 if (q.id == id) { 409 return q.event; 410 } 411 } 412 } 413 414 return null; 415 } 416 417 454 protected void dispatchEvent(AWTEvent event) { 455 event.isPosted = true; 456 Object src = event.getSource(); 457 if (event instanceof ActiveEvent ) { 458 setCurrentEventAndMostRecentTimeImpl(event); 460 461 ((ActiveEvent )event).dispatch(); 462 } else if (src instanceof Component ) { 463 ((Component )src).dispatchEvent(event); 464 event.dispatched(); 465 } else if (src instanceof MenuComponent ) { 466 ((MenuComponent )src).dispatchEvent(event); 467 } else if (src instanceof AWTAutoShutdown) { 468 if (noEvents()) { 469 dispatchThread.stopDispatching(); 470 } 471 } else { 472 System.err.println("unable to dispatch event: " + event); 473 } 474 } 475 476 502 public static long getMostRecentEventTime() { 503 return Toolkit.getEventQueue().getMostRecentEventTimeImpl(); 504 } 505 private synchronized long getMostRecentEventTimeImpl() { 506 return (Thread.currentThread() == dispatchThread) 507 ? mostRecentEventTime 508 : System.currentTimeMillis(); 509 } 510 511 514 synchronized long getMostRecentEventTimeEx() { 515 return mostRecentEventTime; 516 } 517 518 530 public static AWTEvent getCurrentEvent() { 531 return Toolkit.getEventQueue().getCurrentEventImpl(); 532 } 533 private synchronized AWTEvent getCurrentEventImpl() { 534 return (Thread.currentThread() == dispatchThread) 535 ? ((AWTEvent )currentEvent.get()) 536 : null; 537 } 538 539 549 public synchronized void push(EventQueue newEventQueue) { 550 if (debug) { 551 System.out.println("EventQueue.push(" + newEventQueue + ")"); 552 } 553 554 if (nextQueue != null) { 555 nextQueue.push(newEventQueue); 556 return; 557 } 558 559 synchronized (newEventQueue) { 560 while (peekEvent() != null) { 562 try { 563 newEventQueue.postEventPrivate(getNextEvent()); 564 } catch (InterruptedException ie) { 565 if (debug) { 566 System.err.println("interrupted push:"); 567 ie.printStackTrace(System.err); 568 } 569 } 570 } 571 572 newEventQueue.previousQueue = this; 573 } 574 584 if (dispatchThread != null) { 585 dispatchThread.stopDispatchingLater(); 586 } 587 588 nextQueue = newEventQueue; 589 590 AppContext appContext = AppContext.getAppContext(); 591 if (appContext.get(AppContext.EVENT_QUEUE_KEY) == this) { 592 appContext.put(AppContext.EVENT_QUEUE_KEY, newEventQueue); 593 } 594 } 595 596 608 protected void pop() throws EmptyStackException { 609 if (debug) { 610 System.out.println("EventQueue.pop(" + this + ")"); 611 } 612 613 EventQueue prev = previousQueue; 617 synchronized ((prev != null) ? prev : this) { 618 synchronized(this) { 619 if (nextQueue != null) { 620 nextQueue.pop(); 621 return; 622 } 623 if (previousQueue == null) { 624 throw new EmptyStackException (); 625 } 626 627 previousQueue.nextQueue = null; 629 while (peekEvent() != null) { 630 try { 631 previousQueue.postEventPrivate(getNextEvent()); 632 } catch (InterruptedException ie) { 633 if (debug) { 634 System.err.println("interrupted pop:"); 635 ie.printStackTrace(System.err); 636 } 637 } 638 } 639 AppContext appContext = AppContext.getAppContext(); 640 if (appContext.get(AppContext.EVENT_QUEUE_KEY) == this) { 641 appContext.put(AppContext.EVENT_QUEUE_KEY, previousQueue); 642 } 643 644 previousQueue = null; 645 } 646 } 647 648 EventDispatchThread dt = this.dispatchThread; 649 if (dt != null) { 650 dt.stopDispatching(); } 653 } 654 655 665 public static boolean isDispatchThread() { 666 EventQueue eq = Toolkit.getEventQueue(); 667 EventQueue next = eq.nextQueue; 668 while (next != null) { 669 eq = next; 670 next = eq.nextQueue; 671 } 672 return (Thread.currentThread() == eq.dispatchThread); 673 } 674 675 final void initDispatchThread() { 676 synchronized (this) { 677 if (dispatchThread == null && !threadGroup.isDestroyed()) { 678 dispatchThread = (EventDispatchThread ) 679 AccessController.doPrivileged(new PrivilegedAction () { 680 public Object run() { 681 EventDispatchThread t = 682 new EventDispatchThread (threadGroup, 683 name, 684 EventQueue.this); 685 t.setContextClassLoader(classLoader); 686 t.setPriority(Thread.NORM_PRIORITY + 1); 687 t.setDaemon(false); 688 return t; 689 } 690 }); 691 AWTAutoShutdown.getInstance().notifyThreadBusy(dispatchThread); 692 dispatchThread.start(); 693 } 694 } 695 } 696 697 final void detachDispatchThread() { 698 dispatchThread = null; 699 } 700 701 710 final EventDispatchThread getDispatchThread() { 711 return dispatchThread; 712 } 713 714 726 final void removeSourceEvents(Object source, boolean removeAllEvents) { 727 SunToolkit.flushPendingEvents(); 728 synchronized (this) { 729 for (int i = 0; i < NUM_PRIORITIES; i++) { 730 EventQueueItem entry = queues[i].head; 731 EventQueueItem prev = null; 732 while (entry != null) { 733 if ((entry.event.getSource() == source) 734 && (removeAllEvents 735 || ! (entry.event instanceof SequencedEvent 736 || entry.event instanceof SentEvent 737 || entry.event instanceof FocusEvent 738 || entry.event instanceof WindowEvent 739 || entry.event instanceof KeyEvent 740 || entry.event instanceof InputMethodEvent ))) 741 { 742 if (entry.event instanceof SequencedEvent ) { 743 ((SequencedEvent )entry.event).dispose(); 744 } 745 if (entry.event instanceof SentEvent ) { 746 ((SentEvent )entry.event).dispose(); 747 } 748 if (prev == null) { 749 queues[i].head = entry.next; 750 } else { 751 prev.next = entry.next; 752 } 753 } else { 754 prev = entry; 755 } 756 entry = entry.next; 757 } 758 queues[i].tail = prev; 759 } 760 } 761 } 762 763 static void setCurrentEventAndMostRecentTime(AWTEvent e) { 764 Toolkit.getEventQueue().setCurrentEventAndMostRecentTimeImpl(e); 765 } 766 private synchronized void setCurrentEventAndMostRecentTimeImpl(AWTEvent e) 767 { 768 if (Thread.currentThread() != dispatchThread) { 769 return; 770 } 771 772 currentEvent = new WeakReference (e); 773 774 long mostRecentEventTime2 = Long.MIN_VALUE; 783 if (e instanceof InputEvent ) { 784 InputEvent ie = (InputEvent )e; 785 mostRecentEventTime2 = ie.getWhen(); 786 } else if (e instanceof InputMethodEvent ) { 787 InputMethodEvent ime = (InputMethodEvent )e; 788 mostRecentEventTime2 = ime.getWhen(); 789 } else if (e instanceof ActionEvent ) { 790 ActionEvent ae = (ActionEvent )e; 791 mostRecentEventTime2 = ae.getWhen(); 792 } else if (e instanceof InvocationEvent ) { 793 InvocationEvent ie = (InvocationEvent )e; 794 mostRecentEventTime2 = ie.getWhen(); 795 } 796 mostRecentEventTime = Math.max(mostRecentEventTime, mostRecentEventTime2); 797 } 798 799 810 public static void invokeLater(Runnable runnable) { 811 Toolkit.getEventQueue().postEvent( 812 new InvocationEvent (Toolkit.getDefaultToolkit(), runnable)); 813 } 814 815 832 public static void invokeAndWait(Runnable runnable) 833 throws InterruptedException , InvocationTargetException { 834 835 if (EventQueue.isDispatchThread()) { 836 throw new Error ("Cannot call invokeAndWait from the event dispatcher thread"); 837 } 838 839 class AWTInvocationLock {} 840 Object lock = new AWTInvocationLock(); 841 842 InvocationEvent event = 843 new InvocationEvent (Toolkit.getDefaultToolkit(), runnable, lock, 844 true); 845 846 synchronized (lock) { 847 Toolkit.getEventQueue().postEvent(event); 848 lock.wait(); 849 } 850 851 Throwable eventThrowable = event.getThrowable(); 852 if (eventThrowable != null) { 853 throw new InvocationTargetException (eventThrowable); 854 } 855 } 856 857 863 private void wakeup(boolean isShutdown) { 864 synchronized(this) { 865 if (nextQueue != null) { 866 nextQueue.wakeup(isShutdown); 868 } else if (dispatchThread != null) { 869 notifyAll(); 870 } else if (!isShutdown) { 871 initDispatchThread(); 872 } 873 } 874 } 875 } 876 877 883 class Queue { 884 EventQueueItem head; 885 EventQueueItem tail; 886 } 887 888 class EventQueueItem { 889 AWTEvent event; 890 int id; 891 EventQueueItem next; 892 893 EventQueueItem(AWTEvent evt) { 894 event = evt; 895 id = evt.getID(); 896 } 897 } 898 | Popular Tags |