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 + -
显示快捷键?