?? window.java
字號:
/*
* MWT - Micro Window Toolkit
* Copyright (C) 2007 Lucas Domanico - lucazd@gmail.com
*
* Licensed under the terms of the GNU Lesser General Public License:
* http://www.opensource.org/licenses/lgpl-license.php
*
* For further information visit:
* http://j2me-mwt.sourceforge.net/
*/
package mwt;
import javax.microedition.lcdui.Canvas;
import javax.microedition.lcdui.Graphics;
/**
* <p>In MWT the Window class is like a Frame/Form/Shell in other UI frameworks.<br>
* Normally, an application that uses MWT should instance at least one window.</p>
*
* A window has the following functionallity:
* <ul>
* <li><a href="#input" >Handles input</a></li>
* <li><a href="#focus" >Keeps track of the focus</a></li>
* <li><a href="#painting">Paints components</a></li>
* <li><a href="#dialogs" >Shows dialogs</a></li>
* </ul>
*
*
*
* <h3>Handling Input<a name="input"></a></h3>
* <p>A window should be notified whenever a key is pressed or released using
* {@link #setKeyState(int, int, boolean)} method.<br>
* Normally you will invoke this method from your canvas implementation:
* <pre>
* class MyCanvas extends Canvas {
* Window win;
* protected void keyPressed(int keyCode) { win.setKeyState(keyCode,Window.KEYSTATE_PRESSED,true); }
* protected void keyReleased(int keyCode) { win.setKeyState(keyCode,Window.KEYSTATE_RELEASED,true); }
* ...
* }
* </pre>
*
* <p>Some devices don't support the {@link Canvas#keyRepeated(int)} event. MWT can "simulate" this event calling
* {@link #repeatKeys(boolean)} from your application's main loop.</p>
*
* <p>You may get a key state at anytime using {@link #getKeyState(int)}.</p>
*
* <h4>Focus Actions</h4>
* <p>Usually in UI frameworks the keyboard's TAB and ARROWS keys are used to move
* the focus, the ENTER key is used to trigger actions. Similarly, "focus actions" are
* used to handle such things.</p>
*
* <p>A focus action can be either {@link #FOCUSACTION_FIRE}, {@link #FOCUSACTION_NEXT},
* {@link #FOCUSACTION_PREV} or {@link #FOCUSACTION_NONE}.</p>
*
* <p>The MWT Window has a default implementation which uses {@link Canvas#KEY_NUM2},
* {@link Canvas#KEY_NUM8}, {@link Canvas#KEY_NUM6} and {@link Canvas#KEY_NUM4} to move the focus
* and {@link Canvas#KEY_NUM5} to trigger actions.<br>
* You can define your own implementation overriding {@link #getFocusAction(long)} method.</p>
*
*
* <br>
*
*
* <h3>Handling Focus<a name="focus"></a></h3>
* <p>A window can focus one or none components simultaneously.<br>
* To set the focus directely use {@link #setFocus(Component)}, but if you like to move it
* use {@link #setFocusNext()} and {@link #setFocusPrevious()}.<br>
* Note that when a window is created and components are added into it focus is still null.
* You must set the focus "manually".</p>
*
* <p>Components don't have a "focusIndex" (or "tabIndex" in other UI frameworks)
* propery, focus is moved according to the component hierarchy.</p>
*
* <p>Remember that a component can gain focus only if
* {@link mwt.Component#acceptsFocus()} is true.</p>
*
*
* <br>
*
*
* <h3>Painting<a name="painting"></a></h3>
* <p>The {@link #paint(Graphics)} paints all childs components into the graphics in
* hierarchy order; there is not a "z-index" property.</p>
*
* <p>A window paints all components during each paint call, there is not a dirty rectangle
* implementation.</p>
*
*
* <br>
*
*
* <h3>Dialogs<a name="dialogs"></a></h3>
* <p>MWT allows you create dialogs, setting another window in front.<br>
* You don't need to notify input events to the new dialog window, its owner window
* dispatch these events automatically to the dialog.</p>
*
* <p>Unlike other UI frameworks, the method {@link #dialogOpen(Window)} returns immediately,
* without waiting the dialog to close. However, is possible to simulate this trick by
* calling your application main loop.</p>
* <pre>
* Window main = ...;
* boolean result;
* Window dialog = ...; // sets the result before closing
*
* void save() {
* main.dialogOpen(dialog);
* while(main.getDialog() == dialog)
* mainLoop();
* if(result) ...
* else ...
* }
* </pre>
* Remember, everytime you use a {@link #dialogOpen(Window)}, a {@link #dialogClose()}
* should be called somewhere.
*
* <h3><a name="keys">Keys, KeyCodes and Key's States</a></h3>
* <p>A key code is a value that maps a device's key, like
* {@link javax.microedition.lcdui.Canvas}'s KEY_NUMs.</p>
*
* <p>MWT uses two more concepts; key's states and keys.<br>
* A key state is a value that represents the state of a key at anytime.
* That is, if it is released, pressed or repeated.<br>
* {@link #KEYSTATE_PRESSED} or 1 is for key pressed states.<br>
* {@link #KEYSTATE_RELEASED} or 0 is for key released states.<br>
* Other values are for key repeated states.<br>
* A key is a long value where the integer part is the key code, and the key >> 32
* value is its key state.
*
*/
public class Window extends Component {
/** Constant returned by {@link #getFocusAction(long)} when there's not action. */
final static public int FOCUSACTION_NONE = 0;
/** Constant returned by {@link #getFocusAction(long)} to "fire" events. */
final static public int FOCUSACTION_FIRE = 1;
/** Constant returned by {@link #getFocusAction(long)} to request focus next. */
final static public int FOCUSACTION_NEXT = 2;
/** Constant returned by {@link #getFocusAction(long)} to request focus previous. */
final static public int FOCUSACTION_PREV = 4;
/** Constant value to get/set a skin/font. */
static public final int STYLE_DEFAULT = 0;
/** Constant value to get/set a skin/font. */
static public final int STYLE_DISABLED = 1;
/** Constant which represents the state of a key when is pressed. See also <a href="#keys">Keys</a>. */
public static final int KEYSTATE_PRESSED = 1;
/** Constant which represents the state of a key when is released. See also <a href="#keys">Keys</a>. */
public static final int KEYSTATE_RELEASED = 0;
private Window dialog;
private Component focus;
static private final int KEYS_INC = 20;
private int keysLength; // warning, must be synchronized
private long[] keys = new long[KEYS_INC]; // warning, must be synchronized
// stores the graphics' clip durning the Component's '_paint' method
int rectX;
int rectY;
int rectW;
int rectH;
private final Skin[] skins;
final static private Skin[] defaultSkins = {
new Skin(new int[] {0xFFFFFF,0,0,0xC6C6C6,0xC6C6C6}),
new Skin(new int[] {0xFFFFFF,0xC6C6C6,0xC6C6C6,0xC6C6C6})
};
/** Creates a new window with the given position and size. */
public Window(int x, int y, int width, int height) {
super(x,y,width,height,true);
skins = new Skin[] { defaultSkins[0].clone(), defaultSkins[1].clone() };
}
/** Gets the default skin for the given style. */
static final public Skin getDefaultSkin(int style) { return defaultSkins[style]; }
/** Sets the default skin for the given style. */
static final public void setDefaultSkin(int style, Skin skin) { defaultSkins[style] = skin; }
/** Gets this window skin for the given style. */
public Skin getSkin(int style) { return skins[style]; }
/** Sets this window skin for the given style. */
public void setSkin(int style, Skin skin) { skins[style] = skin; }
/**
* Gets the current key state for the given keycode.
* @param keyCode the key code
* @return the current key state for the given keycode
* @see <a href="#keys">Keys</a>
*/
final public int getKeyState(int keyCode) {
synchronized(keys) {
return (int) (keys[getKeyIndex(keyCode)] >> 32);
}
}
/**
* Gets the focus action for the given key.<br>
* The default implementation is:
* <pre>
* protected int getFocusAction(long key) {
* switch((int) key) {
* case Canvas.KEY_NUM4:
* case Canvas.KEY_NUM2: return FOCUSACTION_PREV;
* case Canvas.KEY_NUM6:
* case Canvas.KEY_NUM8: return FOCUSACTION_NEXT;
* case Canvas.KEY_NUM5: return FOCUSACTION_FIRE;
* default: return FOCUSACTION_NONE;
* }
* }
* </pre>
* Note that you can ask for other key states using {@link #getKeyState(int)}.
* This allow you, for example, poll if another key is pressed.
* <pre>
* if((int)key && getKeyState(Canvas.KEY_NUM0)) ...
* </pre>
* @param key the key
* @return the focus action
* @see <a href="#keys">Keys</a>
*/
public int getFocusAction(long key) {
switch((int) key) {
case Canvas.KEY_NUM4:
case Canvas.KEY_NUM2: return FOCUSACTION_PREV;
case Canvas.KEY_NUM6:
case Canvas.KEY_NUM8: return FOCUSACTION_NEXT;
case Canvas.KEY_NUM5: return FOCUSACTION_FIRE;
default: return FOCUSACTION_NONE;
}
}
private static final int KEYSTATE_REPEATED = -1;
final static private long KEY_STATE = 0xFFFFFFFF00000000l;
/**
* Sets the key state for the given key code.<br>
* This method triggers component's key events if processKeyEvents is true.
* @param keyCode The key code
* @param keyState The new key state for the given key code. Either {@link #KEYSTATE_PRESSED} or {@link #KEYSTATE_RELEASED}
* @param processKeyEvents True if component's key events should be triggered
* @throws IllegalArgumentException
* @see <a href="#keys">Keys</a>
*/
final public void setKeyState(int keyCode, int keyState, boolean processKeyEvents) throws IllegalArgumentException {
if(dialog != null) { dialog.setKeyState(keyCode,keyState,processKeyEvents); return; }
synchronized(keys) {
final int index = getKeyIndex(keyCode);
switch(keyState) {
case KEYSTATE_RELEASED: keys[index] &= ~KEY_STATE; break;
case KEYSTATE_PRESSED: keys[index] = (keys[index] & ~KEY_STATE) | (0x0000000100000000l); break;
case KEYSTATE_REPEATED: keys[index] = (keys[index] & ~KEY_STATE) | (((keys[index] >> 32)+1) << 32); break;
default: throw new IllegalArgumentException("Invalid key state");
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -