basicinputmode.java
来自「This is a resource based on j2me embedde」· Java 代码 · 共 686 行 · 第 1/2 页
JAVA
686 行
/* * * * 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.input;import javax.microedition.lcdui.Canvas;import javax.microedition.lcdui.TextField;import javax.microedition.lcdui.Displayable;import com.sun.midp.i18n.*;import com.sun.midp.log.Logging;import com.sun.midp.log.LogChannels;/** * An InputMode instance which processes the numeric 0-9 keys * as their literal numeric values. */abstract class BasicInputMode implements InputMode, Runnable { /** * Text input constraints for this input mode. The semantics of the * constraints value are defined in the TextField API. */ protected int constraints; /** * Text input modifiers for this input mode. The semantics of the * modifiers value are defined in the TextField API. */ protected int modifiers; /** * A timeout, in ms, after which a pending key will be committed * to the text component. By default this is set to 250ms. */ protected static final int KEY_COMMIT_TIMEOUT = 1000; /** A holder for the keyCode which was last processed */ protected int lastKey = -1; /** The InputModeMediator for the current input session */ protected InputModeMediator mediator; /** * A boolean flag used by the timer in this input mode to * determine if a character should be committed to the text * component or not */ protected boolean commitChar; /** * The number of times the user pressed the last key code. This value * acts as an index into the array of possible characters of any one * key. For example, a lastKey == to Canvas.KEY_NUM2 and a clickCount * of 3 would yield a 'c'. */ protected int clickCount; /** * The single, pending character based on the key presses thus far */ protected int pendingChar = KEYCODE_NONE; /** * Flag indicating if more matches exist */ protected boolean hasMoreMatches; /** * A boolean flag used by the timer in this input mode to * know when to completely shut down the timer thread. That is, * when the input session is no longer active, the timer thread * in this input mode will quit entirely, freeing up system * resources. */ protected boolean sessionIsLive; /** the possible key maps for this input mode */ static char[][] keyMap; /** * This method will be called before any input keys are passed * to this InputMode to allow the InputMode to perform any needed * initialization. A reference to the InputModeMediator which is * currently managing the relationship between this InputMode and * the input session is passed in. This reference can be used * by this InputMode to commit text input as well as end the input * session with this InputMode. The reference is only valid until * this InputMode's endInput() method is called. * * @param constraints text input constraints. The semantics of the * constraints value are defined in the TextField API. * * @param mediator the InputModeMediator which is negotiating the * relationship between this InputMode and the input session * @param inputSubset current input subset */ public void beginInput(InputModeMediator mediator, String inputSubset, int constraints) { if (Logging.REPORT_LEVEL <= Logging.INFORMATION) { Logging.report(Logging.INFORMATION, LogChannels.LC_HIGHUI, "[basic.beginInput] >>"); } validateState(false); this.mediator = mediator; this.constraints = constraints & TextField.CONSTRAINT_MASK; this.modifiers = constraints & ~TextField.CONSTRAINT_MASK; startTimer(); setInputSubset(inputSubset); setKeyMap(constraints, false); if (Logging.REPORT_LEVEL <= Logging.INFORMATION) { Logging.report(Logging.INFORMATION, LogChannels.LC_HIGHUI, "[basic.beginInput] <<"); } } /** * Start timmer which will attempt to commit * a pending character after a certain timeout */ private void startTimer() { (new Thread(this)).start(); } /** * Stop timmer which will attempt to commit * a pending character after a certain timeout */ private void stopTimer() { sessionIsLive = false; // Lastly, we'll interrupt the timer to end it. synchronized (this) { try { notify(); } catch (IllegalMonitorStateException ignore) { } } } /** * Reset timmer which will attempt to commit * a pending character after a certain timeout */ private void resetTimer() { sessionIsLive = true; // Lastly, we'll interrupt the timer to end it. synchronized (this) { try { notify(); } catch (IllegalMonitorStateException ignore) { } } } /** * Returns true if input mode is using its own displayable, false ifinput * mode does not require the speial displayable for its representation. * By default - false * @return true if input mode is using its own displayable, otherwise false */ public boolean hasDisplayable() { return false; } /** * Converts the string to key map. The rows are separated each from other * by '$'. The characters inside of one row follow each to other without * any separator. * @param line string combines all keys * @return map of the keys in char[][] format */ protected char[][] getMapByLine(String line) { char[] chars = line.toCharArray(); int rows = 1; for (int i = line.length() - 1; i >= 0; i--) { if (chars[i] == '$') rows++; } char[][] map = new char[rows][]; for (int start = 0, j = 0; start < line.length(); j++) { int end = line.indexOf('$', start); // if '$' is not found that means the end of string is reached if (end == -1) end = line.length(); map[j] = line.substring(start, end).toCharArray(); start = end + 1; } return map; } /** * Set the corresponding key map. * * @param constraints text input constraints. The semantics of the * constraints value are defined in the TextField API. * * @param longPress return true if it's long key press otherwise false * * @return true if the key map has been changed otherwise false */ protected abstract boolean setKeyMap(int constraints, boolean longPress); /** * Process the given key code as input. * * This method will return true if the key was processed successfully, * false otherwise. * * @param keyCode the keycode of the key which was input * @param longPress return true if it's long key press otherwise false * @return the key code if the key has been committed for the input, or * KEYCODE_NONE if the key has not been habdled by the input mode, or * KEYCODE_INVISIBLE if the key has been handled by the input mode but * this key has not been displayed */ public int processKey(int keyCode, boolean longPress) { int ret = KEYCODE_NONE; if (isValidKey(keyCode, longPress)) { // We immediately disable the commit of any pending character // input in case the timer expires commitChar = false; validateState(true); if (mediator != null && mediator.isClearKey(keyCode) || keyCode == Canvas.LEFT || keyCode == Canvas.RIGHT || keyCode == Canvas.UP || keyCode == Canvas.DOWN) { if (Logging.REPORT_LEVEL <= Logging.INFORMATION) { Logging.report(Logging.INFORMATION, LogChannels.LC_HIGHUI, "[processKey] got clear or arrow. lastKey=" + lastKey); } completeInputMode(true); } else { if (setKeyMap(constraints, longPress)) { pendingChar = KEYCODE_NONE; clickCount = 0; } // at first check if previous key has to be committed // If we have a pending keycode and this new keycode is // different, we will commit the previous key and continue if (lastKey != -1 && lastKey != keyCode) { commitPendingChar(); } clickCount++; // If the pending key code has just one match or long key // press happens commit the current key if (longPress) { if (lastKey != -1) { lastKey = keyCode; commitPendingChar(); } } else if (hasOneCase(keyCode)) { lastKey = keyCode; commitPendingChar(); } else { lastKey = keyCode; } // Lastly, we'll interrupt the timer to reset it or start it if // timer is still not working. resetTimer(); if (getNextChar() == KEYCODE_NONE) { lastKey = -1; } ret = getPendingCharInternal(); } } else { ret = InputMode.KEYCODE_INVISIBLE; if (Logging.REPORT_LEVEL <= Logging.INFORMATION) { Logging.report(Logging.INFORMATION, LogChannels.LC_HIGHUI, "[processKey] returning KEYCODE_INVISIBLE"); } } return ret; } /** * Check if the key has to be handled this input mode * @param keyCode key * @param longPress true if long key press happens otherwise false. * @return true if this key can be handled by this input mode, * otherwise false */ private boolean isValidKey(int keyCode, boolean longPress) { if ((keyCode != Canvas.KEY_STAR && keyCode != Canvas.KEY_POUND && (mediator != null && !mediator.isClearKey(keyCode)) && keyCode != Canvas.LEFT && keyCode != Canvas.RIGHT && keyCode != Canvas.UP && keyCode != Canvas.DOWN && (keyCode < Canvas.KEY_NUM0 || keyCode > Canvas.KEY_NUM9)) || (longPress && lastKey != keyCode && lastKey != -1)) { if (Logging.REPORT_LEVEL <= Logging.INFORMATION) { Logging.report(Logging.INFORMATION, LogChannels.LC_HIGHUI, "INVALID KEY"); } return false; } return true; } /** * Set the next capital mode for this input method */ protected void nextCapsMode() {} /** * Get next possble char
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?