📄 textfieldpopup.java
字号:
// Copyright (c) 2005 Sony Ericsson Mobile Communications AB
//
// This software is provided "AS IS," without a warranty of any kind.
// ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
// INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
// PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED.
//
// THIS SOFTWARE IS COMPLEMENTARY OF JAYWAY AB (www.jayway.se)
package com.ultrapower.gui.popup;
import java.util.Timer;
import java.util.TimerTask;
import javax.microedition.lcdui.Alert;
import javax.microedition.lcdui.AlertType;
import javax.microedition.lcdui.Canvas;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Font;
import javax.microedition.lcdui.Graphics;
import com.ultrapower.Device;
import com.ultrapower.Resources;
import com.jmobilecore.ui.core.PlatformCanvas;
import com.jmobilecore.ui.core.Style;
import com.jmobilecore.ui.core.TextFieldComposer;
/**
* <p>
* The <code>Popup</code> represents a popup with text and zero or many
* alternatives that user can select among. A popup can be shown for a
* specific amount of time or forever, the latter case requiring a user to close
* the popup. The choice of the alternatives can be reported by implementing
* a <code>PopupListener</code>
* </p><p>
* This class contains all functionality of a popup, i.e. interaction,
* graphics and callback.
* </p>
*
* @author Peter Andersson
*/
public class TextFieldPopup extends Popup
{
/** Preset alternative containing OK */
public static final char[][] ALT_OK;
/*
* 输入框当前支持两种输入:
* 一,用户bloglines邮件名的输入
*/
public static final char[][] ALT_LOGIN_USERMAIL;
/*
* 输入框当前支持两种输入:
* 二,用户bloglines登录密码的输入
*/
public static final char[][] ALT_LOGIN_USERPASS;
// Setup preset alternatives
static
{
ALT_OK = new char[1][];
ALT_OK[0] = Resources.getChars(Resources.TXT_OK);
ALT_LOGIN_USERMAIL = new char[1][];
ALT_LOGIN_USERMAIL[0] = Resources.getChars(Resources.TXT_OK);
ALT_LOGIN_USERPASS = new char[1][];
ALT_LOGIN_USERPASS[0] = Resources.getChars(Resources.TXT_OK);
}
/** The text to show in the popup */
protected char[] m_text;
/** Number of alternatives to select in popup */
protected byte m_alternatives;
/** Array of texts as chararrays in alternatives */
protected char[][] m_altTexts;
/** Time out in seconds */
protected byte m_timeOut;
/** Alternative reported back if timeout is reached */
protected byte m_timeOutAlt;
/** Current alternative index */
protected byte m_curAlt;
/** Listener to this popup */
protected PopupListener m_listener;
/** Flag indicating if popup is active */
protected volatile boolean m_active = true;
/** Width of popup */
protected int m_w;
/** Height of popup */
protected int m_h;
/**
* Indices indicating where to break the text organized as [line][0 = start
* char offset | 1 = char len]
*/
protected int[][] m_breakTextData;
/** Number of visible text lines in popup */
protected int m_visibleLines;
/** Current line offset */
protected int m_curLine;
/** Maximum line offset */
protected int m_maxLine;
/** Horizontal coordinate offset of text */
protected int m_yoffset;
/** The life time of this popup */
protected long m_endTime;
private Display m_display;
// Graphical data
protected Font m_font = Font.getFont(Font.FACE_MONOSPACE, Font.STYLE_BOLD,
Font.SIZE_LARGE);
protected int m_fontHeight = m_font.getHeight();
/*
* 边框的颜色,0xdd0000是红色
*/
protected int m_borderColor = 0xd6ffff;//0xdd0000;
/*
* 对话框的背景透明色,0xcc440000不要随便改,0x65ee0000是粉红色,0x65440000是深绿色
*/
protected int m_backgroundColor = 0x65440000;
/*
* 对话框内文本的字体颜色,0xffffff是白色
*/
protected int m_textColor = 0xffffff;
protected int m_alternativeColor = 0xfffff0;
protected int m_selectedAlternativeColor = 0xffffff;
/*
* 对话框的编辑框背景透明色,0x65ee0000是粉红色
*/
protected int m_textFieldBackgroundColor = 0x32ff0000;
/*
* 对话框的确定按钮背景透明色,0x65ee0000是粉红色
*/
protected int m_buttonBackgroundColor = 0x65ee0000;
protected static int[] m_rgbData;
protected static int[] m_rgbTextFieldData;
protected static int[] m_rgbButtonData;
/**
* Space between actual popup graphics and the rectangle reported in method
* <code>init</code>
*/
protected static final int OFFSET_POPUP = 8;
/** Space between popup edges and text content */
protected static final int OFFSET_TEXT = 2;
/** Space between alternative texts */
protected static final int OFFSET_ALT = 4;
/** Scrollbar width */
protected static final int SB_WIDTH = 5;
/** Textbreak constants */
protected static final char[] TEXTBREAKS =
{ ' ', '?', ';', ',', '.', '!',
':', '-', '=', '(', ')', '[', ']' };
/** New line constant */
protected static final char NEWLINE = '\n';
/**
* Handles input of the phone keys
* zhengyun 20051220 added
*/
protected TextFieldComposer composer;
protected int maxTextLen = 22;
/*
* 点击确认按钮之后要产生的事件ID,zhengyun added 20051227
*/
protected int m_clickEventID;
/**
* Creates an uninitialized popup. Call <code>init</code> to setup
* this popup instance. This constructor is used for instance cache
* functionality.
*/
public TextFieldPopup() {}
/**
* Initializes this popup.
*
* @param text The text to show in popup.
* @param altTexts The alternatives to select among or null if no choices.
* @param timeOut Time out for this popup in seconds (0 means no timeout).
* @param defaultAlt Index of default alternative.
* @param timeOutAlt Alternative index reported on time out.
* @param clickEventID 点击确认按钮之后要产生的事件ID,zhengyun added
* @param listener The popuplistener being reported on selection or timeout or null
* if no listener.
* @param width Canvas width.
* @param height Canvas height.
*/
public void init(Display display, char[] text, char[][] altTexts, byte timeOut,
byte defaultAlt, byte timeOutAlt, int clickEventID, PopupListener listener, int width,
int height)
{
m_display = display;
// Set parameters
m_text = text;
m_altTexts = altTexts;
if (altTexts != null)
{
m_alternatives = (byte) altTexts.length;
}
else
{
m_alternatives = 0;
}
m_timeOut = timeOut;
m_timeOutAlt = timeOutAlt;
m_listener = listener;
m_curAlt = defaultAlt;
m_clickEventID = clickEventID;
m_w = width - (OFFSET_POPUP << 1);
m_h = height - (OFFSET_POPUP << 1);
m_active = true;
if (m_timeOut > 0)
{
// Set timeout
m_endTime = System.currentTimeMillis() + (m_timeOut * 1000);
}
else if (m_alternatives > 0)
{
// No timeout
m_endTime = 0;
}
else
{
// This should never happen - a popup with no alternatives and no timeout
m_endTime = System.currentTimeMillis();
}
/*
* Math库没有,必须把Math.max(1, ((m_h - (OFFSET_TEXT << 1)) / m_fontHeight) - 1)
* 换成if判断的表达方式!
* zhengyun 200501216
*/
int nLines = ((m_h - (OFFSET_TEXT << 1)) / m_fontHeight) - 1;
m_visibleLines = nLines>1 ? nLines:1;
int w = m_w - (OFFSET_TEXT << 1) - (SB_WIDTH << 1);
m_curLine = 0;
m_breakTextData = breakString(text, w);
// Calculate height
m_yoffset = 0;
m_maxLine = m_breakTextData.length - m_visibleLines + 1;
if (m_breakTextData.length < m_visibleLines)
{
int newH = m_breakTextData.length * m_fontHeight;
if (m_alternatives > 0)
newH += m_fontHeight;
newH += OFFSET_TEXT + OFFSET_ALT;
m_yoffset = (m_h - newH) >> 1;
m_h = newH;
}
// Create transparent rgb buffer if needed (8 lines)
if (m_rgbData == null || m_rgbData.length != m_w * 8)
{
m_rgbData = new int[m_w * 8];
for (int i = 0; i < m_rgbData.length; i++)
{
m_rgbData[i] = m_backgroundColor;
}
}
////////////////////////////////////////////////////////////////
// 创建文本输入框的透明背景色rgb缓冲区 (4 lines)
// zhengyun 20051220
if (m_rgbTextFieldData == null || m_rgbTextFieldData.length != m_w * 4)
{
m_rgbTextFieldData = new int[m_w * 4];
for (int i = 0; i < m_rgbTextFieldData.length; i++)
{
m_rgbTextFieldData[i] = m_textFieldBackgroundColor;
}
}
// 创建按钮的透明背景色rgb缓冲区 (4 lines)
// zhengyun 20051220
if (m_rgbButtonData == null || m_rgbButtonData.length != m_w * 4)
{
m_rgbButtonData = new int[m_w * 4];
for (int i = 0; i < m_rgbButtonData.length; i++)
{
m_rgbButtonData[i] = m_buttonBackgroundColor;
}
}
/*
* 创建接收输入字符串的缓冲区*/
composer = new TextFieldComposer(maxTextLen);
// 初始化输入规则
initValidChars(C_EMAIL);
//////////////////////////////////////////////////////////////
// Start poll thread
Thread thread;
( thread = new Thread(this)).start();
/*
* 实践发现,这里的声明Thread.start不能像原来的new Thread(this, "PopupPoll").start();
* 一句话了事,好像这种语句在nokia上跑不起来!气愤!
* 切记!
* zhengyun 20051216
*/
}
/**
* Returns the text that is presented by this text component.
* zhengyun 20051220 added
*/
public String getText() {
return composer.getText();
}
/**
* Sets the text that is presented by this
* text component to be the specified text.
* zhengyun 20051220 added
*
* @param newText the new text.
*/
public void setText(String newText) {
composer.setText(newText);
}
/**
* Gets current input composer
* zhengyun 20051220 added
*/
protected TextFieldComposer getComposer() {
return composer;
}
/**
* Breaks specified character array and returns a break matrix by line,
* organized as [line][0 | 1] where 0 means starting offset in text for this
* line, 1 means number of characters of this line.
*
* @param text The string to break
* @param width Width in pixels to break on
* @return A break index table
*/
protected int[][] breakString(char[] text, int width)
{
// Count text lines
int offset = 0;
int lines = 0;
int newOffset;
while (offset < text.length)
{
newOffset =
findNextBreak(text, offset, text.length - offset, width, m_font);
offset = newOffset;
lines++;
}
int[][] indices = new int[lines][2];
// Setting offset data
lines = 0;
offset = 0;
while (offset < text.length)
{
newOffset =
findNextBreak(text, offset, text.length - offset, width, m_font);
indices[lines][0] = offset;
indices[lines][1] = newOffset - offset;
lines++;
offset = newOffset;
}
return indices;
}
/**
* Returns next break when breaking a string.
*
* @param text The chars to calculate on
* @param offset From what offset to read in chars
* @param len How many characters to read
* @param w Width
* @param f Font
* @return Offset of next break or length of text if no more breaks
*/
public int findNextBreak(char[] text, int offset, int len, int w, Font f)
{
int breakOffset = offset;
int textW = 0;
int niceB = -1;
char c;
charLoop: while (breakOffset <= offset + len && textW < w)
{
if (breakOffset == offset + len)
c = TEXTBREAKS[0]; // last character + 1, fake break char
else
c = text[breakOffset];
if (c == NEWLINE)
{
// got a nice break here, new line
niceB = breakOffset;
break charLoop;
}
// Try finding break charachters
breakCharLoop:
for (int i = TEXTBREAKS.length - 1; i >= 0; i--)
{
if (c == TEXTBREAKS[i])
{
niceB = breakOffset;
break breakCharLoop;
}
}
if (breakOffset == offset + len - 1)
{
// Special case, skip the last character
niceB = breakOffset + 1;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -