001: /*
002: *
003: *
004: * Copyright 1990-2007 Sun Microsystems, Inc. All Rights Reserved.
005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License version
009: * 2 only, as published by the Free Software Foundation.
010: *
011: * This program is distributed in the hope that it will be useful, but
012: * WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * General Public License version 2 for more details (a copy is
015: * included at /legal/license.txt).
016: *
017: * You should have received a copy of the GNU General Public License
018: * version 2 along with this work; if not, write to the Free Software
019: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA
021: *
022: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
023: * Clara, CA 95054 or visit www.sun.com if you need additional
024: * information or have any questions.
025: */
026:
027: package com.sun.midp.util;
028:
029: import javax.microedition.lcdui.Display;
030:
031: /**
032: * An adaptor class that lets a caller synchronize with the event thread. The
033: * invokeAndWait() method enqueues an event using Display.callSerially() and
034: * blocks the caller. When the event reaches the front of the queue, it calls
035: * this object's run() method on the event thread, and unblocks the caller.
036: *
037: * Clients may override the run() method if they wish to provide specialized
038: * behavior that must be run on the event thread. If run() is not overridden,
039: * invokeAndWait() simply blocks until the event thread has processed the
040: * event. This is useful for callers that need to wait until after an event
041: * has been processed.
042: *
043: * The invokeAndWait() method must not be called on the event thread,
044: * otherwise the system will deadlock.
045: */
046: public class SerialCallback implements Runnable {
047:
048: Display dpy;
049: Callback callback;
050: boolean done;
051:
052: /**
053: * Constructs this callback object. Requires a Display object upon which
054: * the callSerially() method is to be invoked.
055: */
056: public SerialCallback(Display dpy) {
057: this .dpy = dpy;
058: callback = new Callback();
059: }
060:
061: /**
062: * Blocks the caller until the events currently in the event queue have
063: * been processed, calls the run() method on the event thread, then
064: * unblocks the caller.
065: */
066: public synchronized void invokeAndWait() {
067: dpy.callSerially(callback);
068: done = false;
069:
070: try {
071: while (!done) {
072: wait();
073: }
074: } catch (InterruptedException ignore) {
075: }
076: }
077:
078: /**
079: * Subclassers may override this if they wish to provide any specialized
080: * behavior. The default implementation does nothing.
081: */
082: public void run() {
083: }
084:
085: /**
086: * Called on the event thread when the callSerially event reaches the
087: * front of the queue. Calls the client's run() method and awakens the
088: * thread that had called invokeAndWait().
089: */
090: synchronized void called() {
091: run();
092: done = true;
093: notifyAll();
094: }
095:
096: /**
097: * A nested class that provides a run() method to callSerially(), distinct
098: * from the run() method that can be overridden by clients.
099: */
100: class Callback implements Runnable {
101: public void run() {
102: called();
103: }
104: }
105: }
|