repainteventproducer.java

来自「This is a resource based on j2me embedde」· Java 代码 · 共 282 行

JAVA
282
字号
/* *    * * Copyright  1990-2007 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER *  * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License version * 2 only, as published by the Free Software Foundation. *  * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License version 2 for more details (a copy is * included at /legal/license.txt). *  * You should have received a copy of the GNU General Public License * version 2 along with this work; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA *  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa * Clara, CA 95054 or visit www.sun.com if you need additional * information or have any questions. */package com.sun.midp.lcdui;import com.sun.midp.events.EventTypes;import com.sun.midp.events.Event;import com.sun.midp.events.EventListener;import com.sun.midp.events.EventQueue;import com.sun.midp.security.Permissions;import com.sun.midp.security.SecurityToken;import javax.microedition.lcdui.Display;/** * This class performs all of the repaint event handling. */public class RepaintEventProducer implements EventListener {    /** Cached reference to the MIDP event queue. */    private EventQueue eventQueue;    /** Repaint event free for reuse. */    private RepaintEvent pooledEvent1;    /** Repaint event free for reuse. */    private RepaintEvent pooledEvent2;    /** Repaint event free for reuse. */    private RepaintEvent pooledEvent3;    /**     * Repaint event in the queue or waiting to be moved to the processed     * slot. Events are rotated to different slots in     * <code>preprocessRepaints</code>.     */    private RepaintEvent queuedEvent;    /**     * Repaint event being processed (queue has event also) or     * has been processed (no event in the queue).     */    private RepaintEvent eventInProcess;    /**     * The constructor LCDUI repaint events handler.     *     * @param theEventQueue the event queue     */    public RepaintEventProducer(EventQueue theEventQueue) {                eventQueue = theEventQueue;        pooledEvent1 = RepaintEvent.createRepaintEvent(null, 0, 0, 0, 0, null);        pooledEvent2 = RepaintEvent.createRepaintEvent(null, 0, 0, 0, 0, null);        pooledEvent3 = RepaintEvent.createRepaintEvent(null, 0, 0, 0, 0, null);                eventQueue.registerEventListener(EventTypes.REPAINT_EVENT, this);    }    /**     * Called to schedule a repaint of the current Displayable     * as soon as possible.     *     * @param d     The Display     * @param x     The x coordinate of the origin of the repaint rectangle     * @param y     The y coordinate of the origin of the repaint rectangle     * @param w     The width of the repaint rectangle     * @param h     The height of the repaint rectangle     * @param target An optional target Object, which may have been the     *               original requestor for the repaint     */    public void scheduleRepaint(DisplayEventConsumer d,                                int x, int y, int w, int h, Object target) {        RepaintEvent freeEvent;        synchronized (this) {            freeEvent = pooledEvent1;            freeEvent.setRepaintFields(d, x, y, w, h, target);            if (queuedEvent == null) {                /*                 * Since the queue does not lock posting during event                 * processing, we need to rotate 3 repaint events for reuse.                 *                 * 1 for the queued event, 1 for the event begin processed                 * and 1 for temporary use when merging a new event with                 * a queued event.                 *                 * Event pooling is done because game can generate upto 15                 * repaints a second and cause a lot garbage collection if                 * we created new repaint every time.                 */                pooledEvent1 = pooledEvent2;                pooledEvent2 = pooledEvent3;                pooledEvent3 = freeEvent;                queuedEvent = freeEvent;                eventQueue.post(queuedEvent);            } else if (queuedEvent.display != d) {                /*                 * A new display has come to the foreground so don't                 * bother paint the display in the queued event.                 *                 * Overwrite this fields in queue event with new values.                 */                 queuedEvent.setRepaintFields(d, x, y, w, h, target);            } else {                /*                 * When there is a pending repaint                 * union the dirty regions into one event                 */                if (queuedEvent.paintX1 > freeEvent.paintX1) {                    queuedEvent.paintX1 = freeEvent.paintX1;                }                if (queuedEvent.paintY1 > freeEvent.paintY1) {                    queuedEvent.paintY1 = freeEvent.paintY1;                }                if (queuedEvent.paintX2 < freeEvent.paintX2) {                    queuedEvent.paintX2 = freeEvent.paintX2;                }                                if (queuedEvent.paintY2 < freeEvent.paintY2) {                    queuedEvent.paintY2 = freeEvent.paintY2;                }                queuedEvent.paintTarget = null;            }        }    }    /**     * Preprocess an event that is being posted to the event queue.     *      * @param event event being posted     *     * @param waitingEvent previous event of this type waiting in the     *     queue to be processed     *      * @return true to allow the post to continue, false to not post the     *     event to the queue     */    public boolean preprocess(Event event, Event waitingEvent) {        /*         * Because of the needs of serviceRepaints the preprocessing         * is done in scheduleRepaint.         */        return true;    }    /**     * Process an event.     *     * @param genericEvent event to process     */    public void process(Event genericEvent) {        RepaintEvent event = (RepaintEvent)genericEvent;        synchronized (this) {            queuedEvent = null;            eventInProcess = event;        }        /*         * Target DisplayEventConsumer is obtained directly from event field.         * Assumed that target consumer is not null.         */        event.display.handleRepaintEvent(                event.paintX1, event.paintY1,                 event.paintX2, event.paintY2,                 event.paintTarget);        synchronized (this) {            /* Change the ID here to signal waitForRepaint. */            eventInProcess.perUseID++;                        eventInProcess = null;            // ServiceRepaints may be blocking.            notifyAll();        }    }    /**     * Called to block the calling MIDlet until the the pending repaint     * operation is performed.     * <p>     * Does not return until the pending repaint (if any)     * has been processed.</p>     *     */    public void serviceRepaints() {        if (EventQueue.isDispatchThread()) {            Event event;            if (eventInProcess != null) {                /*                 * We are in the midst of a calling the application's                 * paint method, avoid recursion, simply return                 */                return;            }            /*             * Since we are in the dispatch thread, at this point             * there can only one repaint in the queue so remove it             * from the queue and process it.             */            event = eventQueue.remove(EventTypes.REPAINT_EVENT);            /* Do not hold a lock when calling out to the application */            if (event != null) {                process(event);            }        } else {            /*             * We only want paint events to be process in the dispatch             * to avoid deadlocks. So wait for the repaint event to occur.             */            waitForCurrentRepaintEvents();        }    }    /**     * Wait for the event queue to process all of the events currently     * in the queue but not any new ones after the start of this     * method.     */    private void waitForCurrentRepaintEvents() {        RepaintEvent eventToWaitFor = null;        int currentEventUseID;        synchronized (this) {            if (queuedEvent != null) {                eventToWaitFor = queuedEvent;            } else if (eventInProcess != null) {                eventToWaitFor = eventInProcess;            } else {                /* Nothing to wait for, done. */                return;            }            currentEventUseID = eventToWaitFor.perUseID;            while (eventToWaitFor.perUseID == currentEventUseID) {                try {                    wait();                } catch (InterruptedException ie) {                    /* The application wants this thread to unblock */                    break;                }            }                        }    }    }

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?