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