FileDocCategorySizeDatePackage
SystemEventQueueUtilities.javaAPI DocJava SE 5 API25114Fri Aug 26 14:57:58 BST 2005javax.swing

SystemEventQueueUtilities

public class SystemEventQueueUtilities extends Object
Swing internal utilities for dealing with the AWT system event queue. Four methods are exported, see the individual method javadoc for more information: addRunnableCanvas(), removeRunnableCanvas(), postRunnable(), queueComponentWorkRequest(). Note: most of the code in this class is no longer needed since we're no longer supporting Swing in 1.1.x VM's and in 1.2 we're guaranteed access to the AWT event queue. However all of the entry points, save postRunnable(), are still used.
see
RepaintManager
see
JRootPane

Fields Summary
private static final Object
classLock
private static final Object
rootTableKey
Constructors Summary
Methods Summary
static voidaddRunnableCanvas(javax.swing.JRootPane rootPane)
Associate a RunnableCanvas and a JRootPane to enable queuing events for the root pane's parent window's event dispatching thread. Adds a 1x1 RunnableCanvas to the root pane's layered pane.

Called by JRootPane.addNotify() to set up the RunnableCanvas.

see
RunnableCanvas
see
JRootPane#addNotify

	synchronized (classLock) {
	    /* If we have access to the system event queue, we don't bother
	     * with a RunnableCanvas
	     */
	    if (SystemEventQueue.get(rootPane) != null) {
		return;
	    }

	    JLayeredPane layeredPane = rootPane.getLayeredPane();
	    if (layeredPane != null) {
		RunnableCanvas rc = new RunnableCanvas(rootPane);
		layeredPane.add(rc);
	    }
	}
    
private static java.util.MapgetRootTable()


        
	Map rt = (Map)AppContext.getAppContext().get(rootTableKey);
	if (rt == null) {
	    synchronized (rootTableKey) {
		rt = (Map)AppContext.getAppContext().get(rootTableKey);
		if (rt == null) {
		    rt = Collections.synchronizedMap(new WeakHashMap(4));
		    AppContext.getAppContext().put(rootTableKey, rt);
		}
	    }
	}
	return rt;
    
private static java.lang.ThreadGroupgetThreadGroupSafely()
Return the current threads ThreadGroup, even on IE4.0. IE4.0 throws a SecurityException if you apply getThreadGroup() to the event dispatching thread. However a child of the event dispatching thread (same thread group) is OK.

	return new Thread().getThreadGroup();
    
static java.lang.ExceptionpostRunnable(java.lang.Runnable doRun, java.lang.Object lock)
Post an event to the AWT System event queue that, when dispatched, will invoke the specified Runnable. If lock is non-null this call blocks (by waiting on the lock) until the doRun() method returns, otherwise we return as soon as the event has been enqueued. An exception is only returned if lock is non-null, i.e. if we're being called from invokeAndWait().

This method is only intended to support SwingUtilities.invokeLater() and SwingUtilities.invokeAndWait().

	EventQueue systemEventQueue = SystemEventQueue.get();

	RunnableEvent event = new RunnableEvent(doRun, lock);
	if (systemEventQueue != null) {
	    systemEventQueue.postEvent(event);
	}
	else {
	    postRunnableCanvasEvent(event);
	}
	return event.exception;
    
private static voidpostRunnableCanvasEvent(javax.swing.SystemEventQueueUtilities$RunnableEvent e)
Synchronized entry point to the applet support for AWT System event queue access. This method adds the event to the appropriate runnable canvas's queue and then has the canvas repaint(). Note that by the time the event dispatching thread gets to handling the repaint() (by calling runnableCanvas.update()), many runnable events may have been queued up.

see
RunnableCanvas#addRunnableEvent
see
RunnableCanvas#update

	synchronized (classLock) {
	    RunnableCanvas runnableCanvas = RunnableCanvas.lookup(e);

	    if (runnableCanvas == null) {

		/* If this is a ComponentWorkRequest and we were unable to
		 * queue it, then clear the pending flag.
		 */
		if (e.doRun instanceof ComponentWorkRequest) {
		    ComponentWorkRequest req = (ComponentWorkRequest)e.doRun;
		    synchronized(req) {
			req.isPending = false;
		    }
		}

		/* If this is a Timer event let it know that it didn't fire.
		 */
		if(e.doRun instanceof Timer.DoPostEvent) {
		    ((Timer.DoPostEvent)e.doRun).getTimer().cancelEvent();
		}

		/* We are unable to queue this event on a system event queue.  Make
		 * sure that any code that's waiting for the runnable to finish
		 * doesn't hang.
		 */
		if (e.lock != null) {
		    e.lock.notify();
		}
		return;
	    }

	    runnableCanvas.addRunnableEvent(e);
	    runnableCanvas.repaint();
	}
    
private static voidprocessRunnableEvent(javax.swing.SystemEventQueueUtilities$RunnableEvent runnableEvent)
Calls RunnableEvent.doRun.run(). If RunnableEvent.lock is non null then we synchronize the run() call and save the exception (if any) in the RunnableEvent.exception field.

	Object lock = runnableEvent.lock;
	if (lock == null) {
	    runnableEvent.doRun.run();
	}
	else {
	    synchronized(lock) {
		try {
		    runnableEvent.doRun.run();
		}
		catch (Exception e) {
		    runnableEvent.exception = e;
		}
		finally {
		    if (runnableEvent.lock != null) {
			runnableEvent.lock.notify();
		    }
		}
	    }
	}
    
static voidqueueComponentWorkRequest(java.awt.Component root)
This method is used by RepaintManager to queue a ComponentWorkRequest with invokeLater(). It assumes that the root argument is either and Applet or a Window, the root passed in obtained in a slightly different manner than see SwingUtilities.getRoot(). If this called with the root obtained in a different way than RepaintManager currently uses, be sure to also tweak removeRunnableCanvas.

	ComponentWorkRequest req = (ComponentWorkRequest)(getRootTable().get(root));
	boolean newWorkRequest = (req == null);
	if (newWorkRequest) {
	    req = new ComponentWorkRequest(root);
	}

	/* At this point the ComponentWorkRequest may be accessible from
	 * an event dispatching thread so before updating it further
	 * we synchronize access to it.
	 */
	synchronized(req) {
	    if (newWorkRequest) {
		getRootTable().put(root, req);
	    }
	    if (!req.isPending) {
		SwingUtilities.invokeLater(req);
		req.isPending = true;
	    }
	}
    
static voidremoveRunnableCanvas(javax.swing.JRootPane rootPane)
Remove the RunnableCanvas from the JRootPane and clear the internal bookeeping associated with it.

Called by JRootPane.removeNotify()

see
RunnableCanvas

	synchronized (classLock) {
	    // We don't use SwingUtilities.getRoot, as it has different
	    // behavior then the RepaintManager call to add the initial root.
	    Component root = null;
	    for (Component c = rootPane; c != null; c = c.getParent()) {
		if ((c instanceof Window) ||
		    (c instanceof  java.applet.Applet)) {
		    root = c;
		    break;
		}
	    }
	    if (root != null) {
		getRootTable().remove(root);
	    }
	    RunnableCanvas.remove(rootPane);
	}
    
static voidrestartTimerQueueThread()
Adds a RunnableEvent to all the remaining RunnableCanvases to restart the TimerQueues thread.

see
RunnableCanvas#postRunnableEventToAll

	synchronized (classLock) {
	    if (SystemEventQueue.get() == null) {
		Runnable restarter = new TimerQueueRestart();
		RunnableEvent event = new RunnableEvent(restarter, null);
		RunnableCanvas.postRunnableEventToAll(event);
	    }
	}