001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: /**
018: * @author Pavel Dolgov
019: * @version $Revision$
020: */package java.awt;
021:
022: import java.awt.event.ActionEvent;
023: import java.awt.event.InputEvent;
024: import java.awt.event.InputMethodEvent;
025: import java.awt.event.InvocationEvent;
026: import java.awt.event.MouseEvent;
027: import java.util.LinkedList;
028:
029: import org.apache.harmony.awt.internal.nls.Messages;
030:
031: /**
032: * The events storage for EventQueue
033: */
034: final class EventQueueCore {
035:
036: private final LinkedList<EventQueue> queueStack = new LinkedList<EventQueue>();
037: private final LinkedList<AWTEvent> events = new LinkedList<AWTEvent>();
038:
039: private Toolkit toolkit;
040: private EventQueue activeQueue;
041: private Thread dispatchThread;
042:
043: AWTEvent currentEvent;
044: long mostRecentEventTime = System.currentTimeMillis();
045:
046: EventQueueCore(EventQueue eq) {
047: synchronized (this ) {
048: queueStack.addLast(eq);
049: activeQueue = eq;
050: }
051: }
052:
053: EventQueueCore(EventQueue eq, Toolkit t) {
054: synchronized (this ) {
055: queueStack.addLast(eq);
056: activeQueue = eq;
057: setToolkit(t);
058: }
059: }
060:
061: synchronized long getMostRecentEventTime() {
062: return mostRecentEventTime;
063: }
064:
065: synchronized AWTEvent getCurrentEvent() {
066: return currentEvent;
067: }
068:
069: synchronized boolean isSystemEventQueue() {
070: return toolkit != null;
071: }
072:
073: private void setToolkit(Toolkit t) {
074: toolkit = t;
075: if (toolkit != null) {
076: toolkit.setSystemEventQueueCore(this );
077: dispatchThread = toolkit.dispatchThread;
078: }
079: }
080:
081: synchronized void postEvent(AWTEvent event) {
082: events.addLast(event);
083: if ((toolkit == null) && (dispatchThread == null)) {
084: dispatchThread = new EventQueueThread(this );
085: dispatchThread.start();
086: }
087: // TODO: add event coalescing
088: if (toolkit != null) {
089: toolkit.shutdownWatchdog.setAwtQueueEmpty(false);
090: notifyEventMonitor(toolkit);
091: }
092: notifyAll();
093: }
094:
095: void notifyEventMonitor(Toolkit t) {
096: Object em = t.getEventMonitor();
097: synchronized (em) {
098: em.notifyAll();
099: }
100: }
101:
102: synchronized AWTEvent getNextEvent() throws InterruptedException {
103: while (events.isEmpty()) {
104: wait();
105: }
106: AWTEvent event = events.removeFirst();
107: // TODO: add event coalescing
108: return event;
109: }
110:
111: synchronized AWTEvent peekEvent() {
112: return events.isEmpty() ? null : events.getFirst();
113: }
114:
115: synchronized AWTEvent peekEvent(int id) {
116: for (AWTEvent event : events) {
117: if (event.getID() == id) {
118: return event;
119: }
120: }
121: return null;
122: }
123:
124: synchronized void dispatchEvent(AWTEvent event) {
125: updateCurrentEventAndTime(event);
126: try {
127: activeQueue.dispatchEvent(event);
128: } finally {
129: currentEvent = null;
130: }
131: }
132:
133: void dispatchEventImpl(AWTEvent event) {
134: if (event instanceof ActiveEvent) {
135: updateCurrentEventAndTime(event);
136: try {
137: ((ActiveEvent) event).dispatch();
138: } finally {
139: currentEvent = null;
140: }
141: return;
142: }
143:
144: Object src = event.getSource();
145:
146: if (src instanceof Component) {
147: if (preprocessComponentEvent(event)) {
148: ((Component) src).dispatchEvent(event);
149: }
150: } else {
151: if (toolkit != null) {
152: toolkit.dispatchAWTEvent(event);
153: }
154: if (src instanceof MenuComponent) {
155: ((MenuComponent) src).dispatchEvent(event);
156: }
157: }
158: }
159:
160: private final boolean preprocessComponentEvent(AWTEvent event) {
161: if (event instanceof MouseEvent) {
162: return preprocessMouseEvent((MouseEvent) event);
163: }
164: return true;
165: }
166:
167: private final boolean preprocessMouseEvent(MouseEvent event) {
168: if (toolkit != null && toolkit.mouseEventPreprocessor != null) {
169: toolkit.lockAWT();
170: try {
171: return toolkit.mouseEventPreprocessor.preprocess(event);
172: } finally {
173: toolkit.unlockAWT();
174: }
175: }
176: return true;
177: }
178:
179: private void updateCurrentEventAndTime(AWTEvent event) {
180: currentEvent = event;
181: long when = 0;
182: if (event instanceof ActionEvent) {
183: when = ((ActionEvent) event).getWhen();
184: } else if (event instanceof InputEvent) {
185: when = ((InputEvent) event).getWhen();
186: } else if (event instanceof InputMethodEvent) {
187: when = ((InputMethodEvent) event).getWhen();
188: } else if (event instanceof InvocationEvent) {
189: when = ((InvocationEvent) event).getWhen();
190: }
191: if (when != 0) {
192: mostRecentEventTime = when;
193: }
194: }
195:
196: synchronized void push(EventQueue newEventQueue) {
197: // TODO: handle incorrect situations
198: if (queueStack.isEmpty()) {
199: // awt.6B=Queue stack is empty
200: throw new IllegalStateException(Messages
201: .getString("awt.6B")); //$NON-NLS-1$
202: }
203:
204: queueStack.addLast(newEventQueue);
205: activeQueue = newEventQueue;
206: activeQueue.setCore(this );
207: }
208:
209: synchronized void pop() {
210: EventQueue removed = queueStack.removeLast();
211: if (removed != activeQueue) {
212: // awt.6C=Event queue stack is broken
213: throw new IllegalStateException(Messages
214: .getString("awt.6C")); //$NON-NLS-1$
215: }
216: activeQueue = queueStack.getLast();
217: removed.setCore(null);
218: }
219:
220: synchronized AWTEvent getNextEventNoWait() {
221: try {
222: return events.isEmpty() ? null : activeQueue.getNextEvent();
223: } catch (InterruptedException e) {
224: return null;
225: }
226: }
227:
228: synchronized boolean isEmpty() {
229: return (currentEvent == null) && events.isEmpty();
230: }
231:
232: synchronized boolean isEmpty(long timeout) {
233: if (!isEmpty()) {
234: return false;
235: }
236: try {
237: wait(timeout);
238: } catch (InterruptedException e) {
239: }
240: return isEmpty();
241: }
242:
243: synchronized EventQueue getActiveEventQueue() {
244: return activeQueue;
245: }
246: }
|