/** * Copyright (c) 2002-2005, Simone Bordet * All rights reserved. * * This software is distributable under the BSD license. * See the terms of the BSD license in the documentation provided with this software. */ package foxtrot.pumps; import java.awt.AWTEvent; import java.awt.ActiveEvent; import java.awt.Component; import java.awt.EventQueue; import java.awt.MenuComponent; import java.awt.Toolkit; import java.lang.reflect.Method; import java.security.AccessController; import java.security.PrivilegedAction; import foxtrot.EventPump; import foxtrot.Task; /** * Implementation of an EventPump that should work with JDK 1.2 and 1.3 * and only uses the public API of the <code>java.awt.*</code> package. * @version $Revision: 1.1 $ */ public class QueueEventPump implements EventPump, EventFilterable { private static final boolean debug = false; private EventFilter filter; public void setEventFilter(EventFilter filter) { this.filter = filter; } public EventFilter getEventFilter() { return filter; } public void pumpEvents(Task task) { if (task == null) return; EventQueue queue = getEventQueue(); if (debug) System.out.println("[QueueEventPump] Start pumping events - Pump is " + this + " - Task is " + task); while (!task.isCompleted()) { try { AWTEvent event = queue.getNextEvent(); if (debug) System.out.println("[QueueEventPump] Next Event: " + event); if (filter != null && !filter.accept(event)) { if (debug) System.out.println("[QueueEventPump] Filtered out AWT Event: " + event + " by filter " + filter); continue; } try { dispatchEvent(queue, event); } catch (Throwable x) { handleThrowable(x); } } catch (InterruptedException x) { // AWT Thread has been interrupted, interrupt again to set again the interrupted flag Thread.currentThread().interrupt(); break; } } if (debug) System.out.println("[QueueEventPump] Stop pumping events - Pump is " + this + " - Task is " + task); } /** * Copy/Paste of the Sun's JDK 1.3 implementation in java.awt.EventQueue.dispatchEvent(AWTEvent) * @param queue The system EventQueue * @param event The event to dispatch */ private void dispatchEvent(EventQueue queue, AWTEvent event) { Object source = event.getSource(); if (event instanceof ActiveEvent) ((ActiveEvent)event).dispatch(); else if (source instanceof Component) ((Component)source).dispatchEvent(event); else if (source instanceof MenuComponent) ((MenuComponent)source).dispatchEvent(event); else System.err.println("[QueueEventPump] Unable to dispatch event " + event); } /** * Handle a RuntimeException or Error happened during event dispatching. * If the system property <code>sun.awt.exception.handler</code> is defined, * that handler will be used, otherwise it simply logs on <code>System.err</code>. */ private void handleThrowable(Throwable x) { String handlerName = (String)AccessController.doPrivileged(new PrivilegedAction() { public Object run() { return System.getProperty("sun.awt.exception.handler"); } }); if (handlerName != null) { try { Object handler = Thread.currentThread().getContextClassLoader().loadClass(handlerName).newInstance(); Method handle = handler.getClass().getMethod("handle", new Class[]{Throwable.class}); handle.invoke(handler, new Object[]{x}); return; } catch (Throwable ignored) { System.err.println("[QueueEventPump] Exception occurred while invoking AWT exception handler: " + ignored); // Fall through } } System.err.println("[QueueEventPump] Exception occurred during event dispatching:"); x.printStackTrace(); } private EventQueue getEventQueue() { return (EventQueue)AccessController.doPrivileged(new PrivilegedAction() { public Object run() { return Toolkit.getDefaultToolkit().getSystemEventQueue(); } }); } }