1/* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17/** 18 * @author Michael Danilov, Pavel Dolgov 19 * @version $Revision$ 20 */ 21package java.awt; 22 23import org.apache.harmony.awt.wtk.NativeEvent; 24import org.apache.harmony.awt.wtk.NativeEventQueue; 25 26class EventDispatchThread extends Thread { 27 28 private static final class MarkerEvent extends AWTEvent { 29 MarkerEvent(Object source, int id) { 30 super(source, id); 31 } 32 } 33 34 final Dispatcher dispatcher; 35 final Toolkit toolkit; 36 private NativeEventQueue nativeQueue; 37 38 protected volatile boolean shutdownPending = false; 39 40 /** 41 * Initialise and run the main event loop 42 */ 43 @Override 44 public void run() { 45 nativeQueue = toolkit.getNativeEventQueue(); 46 47 try { 48 runModalLoop(null); 49 } finally { 50 toolkit.shutdownWatchdog.forceShutdown(); 51 } 52 } 53 54 void runModalLoop(ModalContext context) { 55 long lastPaintTime = System.currentTimeMillis(); 56 while (!shutdownPending && (context == null || context.isModalLoopRunning())) { 57 try { 58 EventQueue eventQueue = toolkit.getSystemEventQueueImpl(); 59 60 NativeEvent ne = nativeQueue.getNextEvent(); 61 if (ne != null) { 62 dispatcher.onEvent(ne); 63 MarkerEvent marker = new MarkerEvent(this, 0); 64 eventQueue.postEvent(marker); 65 for (AWTEvent ae = eventQueue.getNextEventNoWait(); 66 (ae != null) && (ae != marker); 67 ae = eventQueue.getNextEventNoWait()) { 68 eventQueue.dispatchEvent(ae); 69 } 70 } else { 71 toolkit.shutdownWatchdog.setNativeQueueEmpty(true); 72 AWTEvent ae = eventQueue.getNextEventNoWait(); 73 if (ae != null) { 74 eventQueue.dispatchEvent(ae); 75 long curTime = System.currentTimeMillis(); 76 if (curTime - lastPaintTime > 10) { 77 toolkit.onQueueEmpty(); 78 lastPaintTime = System.currentTimeMillis(); 79 } 80 } else { 81 toolkit.shutdownWatchdog.setAwtQueueEmpty(true); 82 toolkit.onQueueEmpty(); 83 lastPaintTime = System.currentTimeMillis(); 84 waitForAnyEvent(); 85 } 86 } 87 } catch (Throwable t) { 88 // TODO: Exception handler should be implemented 89 // t.printStackTrace(); 90 } 91 } 92 } 93 94 private void waitForAnyEvent() { 95 EventQueue eventQueue = toolkit.getSystemEventQueueImpl(); 96 if (!eventQueue.isEmpty() || !nativeQueue.isEmpty()) { 97 return; 98 } 99 Object eventMonitor = nativeQueue.getEventMonitor(); 100 synchronized(eventMonitor) { 101 try { 102 eventMonitor.wait(); 103 } catch (InterruptedException e) {} 104 } 105 } 106 107 void shutdown() { 108 shutdownPending = true; 109 } 110 111 EventDispatchThread(Toolkit toolkit, Dispatcher dispatcher ) { 112 this.toolkit = toolkit; 113 this.dispatcher = dispatcher; 114 setName("AWT-EventDispatchThread"); //$NON-NLS-1$ 115 setDaemon(true); 116 } 117 118} 119