We could try to use a web forums approach:
- allow users to input ASCII codes for emoticons
- in message edit mode show emoticons as a text codes
- in message history show emoticons as images (use BrowserField for this purpose)
- use additional html formatting
Try this code:
public final class ChatScreen extends MainScreen implements FieldChangeListener {
static final int INT_MSG_MAX_LEN = 200;
static final DateFormat FRMT_TIME = DateFormat
.getInstance(DateFormat.TIME_SHORT);
static final String STR_FRMT_IMG = "<img src="{0}"></img>";
static final String STR_FRMT_MSG = "<b>{0}</b> [{1}]: {2}</p>";
// several emoticon ASCII codes
static final String STR_CODE_SMILE = ":)";
static final String STR_CODE_SADSMILE = ":(";
static final String STR_CODE_WINK = ";)";
// use emoticons from http://www.skypeemoticonslist.com
static final String STR_IMG_URL = "http://www.skypeemoticonslist.com/images/";
static final String STR_IMG_NAME_SMILE = "emoticon-0100-smile.png";
static final String STR_IMG_NAME_SADSMILE = "emoticon-0101-sadsmile.png";
static final String STR_IMG_NAME_WINK = "emoticon-0105-wink.png";
static final Hashtable TABLE_URL = new Hashtable();
static final Hashtable TABLE_IMG = new Hashtable();
private static void initCode(String code, String imgFName) {
String tag;
// prepare table for online use
// generate img tag with live url
tag = MessageFormat.format(STR_FRMT_IMG, new Object[] { STR_IMG_URL
+ imgFName });
TABLE_URL.put(code, tag);
// prepare table for offline use
// retrieve image from project resources
try {
EncodedImage img = EncodedImage.getEncodedImageResource(imgFName);
// generate img tag with embedded data url
String dataStr = getDataUrl(img.getData(), img.getMIMEType());
tag = MessageFormat.format(STR_FRMT_IMG, new Object[] { dataStr });
TABLE_IMG.put(code, tag);
} catch (IOException e) {
System.out.println("
Troubles preparing res for code " + code
+ "
");
}
}
static {
initCode(STR_CODE_SMILE, STR_IMG_NAME_SMILE);
initCode(STR_CODE_SADSMILE, STR_IMG_NAME_SADSMILE);
initCode(STR_CODE_WINK, STR_IMG_NAME_WINK);
}
boolean mIsOffline = true;
String mChatHistory = "";
BrowserField mBrowserField = new BrowserField();
EditField mTextField = new EditField("Input message: ", "",
INT_MSG_MAX_LEN, Field.USE_ALL_WIDTH);
ButtonField mBtnUserLeft = new ButtonField("Send as Mr. Left",
Field.FIELD_LEFT | ButtonField.CONSUME_CLICK);
ButtonField mBtnUserRight = new ButtonField("Send as Mr. Right",
Field.FIELD_RIGHT | ButtonField.CONSUME_CLICK);
public ChatScreen() {
super(Manager.NO_VERTICAL_SCROLL | Manager.NO_HORIZONTAL_SCROLLBAR);
add(mTextField);
HorizontalFieldManager hfm = new HorizontalFieldManager(
Field.USE_ALL_WIDTH | Field.FIELD_HCENTER);
mBtnUserLeft.setChangeListener(this);
mBtnUserRight.setChangeListener(this);
hfm.add(mBtnUserLeft);
hfm.add(mBtnUserRight);
add(hfm);
VerticalFieldManager vfm = new VerticalFieldManager(Field.USE_ALL_WIDTH
| Manager.VERTICAL_SCROLL | Manager.VERTICAL_SCROLLBAR);
vfm.add(mBrowserField);
add(vfm);
}
protected void makeMenu(Menu menu, int instance) {
menu.add(new MenuItem(mIsOffline ? "Go Online" : "Go Offline", 0, 0) {
public void run() {
mIsOffline = !mIsOffline;
}
});
super.makeMenu(menu, instance);
}
public void fieldChanged(final Field field, int context) {
if (field == mBtnUserLeft) {
addMessage("Mr. Left");
} else if (field == mBtnUserRight) {
addMessage("Mr. Right");
}
}
private void addMessage(String userName) {
String message = mTextField.getText();
// update message with emoticons
message = replaceCodeWithImg(message, STR_CODE_SMILE);
message = replaceCodeWithImg(message, STR_CODE_SADSMILE);
message = replaceCodeWithImg(message, STR_CODE_WINK);
String timeStr = FRMT_TIME.format(new Date(System.currentTimeMillis()));
String text = MessageFormat.format(STR_FRMT_MSG, new Object[] {
userName, timeStr, message });
mChatHistory = text + mChatHistory;
mTextField.setText("");
// fix IllegalStateException up to
// http://supportforums.blackberry.com/t5/Java-Development/IllegalStateException-at-displayContent-on-browserfield/td-p/1071991
mBrowserField.setFocus();
mBrowserField.displayContent("<html>" + mChatHistory + "</html>", "");
}
private String replaceCodeWithImg(String message, String code) {
Hashtable table = mIsOffline ? TABLE_IMG : TABLE_URL;
int index = message.indexOf(code);
while (index != -1) {
String begin = message.substring(0, index);
String end = message.substring(index + code.length());
String tag = (String) table.get(code);
message = begin + tag + end;
index = message.indexOf(code, index + tag.length());
}
return message;
}
// src taken from http://bfo.com/blog/files/src/DataStreamHandler.java
private static final String getDataUrl(byte[] data, String mimetype)
throws IOException {
final StringBuffer sb = new StringBuffer();
sb.append("data:");
sb.append(mimetype);
sb.append(";base64,");
OutputStream out = new OutputStream() {
public void write(int c) {
sb.append((char) (c & 0xFF));
}
};
Base64OutputStream fout = new Base64OutputStream(out);
fout.write(data);
fout.close();
return sb.toString();
}
}
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…