📄 inputbox.java
字号:
package com.podome.ui;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;
import javax.microedition.lcdui.TextBox;
import javax.microedition.lcdui.TextField;
import com.podome.log.Logger;
import com.podome.style.Style;
import com.podome.tool.Config;
import com.podome.tool.EffectHelper;
import com.podome.tool.Key;
public class InputBox extends UIBase implements EventDispatch{
/**
* 键盘布局数字字母表
*/
private static byte[][] letter = {
{ 48 },
{ 49 }, // 0,1
{ 50, 97, 98, 99, 65, 66, 67 }, // 2abcABC
{ 51, 100, 101, 102, 68, 69, 70 }, // 3defDEF
{ 52, 103, 104, 105, 71, 72, 73 },
{ 53, 106, 107, 108, 74, 75, 76 },
{ 54, 109, 110, 111, 77, 78, 79 },
{ 55, 112, 113, 114, 115, 80, 81, 82, 83 },
{ 56, 116, 117, 118, 84, 85, 86 },
{ 57, 119, 120, 121, 122, 87, 88, 89, 90 },
{ 42, 64, 45, 46 },
{ 35, 36, 37, 38 }
};
private StringBuffer text; // 字符数组
private int length = 0; // 字符长度
private int cursorPos = -1; // 光标的当前位置
private String hints; // 输入提示字符
private int showLength; // 显示在界面上的最大字符长度
private int maxLength; // 控件可以输入的最大字符个数
private int constraints; // 输入约束
/** ************************************************** */
private long currentTime; // 当前时间
private long interval; // 与前一次的按键时间间隔
private long lastTime; // 最后一次发生按键的时间
private int lastKeyCode;
private int keyRepeatCnt; // 重复按键次数
/** ************************************************** */
private boolean drawCursor = false;
private int cursorInterval = Config.CURSOR_INTERVAL;
/**
* 构造一个可以接受用户输入的界面UI对象
*
* @param len 每行显示的字符个数
*/
public InputBox(int len) {
text = new StringBuffer();
this.setSize(len);
this.setEnable(true);
this.setEditAble(true);
setConstraints(TextField.ANY);
}
/**
* 构造一个可以接受用户输入的界面UI对象
*
* @param len
* 每行可以显示的个数(英文字符)
* @param max
* 最大可以输入的字符个数(英文字符) max 可以小于 len
*/
public InputBox(int len, int max) {
this(len);
this.setMaxSize(max);
}
/**
* @return String
*/
public String getText() {
return text.toString();
}
/**
* @param s
*/
public void setText(String s) {
if (text.length() > 0) {
text.delete(0, text.length());
}
text.append(s);
length = text.length();
cursorPos = length - 1;
}
public void setString(String s){
this.setText(s);
}
/**
* 控件可以显示的字符个数
*
* @param size
*/
private void setSize(int size) {
if (this.showLength != size && size > 0) {
this.showLength = size;
}
}
/**
* 只处理了英文和数字的偏移量
*/
private void setOffset(){
if( this.cursorPos > this.showLength-1 + this.offset ){
this.offset = this.cursorPos - this.showLength + 1;
}
else if( this.cursorPos == -1 && offset > 0 ){
this.offset = 0;
}
else if( this.cursorPos < this.offset-1){
this.offset--;
}
}
/**
*
*/
public void paint(Graphics g) {
//设置偏移值
this.setOffset();
Style s = this.getStyle();
int x = getX();
int y = getY();
int w = bonds[1][0]-bonds[0][0];
int h = bonds[1][1]-bonds[0][1];
Image offImage = Image.createImage(w, h);
Graphics imgGraphics = offImage.getGraphics();
// 画背景
imgGraphics.setColor(hasFocus?s.bColorFocus:s.bColorNormal);
imgGraphics.fillRect(0, 0, w, h );
//画边框
imgGraphics.setColor(hasFocus?s.sColorFocus:s.sColorNormal);
imgGraphics.drawRect(0, 0, w-1, h-1);
// 画文字
imgGraphics.setColor(hasFocus?s.fColorFocus:s.fColorNormal);
imgGraphics.setFont(s.dfont);
imgGraphics.setClip(s.paddingLeft, s.paddingTop, w-s.paddingRight-s.paddingLeft, h);
imgGraphics.drawString(getText().substring(offset), s.paddingLeft, s.paddingTop, Graphics.LEFT | Graphics.TOP);
//设置可见区
if( y + h > owner.vHeight ){
h = owner.vHeight - y;
}
g.setClip(x, y, w, h);
g.drawImage(offImage, x, y, Graphics.TOP | Graphics.LEFT);
if ( drawCursor ) {
if (cursorPos == -1) {
x += 1;
}
String str = getText();
if (str != null && !str.equals("")) {
//Logger.info("Cursor->scrollOffset:" + scrollOffset + "cursorPos:" + this.cursorPos);
str = str.substring(offset, cursorPos + 1);
x = x + 1 + s.dfont.stringWidth(str)+ s.paddingLeft;
}
g.drawLine(x, y + 3, x, y + h - 3);
}
}
//按键事件处理
public void keyPressed(int keyCode) {
Logger.debug("InputBox Deal KeyCode:" + keyCode);
keyEventImpl(keyCode);
//Stage.getInstance().notifyRepaint(this);
}
void keyEventImpl(int keyCode) {
// 先处理left right delete 键
if (keyCode == Key.KEY_LEFT) {
movePre();
return;
} else if (keyCode == Key.KEY_RIGHT) {
moveNext();
return;
} else if (keyCode == Key.KEY_DELETE) {
delete();
return;
} else if (keyCode == Key.KEY_OK) {
Agency agency = new Agency();
agency.show();
}
if( !isValidate(keyCode) ){
return;
}
currentTime = System.currentTimeMillis();
interval = currentTime - lastTime;
if (lastKeyCode != keyCode || interval > Config.KEYREPEAT_INTERVAL) {
// 重新设置计数值和最后按键时间
lastKeyCode = keyCode;
keyRepeatCnt = 0;
append(keyCode);
} else {
keyRepeatCnt++;
replace(keyCode, keyRepeatCnt); // 替换最后一个元素
}
// 重新计时
lastTime = currentTime;
}
/**
* 判断是否合法的键值
* @param code
* @return
*/
private boolean isValidate(int code){
for(int i=0; i< letter.length; i++ ){
for(int k = 0 ; k < letter[i].length; k++ ){
if( letter[i][k] == code ){
return true;
}
}
}
return false;
}
/**
* 获取输入类型
*/
public String getTypeName() {
return "InputBox";
}
/**
* 转到高级界面输入是提示的信息
*
* @param message
*/
public void setHint(String s) {
this.hints = s;
}
public String getHint() {
return this.hints;
}
public int getMaxInputSize() {
return this.maxLength;
}
/**
* 设置最大可输入字符个数(英文个数)
*
* @param len
*/
void setMaxSize(int len) {
if (this.maxLength != len && len > 0)
this.maxLength = len;
}
public int getInputConstraints() {
return this.constraints;
}
void setConstraints(int c) {
this.constraints = c;
}
/**
* 增加一个字符到光标处
*
* @param keyCode
*/
void append(int keyCode) {
if (cursorPos == -1 && length == 0) {
text.append((char) keyCode);
} else if (this.length >= this.maxLength) {
return;
} else {
text.insert(cursorPos + 1, (char) keyCode);
}
length++;
cursorPos++;
}
/**
* 替换掉光标处的一个字符
*
* @param keyCode
* @param cnt
*/
void replace(int keyCode, int cnt) {
int code = getChar(keyCode, cnt);
text.deleteCharAt(cursorPos);
text.insert(cursorPos, (char) code);
}
/**
* 删掉光标所在的一个字符
*/
void delete() {
if (cursorPos == -1)
return;
text.deleteCharAt(cursorPos);
length--;
cursorPos--;
}
/**
* 移动光标到下一个字符处
*/
void moveNext() {
if (cursorPos < length - 1 && length > 0) {
cursorPos++;
}
}
/**
* 移动光标到上一个字符处
*/
void movePre() {
if (cursorPos >= 0) {
cursorPos--;
}
}
/**
* @param keyCode
* 按键ASCII值,0-9
* @param repeatCnt
* 重复次数
* @return
*/
int getChar(int keyCode, int repeatCnt) {
int returnCode = keyCode;
int len = 0;
for (int i = 0; i < letter.length; i++) {
if (letter[i][0] == keyCode) {
len = letter[i].length;
if (len == 1)
break;
returnCode = letter[i][repeatCnt % len];
}
}
return returnCode;
}
public void setFocus(boolean focus) {
if (this.hasFocus != focus) {
this.hasFocus = focus;
if( focus){
this.drawCursor = true;
this.cursorPos = this.length-1;
EffectHelper.addToRepaint(this);
}
else{
this.drawCursor = false;
EffectHelper.removeRepaint(this);
}
Stage.getInstance().notifyRepaint(this);
}
}
public void move(){
if( this.cursorInterval <=0 ){
this.cursorInterval = Config.CURSOR_INTERVAL;
if( this.drawCursor ){
this.drawCursor = false;
}
else{
this.drawCursor = true;
}
Stage.getInstance().notifyRepaint(this);
}
else{
cursorInterval-=Config.SCHEMA_INTERVAL;
}
}
public String toString() {
return this.getString(); // + "X="+ xpos + ",Y=" + ypos;"Width=" +
// width+",Height="+height;
// return getLabel()+":R-->X="+ xpos + ",Y=" + ypos + ",Width=" +
// width+",Height="+height + ",focus:" + hasFocus + "\n" +
// getLabel()+":A-->X="+ getX() + ",Y=" + getY()+",Width=" +
// getWidth()+",Height="+getHeight() + "\n" ;
// "Parent: X=" + owner.getX() + ",Y=" + owner.getY() + "\n";
}
public String getString() {
return this.text.toString();
}
protected void setAutoArea(int x, int y,int maxWidth){
this.setX(x);
this.setY(y);
Style s = this.getStyle();
int w = s.wCharEN * this.showLength + s.paddingLeft + s.paddingRight;
int h = s.dfont.getHeight() + s.paddingTop + s.paddingBottom;
//如过长度超过,则自动减少显示字符个数
if( x + w > maxWidth + owner.getStyle().paddingLeft ){
w = maxWidth + owner.getStyle().paddingLeft - x;
this.showLength = w / s.wCharEN;
}
//Logger.info("X=" + x + ",Y=" + y + "W=" + w + ",OW=" + maxWidth );
bonds[1][0] = bonds[0][0] + w;
bonds[1][1] = bonds[0][1] + h;
this.setLineHeight(h);
}
class Agency extends TextBox implements CommandListener {
Command cmdOK = new Command("确 定", Command.OK, 1);
Command cmdCancel = new Command("取 消", Command.CANCEL, 1);
private Agency() {
super( getHint(), getText(), getMaxInputSize(), getInputConstraints());
this.addCommand(cmdOK);
this.addCommand(cmdCancel);
this.setCommandListener(this);
}
/**
* 显示输入框(高级界面)
*/
private void show() {
Logger.info("show " + getText());
EffectHelper.pause();
Display.getDisplay(Stage.midlet).setCurrent(this);
}
/**
* 返回前一个界面
*/
private void hidde() {
Display.getDisplay(Stage.midlet).setCurrent(Stage.getInstance());
EffectHelper.play();
Stage.getInstance().notifyRepaintCurrent();
}
public void commandAction(Command cmd, Displayable d) {
if (cmd == cmdOK) {
setText( this.getString() );
// 返回前面一个界面
this.hidde();
} else if (cmd == cmdCancel) {
// 返回前面一个界面
this.hidde();
}
}
}
/**
* 可以向下分发事件
* @return
*/
public boolean canDisPatchEvent() {
return true;
}
public void notifyCommand(com.podome.ui.Command cmd) {
// TODO Auto-generated method stub
}
public boolean isActive() {
return true;
}
public boolean responseKeyCode(int keyCode) {
if(keyCode == Key.KEY_UP ||
keyCode == Key.KEY_DOWN )
return false;
else
return true;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -