/** * Fetches and possibly removes the next event from the internal queues. This method returns * immediately. When all queues are empty, this returns <code>null</code>: * * @param remove <true> when the event should be removed from the queue, <code>false</code> * otherwise * @return the next event or <code>null</code> when all internal queues are empty */ private AWTEvent getNextEventImpl(boolean remove) { AWTEvent next = null; for (int i = 0; i < queues.length && next == null; i++) { Queue q = queues[i]; if (q.queueHead != null) { // Got an event, remove it. next = q.queueHead; if (remove) { // Unlink event from the queue. q.queueHead = next.queueNext; if (q.queueHead == null) q.queueTail = null; next.queueNext = null; } } } return next; }
/** * Actually performs the event posting. This is needed because the RI doesn't use the public * postEvent() method when transferring events between event queues in push() and pop(). * * @param evt the event to post * @param priority the priority of the event */ private final void postEventImpl(AWTEvent evt, int priority) { if (evt == null) throw new NullPointerException(); if (next != null) { next.postEvent(evt); return; } Object source = evt.getSource(); Queue q = queues[priority]; if (source instanceof Component) { // For PaintEvents, ask the ComponentPeer to coalesce the event // when the component is heavyweight. Component comp = (Component) source; ComponentPeer peer = comp.peer; if (peer != null && evt instanceof PaintEvent && !(peer instanceof LightweightPeer)) peer.coalescePaintEvent((PaintEvent) evt); // Check for any events already on the queue with the same source // and ID. AWTEvent previous = null; for (AWTEvent qevt = q.queueHead; qevt != null; qevt = qevt.queueNext) { Object src = qevt.getSource(); if (qevt.id == evt.id && src == comp) { // If there are, call coalesceEvents on the source component // to see if they can be combined. Component srccmp = (Component) src; AWTEvent coalescedEvt = srccmp.coalesceEvents(qevt, evt); if (coalescedEvt != null) { // Yes. Replace the existing event with the combined event. if (qevt != coalescedEvt) { if (previous != null) { assert previous.queueNext == qevt; previous.queueNext = coalescedEvt; } else { assert q.queueHead == qevt; q.queueHead = coalescedEvt; } coalescedEvt.queueNext = qevt.queueNext; if (q.queueTail == qevt) q.queueTail = coalescedEvt; qevt.queueNext = null; } return; } } previous = qevt; } } if (q.queueHead == null) { // We have an empty queue. Set this event both as head and as tail. q.queueHead = evt; q.queueTail = evt; } else { // Note: queueTail should not be null here. q.queueTail.queueNext = evt; q.queueTail = evt; } if (dispatchThread == null || !dispatchThread.isAlive()) { dispatchThread = new EventDispatchThread(this); dispatchThread.start(); } notify(); }