cwindow.java

来自「This is a resource based on j2me embedde」· Java 代码 · 共 745 行 · 第 1/2 页

JAVA
745
字号
/* *   * * 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.chameleon;import com.sun.midp.chameleon.layers.BackgroundLayer;import javax.microedition.lcdui.*;/** * This class is a top-level "window" in Chameleon. A window is * a collection of other layers and serves to maintain a z-ordering * of those layers. The window also contains the complex repaint logic * to support semi-transparent windows, their dirty regions, and the * rectangle logic to repaint other layers of the window when necessary. */public abstract class CWindow {        /**     * An array holding the bounds of this window. The indices are     * as follows:     * 0 = window's 'x' coordinate     * 1 = window's 'y' coordinate     * 2 = window's width     * 3 = window's height     *      * Note: The window's x and y coordinate can only be interpreted     * by some outside entity. For example, if some sort of manager     * was in charge of overseeing the placement of windows on the     * screen, it could do so by using the x and y coordinate values     * of this window's bounds.     */    public int[]   bounds;        /**     * Flag indicating that at least one layer belonging to this     * window is in need of repainting      */    protected boolean dirty;    /**     * Ordered bi-directional list with all the layers of this window.     */    protected CLayerList layers;    /** The number of dirty layers to repaint */    protected int dirtyCount;    /** Initial maximal number of the dirty layers */    protected int dirtyMaxCount = 10;    /** Layers replication to not keep the lock on painting */    protected CLayer[] dirtyLayers = new CLayer[dirtyMaxCount];    /**     * Background layer of this window, should be the bottom most layer     * of the window, can be invisible for transparent windows.      */    protected BackgroundLayer bgLayer;    /** Cache values for the clip rectangle */    protected int cX, cY, cW, cH;        /** Cache values for the graphics translation */    protected int tranX, tranY;        /** Cache value for the graphics font */    protected Font font;        /** Cache value for the graphics foreground color */    protected int color;        /**     * Construct a new CWindow given the background image and color.     * If the background image is null, the fill color will be used     * instead. In the case null image and negative color are specified     * the window is considered to be transparent.     *     * @param bgImage the background image to use for the window background     * @param bgColor the background fill color in 0xrrggbbaa format to use     *          for the window background if the background image is null.     */    public CWindow(Image bgImage, int bgColor, int width, int height) {        bounds = new int[4];        bounds[X] = 0; bounds[Y] = 0;        bounds[W] = width;        bounds[H] = height;        layers = new CLayerList();        /* Add the most bottom background layer */        bgLayer = new BackgroundLayer(bgImage, bgColor);        bgLayer.setBounds(0, 0, width, height);        addLayer(bgLayer);    }    /** Resize window and its background according to updated skin values */    public void resize(int width, int height) {        bounds[W] = width;        bounds[H] = height;        bgLayer.setBounds(0, 0, width, height);    }    /**     * Add a new CLayer to the "deck" of layers associated     * with this CWindow. This method will sequentially add     * layers to the window, placing subsequently added layers     * on top of previously added layers.     *     * @param layer the new layer to add to this window     * @return true if new layer was added, false otherwise      */    public boolean addLayer(CLayer layer) {        if (layer != null) {            if (CGraphicsQ.DEBUG) {                System.err.println("Add Layer: " + layer);            }            synchronized (layers) {                if (layers.find(layer) == null) {                    layer.owner = this;                    layers.addLayer(layer);                    layer.addDirtyRegion();                    requestRepaint();                    layer.addNotify();                     return true;                }            }        }        return false;    }    /**     * Remove a layer from this CWindow. This method will remove     * the given layer from the "deck" of layers associated with     * this CWindow. If successfull, this method will return true,     * false otherwise (for example, if the layer does not belong     * to this window).     *     * @param layer the layer to remove from this window     * @return true if successful, false otherwise     */    public boolean removeLayer(CLayer layer) {        synchronized (layers) {            CLayerElement le = sweepLayer(layer);            if (le != null) {                if (CGraphicsQ.DEBUG) {                    System.err.println("Remove Layer: " + layer);                }                layer.owner = null;                requestRepaint();                layers.removeLayerElement(le);                layer.removeNotify(this);                 return true;            }        }        return false;    }    /**     * Move layer to anotger location     * @param newBounds new bounds for this layer      * @param x New 'x' coordinate of the layer's origin     * @param y New 'y' coordinate of the layer's origin     * @param w New width of the layer     * @param h New height of the layer     * @return true if successful, false otherwise     */    public boolean relocateLayer(CLayer layer, int x, int y, int w, int h) {        if (layer != null) {            synchronized (layers) {                if (sweepLayer(layer) != null) {                    if (CGraphicsQ.DEBUG) {                        System.err.println("Relocate Layer: " + layer);                    }                    int[] oldBounds = {                                 layer.bounds[X],                                layer.bounds[Y],                                layer.bounds[W],                                layer.bounds[H] };                    if (oldBounds[X] != x || oldBounds[Y] != y ||                        oldBounds[W] != w || oldBounds[H] != h) {                        layer.setBounds(x, y, w, h);                        layer.addDirtyRegion();                        requestRepaint();                        layer.relocateNotify(oldBounds);                         return true;                    }                }            }        }        return false;    }    /**     * Allow this window to process key input. The type of key input     * will be press, release, repeat, etc. The key code will identify     * which key generated the event. This method will return true if     * the event was processed by this window or one of its layers,     * false otherwise.     *     * @param type the type of key event (press, release, repeat)     * @param keyCode the identifier of the key which generated the event     * @return true if this window or one of its layers processed the event     */    public boolean keyInput(int type, int keyCode) {        CLayer layer;        synchronized (layers) {            for (CLayerElement le = layers.getTop();                    le != null; le = le.getLower()) {                layer = le.getLayer();                if (layer.supportsInput &&                        layer.keyInput(type, keyCode))                {                    return true;                }            }        } // sync        return false;    }    /**     * Allow this window to process pointer input. The type of pointer input     * will be press, release, drag, etc. The x and y coordinates will      * identify the point at which the pointer event occurred in the coordinate     * system of this window. This window will translate the coordinates     * appropriately for each layer contained in this window. This method will     * return true if the event was processed by this window or one of its      * layers, false otherwise.     *     * @param type the type of pointer event (press, release, drag)     * @param x the x coordinate of the location of the event     * @param y the y coordinate of the location of the event     * @return true if this window or one of its layers processed the event     */    public boolean pointerInput(int type, int x, int y) {        CLayer layer;        synchronized (layers) {            for (CLayerElement le = layers.getTop();                    le != null; le = le.getLower()) {                layer = le.getLayer();                if (layer.visible && layer.supportsInput &&                    layer.handlePoint(x, y))                {                    // If the layer is visible, supports input, and                    // contains the point of the pointer press, we translate                    // the point into the layer's coordinate space and                    // pass on the input                    if (layer.pointerInput(type, x - layer.bounds[X],                                           y - layer.bounds[Y]))                    {                        return true;                    }                }            }        } // sync        return false;    }    /**     * Handle input from some type of device-dependent     * input method. This could be input from something     * such as T9, or a phonebook lookup, etc.     *     * @param str the text to handle as direct input     * @return true if this window or one of its layers processed the event     */    public boolean methodInput(String str) {        CLayer layer;        synchronized (layers) {            for (CLayerElement le = layers.getTop();                    le != null; le = le.getLower()) {                layer = le.getLayer();                if (layer.visible && layer.supportsInput &&                    layer.methodInput(str))                {                    return true;                }            }        } // sync        return false;    }    /**     * Request a repaint. This method MUST be overridden     * by subclasses to provide the implementation.     */    public abstract void requestRepaint();    /**     * Check whether layer is overlapped with a higher visible layer     * in the layer stack of the window     *     * @param l layer to check overlapping     * @return true if overlapped, false otherwise     */    public boolean isOverlapped(CLayer l) {        synchronized(layers) {            CLayerElement le = layers.find(l);            if (le != null) {                CLayer l2;                for (le = le.getUpper(); le != null; le = le.getUpper()) {                    l2 = le.getLayer();                    if (l2.isVisible() && l.intersects(l2)) {                        return true;                    }                }            }        }        return false;    }    /**     * Subtract this layer area from an underlying dirty regions.     * The method is designed to reduce dirty regions of a layres     * below the opaque visible layer.     *     * @param le layer list element     */    private void cleanLowerDirtyRegions(CLayerElement le) {        if (CGraphicsQ.DEBUG) {            System.err.println("Clean dirty regions under opaque layer: " +                le.getLayer());        }        CLayer l = le.getLayer();        for(CLayerElement le2 = le.getLower();                le2 != null; le2 = le2.getLower()) {            CLayer l2 = le2.getLayer();            if (l2.isDirty()) {                l2.subDirtyRegion(                    l.bounds[X] - l2.bounds[X],                    l.bounds[Y] - l2.bounds[Y],                    l.bounds[W], l.bounds[H]);            }        }    }    /**     * Update dirty regions of all visible layers in the stack regarding     * the entire area of the given layer as being dirty. The method is     * needed to perform layer move/resize/remove opertion, since other     * layers should be informed of changed area.     *     * @param layer the layer whose area should be reported as dirty to     *   other stack layers

⌨️ 快捷键说明

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