📄 textfield.java
字号:
package com.jmobilecore.ui.core;
import javax.microedition.lcdui.Graphics;
/**
* A <code>TextField</code> object is a text component
* that allows for the editing of a single line of text.
*
* @author Greg Gridin
*/
public class TextField extends TextComponent {
/**
* The total vertical gap for textfield text
*/
protected final static int VOFFSET = BORDER_WIDTH + BORDER_GAP + Style.V_GAP;
/**
* The total horizontal gap for textfield text
*/
protected final static int HOFFSET = BORDER_WIDTH + BORDER_GAP + Style.H_GAP;
/**
* Default text size
*/
static public final int DEFAULT_SIZE = 10;
/**
* Handles input of the phone keys
*/
protected AbstractComposer composer;
/**
* The echo character, which is used when
* the user wishes to disguise the characters
* typed into the text field.
* The disguises are removed if echoChar = <code>0</code>.
*/
public char echoChar = 0;
public int adjustment = 0;
protected static final boolean SCROLLABLE = false;
/**
* Constructs a new text field.
*/
public TextField() {
this(DEFAULT_SIZE);
}
/**
* Constructs a new text field with the specified length.
*
* @param maxTextLen the maximum text length
*/
public TextField(int maxTextLen) {
this(maxTextLen, C_ANY);
}
/**
* Constructs a new text field with the specified length and constraints.
*
* @param maxTextLen the maximum text length
* @param constr constraints binary mask
* @see TextComponent
*/
public TextField(int maxTextLen, int constr) {
super(constr);
focusedForeground = Style.FOCUSED_TEXT_COLOR;
foreground = Style.TEXT_COLOR;
init(maxTextLen);
setText(null);
}
protected void init(int maxTextLen) {
setFont(Style.TEXT_FIELD_FONT);
if (maxTextLen > 0) {
composer = new TextFieldComposer(maxTextLen);
}
}
/**
* Returns the text that is presented by this text component.
*/
public String getText() {
return composer.getText();
}
/**
* Sets the text that is presented by this
* text component to be the specified text.
*
* @param newText the new text.
*/
public void setText(String newText) {
composer.setText(newText);
}
/**
* Gets current input composer
*/
protected AbstractComposer getComposer() {
return composer;
}
/**
* Adjusts the cursor position
*/
protected void adjust(char[] text, int caretPosition, int cursorOffset) {
if (text == null) return;
final int realWidth = getWidth() - 2 * TextField.HOFFSET;
final int realWidth3 = realWidth / 3;
if (cursorOffset < 0) {
adjustment -= realWidth3;
if (adjustment < 0) adjustment = 0;
} else {
final int adjWidth = realWidth - ((caretPosition == text.length) ? 0 : font.charWidth('W'));
if (cursorOffset > adjWidth) {
adjustment += realWidth3;
}
}
}
protected int calculatedCaretPosition;
protected int calculatedCursorOffset;
protected int currentLength;
protected char[] getFormattedText(boolean calcCursorOffset) {
char[] formattedText;
currentLength = composer.getCurrentLength();
if (echoChar != 0) {
formattedText = new char[currentLength];
for (int i = 0; i < currentLength; i++) {
formattedText[i] = echoChar;
}
} else {
formattedText = composer.getChars();
}
if (calcCursorOffset) {
calculatedCaretPosition = composer.getCaretPosition();
calculatedCursorOffset = getCursorOffset(formattedText, calculatedCaretPosition);
}
return formattedText;
}
/**
* Paints the component
*
* @param g Graphics object
*/
public void paint(Graphics g) {
paintBackground(g);
int height = getHeight();
int width = getWidth();
g.setColor(Style.BORDER_COLOR);
g.drawRect(0, screenY, width - 1, height - 1);
prepareForeground(g);
char[] text = getFormattedText(SCROLLABLE || isFocusOwner());
int cursorOffset = calculatedCursorOffset;
int caretPosition = calculatedCaretPosition;
int curLen = currentLength;
if (SCROLLABLE) {
adjust(text, caretPosition, cursorOffset);
}
if (text.length != 0) {
int y = screenY + VOFFSET;
g.setClip(HOFFSET, screenY, width - HOFFSET, height - 1);
int textOffset = HOFFSET - adjustment;
if (alignment == LEFT || isFocusOwner()) {
g.drawChars(text, 0, curLen, textOffset, y, Graphics.TOP | Graphics.LEFT);
} else if (alignment == RIGHT) {
g.drawChars(text, 0, curLen, width - textOffset, y, Graphics.TOP | Graphics.RIGHT);
} else if (alignment == CENTER) {
g.drawChars(text, 0, curLen, width / 2 - textOffset, y, Graphics.TOP | Graphics.HCENTER);
}
}
g.setClip(0, 0, ScreenCanvas.WIDTH, ScreenCanvas.HEIGHT);
if (isFocusOwner()) paintCursor(g, text, caretPosition, cursorOffset, insertMode?CURSOR_TYPE_LINE:CURSOR_TYPE_SYMBOL);
}
/**
* Calculates the height of the component.
*/
protected void setHeight() {
this.height = font.getHeight() + 2 * Style.V_GAP +
BORDER_WIDTH * 2 + BORDER_GAP * 2;
}
/**
* Returns the cursor offset (in pixels) for the composed string
*/
public int getCursorOffset(char[] text, int caretPosition) {
int offset = HOFFSET - adjustment;
if (echoChar == 0) {
return offset + getFont().charsWidth(text, 0, caretPosition);
} else {
return offset + getFont().charWidth(echoChar) * caretPosition;
}
}
/**
* Paints the cursor for this component
*
* @param g Graphics object
*/
protected void paintCursor(Graphics g, char[] text, int caretPosition, int cursorOffset, byte cursorType) {
final int cY = screenY + VOFFSET;
final int rh = font.getHeight();
g.setColor(Style.CURSOR_BACKGROUND_COLOR);
if (cursorType==CURSOR_TYPE_SYMBOL) {
final char ch = text[caretPosition];
final int cw = font.charWidth(ch);
g.fillRect(cursorOffset, cY, cw + 1, rh);
g.setColor(Style.CURSOR_TEXT_COLOR);
g.setClip(cursorOffset, cY, cw, rh);
g.drawChar(ch, cursorOffset, cY, Graphics.TOP | Graphics.LEFT);
g.setClip(0, 0, ScreenCanvas.WIDTH, ScreenCanvas.HEIGHT);
} else
g.fillRect(cursorOffset, cY, 1, rh);
}
/**
* Responds to a key press.
* <p/>
* If the key is a number key and the constraint is {@link TextComponent#C_NUMERIC} only,
* no timing interval is used, the number is immediately inserted into the
* field (if there is room).
* If the key is a number key and the constraint IS NOT ONLY {@link TextComponent#C_NUMERIC},
* the timing interval begins so that
* characters may be cycled through via repeated presses of the same key
* within the timing interval.
* <p/>
* Presses of the left and right sides of the 4-way navigation key move the
* cursor one character left or right within the field. Pressing the <b>*</b>
* key deletes the character to the left of the cursor. Pressing the <b>#</b>
* key inserts a space at the cursor position.
* <p/>
* You can override this method if you want a custom component to perform
* additional filtering of key presses. For example, if you want a field that
* accepts only odd digits you could extend this class, ensure it is
* {@link TextComponent#C_NUMERIC}, then in this method check that the pressed key is an odd
* digit before passing it to the parent's <code>keyPressed</code> method.
*
* @param keyCode The code for the key that was pressed.
* @return <code>true</code> if the key was successfully processed, <code>false</code> otherwise
*/
synchronized public boolean keyPressed(int keyCode) {
boolean bRes = false;
resetCursor();
if (!insertMode && preProcessKeyCode(keyCode)) {
composer.caretRight();
}
final boolean curInsertMode = insertMode;
if (keyCode == PlatformCanvas.KEY_LEFT) {
bRes = composer.caretLeft();
}
if (keyCode == PlatformCanvas.KEY_RIGHT) {
bRes = composer.caretRight();
}
if (editable) {
if (keyCode == PlatformCanvas.KEY_STAR || keyCode == PlatformCanvas.KEY_CLEAR) {
bRes = composer.backspace();
}
if (keyCode == PlatformCanvas.KEY_POUND || (keyCode >= PlatformCanvas.KEY_NUM0 && keyCode <= PlatformCanvas.KEY_NUM9)) {
char ch = processKeyCode(keyCode);
if (ch == 0) return false;
bRes = composer.addChar(ch, curInsertMode);
if (insertMode) composer.caretRight();
}
}
if (bRes) {
parentScreen.repaint();
}
initCursor();
lastKeyCode = keyCode;
return bRes;
}
public void destructor() {
composer.destructor();
composer = null;
super.destructor();
}
} // class TextField
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -