predictivetextinputmode.java
来自「This is a resource based on j2me embedde」· Java 代码 · 共 785 行 · 第 1/2 页
JAVA
785 行
/* * * * 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.*;import com.sun.midp.lcdui.*;import com.sun.midp.configurator.Constants;import com.sun.midp.i18n.Resource;import com.sun.midp.i18n.ResourceConstants;import com.sun.midp.log.LogChannels;import com.sun.midp.log.Logging;/** * An InputMode instance which processes the numeric 0-9 keys * as their literal numeric values. */public class PredictiveTextInputMode implements InputMode { /** The InputModeMediator for the current input session */ protected InputModeMediator mediator; /** * Currently formatted predictive word from the PTIterator */ private String part; /** * Iterator interface to the predictive dictionary */ private PTIterator iterator; /** * Keeps the current state strign and compares diffs between current and * next states Class StringDiff is an inner-class defined below */ private StringDiff diff; /** array of sub-inputModes supported by this inputMode */ private static final int[] CAPS_MODES = { CAPS_SENTENCE, CAPS_OFF, CAPS_ON }; /** array of sub-inputModes labels, corresponding to CAPS_MODES array */ private static final String[] CAPS_MODES_LABELS = { Resource.getString(ResourceConstants.LCDUI_TF_CAPS_SENTENCE_LB_PTI), Resource.getString(ResourceConstants.LCDUI_TF_CAPS_OFF_LB_PTI), Resource.getString(ResourceConstants.LCDUI_TF_CAPS_ON_LB_PTI) }; /** points to an element of CAPS_MODES which is the current sub-inputMode */ private int capsMode = 0; /** Init predictive text input mode */ private void init() { iterator = PTDictionaryFactory.getDictionary().iterator(); if (diff == null) { diff = new StringDiff(); } clear(); } /** * This method is called to determine if this InputMode supports * the given text input constraints. The semantics of the constraints * value are defined in the javax.microedition.lcdui.TextField API. * If this InputMode returns false, this InputMode must not be used * to process key input for the selected text component. * @param constraints current constraints. * The constraints format is defined in TextField. * * @return true if this InputMode supports the given text component * constraints, as defined in the MIDP TextField API */ public boolean supportsConstraints(int constraints) { boolean isSupported = false; if ((constraints & TextField.CONSTRAINT_MASK) == TextField.ANY || (constraints & TextField.CONSTRAINT_MASK) == TextField.URL) { isSupported = true; } if ((constraints & TextField.NON_PREDICTIVE) > 0) { isSupported = false; } if ((constraints & TextField.SENSITIVE) > 0) { isSupported = false; } if ((constraints & TextField.PASSWORD) > 0) { isSupported = false; } return isSupported; } /** * Returns the display name which will represent this InputMode to * the user, such as in a selection list or the softbutton bar. * * @return the locale-appropriate name to represent this InputMode * to the user */ public String getName() { return CAPS_MODES_LABELS[capsMode]; } /** * Returns the command name which will represent this InputMode to * the user * * @return the locale-appropriate command name to represent this InputMode * to the user */ public String getCommandName() { return Resource.getString(ResourceConstants.LCDUI_TF_CMD_PTI); } /** * 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, "[*** beginInput]"); } validateState(false); this.mediator = mediator; // need to re-init dictionary every time because the language/locale // can be changed. init(); } /** * Mark the end of this InputMode's processing. The only possible call * to this InputMode after a call to endInput() is a call to beginInput() * to begin a new input session. */ public void endInput() { if (Logging.REPORT_LEVEL <= Logging.INFORMATION) { Logging.report(Logging.INFORMATION, LogChannels.LC_HIGHUI, "********[endInput]"); } validateState(true); this.mediator = null; clear(); } /** * By default the regular input method has no specific displayable * representation so it returns null. * @return null by default */ public Displayable getDisplayable() { return null; } /** * Returns true if input mode is using its own displayable, false ifinput * mode does not require the speial displayable for its representation. * By default returns false * @return true if input mode is using its own displayable, otherwise false */ public boolean hasDisplayable() { return false; } /** * Clear the iterator */ public void clear() { if (Logging.REPORT_LEVEL <= Logging.INFORMATION) { Logging.report(Logging.INFORMATION, LogChannels.LC_HIGHUI, "[clear]"); } diff.clear(); part = ""; iterator.reset(); } /** * 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 true if long key press happens, 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) { if (Logging.REPORT_LEVEL <= Logging.INFORMATION) { Logging.report(Logging.INFORMATION, LogChannels.LC_HIGHUI, "[PT.processKey] keyCode = " + keyCode); } int ret = KEYCODE_NONE; boolean gotoNextState = true; boolean needClear = false; boolean needFinishWord = false; validateState(true); if (mediator != null && mediator.isClearKey(keyCode)) { if (longPress) { if (Logging.REPORT_LEVEL <= Logging.INFORMATION) { Logging.report(Logging.INFORMATION, LogChannels.LC_HIGHUI, " **isClearALL**"); } clear(); gotoNextState = false; } else { if (Logging.REPORT_LEVEL <= Logging.INFORMATION) { Logging.report(Logging.INFORMATION, LogChannels.LC_HIGHUI, " **isClearOne**"); } if (part.length() <= 1) { clear(); gotoNextState = false; // return KEYCODE_NONE; } else { if (Logging.REPORT_LEVEL <= Logging.INFORMATION) { Logging.report(Logging.INFORMATION, LogChannels.LC_HIGHUI, " part.length()>1"); } iterator.prevLevel(); part = getNextMatch(); // part=part.substring(0, part.length()-1); // diff.stateModified(part); ret = KEYCODE_INVISIBLE; } } } else if (longPress) { if (Logging.REPORT_LEVEL <= Logging.INFORMATION) { Logging.report(Logging.INFORMATION, LogChannels.LC_HIGHUI, " **longPress**"); } needFinishWord = true; if (isValidKey(keyCode)) { // if (part.length()>0) { // } part = part.substring(0, part.length() - 1) + String.valueOf((char) keyCode); } needClear = true; } else if (isNextOption(keyCode)) { /** * 2. handle '#' (show next completion option) case */ if (Logging.REPORT_LEVEL <= Logging.INFORMATION) { Logging.report(Logging.INFORMATION, LogChannels.LC_HIGHUI, " **isNextOption**"); } if (part.length() == 0) { gotoNextState = false; } else { part = getNextMatch(); } } else if (isPrevOption(keyCode)) { if (Logging.REPORT_LEVEL <= Logging.INFORMATION) { Logging.report(Logging.INFORMATION, LogChannels.LC_HIGHUI, " **isPrev**"); } part = getPrevMatch(); } else if (isKeyMapChange(keyCode)) { if (Logging.REPORT_LEVEL <= Logging.INFORMATION) { Logging.report(Logging.INFORMATION, LogChannels.LC_HIGHUI, " **isKeyMapChange**"); } /** * 3. handle '*' (key map change) case */ nextCapsMode(); } else if (isWhiteSpace(keyCode)) { if (Logging.REPORT_LEVEL <= Logging.INFORMATION) { Logging.report(Logging.INFORMATION, LogChannels.LC_HIGHUI, " **isWhiteSpace**"); } /** * 4. handle whitespace */ needFinishWord = true; if (keyCode == '#') { part = part + ' '; } needClear = true; } else { /** * 5. handle standard '2'-'9' keys */ if (Logging.REPORT_LEVEL <= Logging.INFORMATION) { Logging.report(Logging.INFORMATION, LogChannels.LC_HIGHUI, " **is key to process**"); } if (isValidKey(keyCode)) { processKeyCode(keyCode); } else { if (Logging.REPORT_LEVEL <= Logging.INFORMATION) { Logging.report(Logging.INFORMATION, LogChannels.LC_HIGHUI, "invalid key, returning KEYCODE_NONE."); } gotoNextState = false; } } /** * Call StringDiff.nextState() method with the next resulting entry * output StringDiff will check if the underlying entry changed and * will invoke the InputMethodClient with the differences. */ if (gotoNextState) { diff.nextState(part); if (needClear) { clear(); } } if (needFinishWord) { finishWord(); } return ret; } /** * return the pending char * used to bypass the asynchronous commit mechanism * e.g. to immediately commit a char before moving the cursor * @return return the pending char */ public char getPendingChar() { return 0; } /** * Process a new key in range '2'-'9'. * Advnace the iterator and update the word part * * @param keyCode char in range '0'-'9','#', '*' */ void processKeyCode(int keyCode) { if (Logging.REPORT_LEVEL <= Logging.INFORMATION) { Logging.report(Logging.INFORMATION, LogChannels.LC_HIGHUI, "[processKeyCode] keyCode=" + keyCode); } iterator.nextLevel(keyCode); if (iterator.hasNext()) { part = iterator.next(); if (Logging.REPORT_LEVEL <= Logging.INFORMATION) { Logging.report(Logging.INFORMATION, LogChannels.LC_HIGHUI, "iterator.hasNext = true\n" + "iterator part\n" + " :) [processKeyCode] iterator.hasNext: part=" + part);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?