⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 window.java

📁 Micro Window Toolkit(MWT)是一个用于开发J2ME用户界面(UI)的工具包。它具有友好
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/*
 * 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 + -