21.06 Ein Low-Level Informations Bildschirm
Die Klasse TextTools
package de.jbb.info;
import javax.microedition.lcdui.Font;
public class TextTools {
public static String[] getViewableTextLines(String text, Font f, int width) {
String[] ret = new String[f.stringWidth(text) / (width - f.stringWidth("012345")) + 1];
if (ret.length == 1) {
return new String[]{text};
}
int arPos = 0;
for (int curPos = 0, lastCut = 0, lastAcceptPos = 0, lastWord = 0;;) {
if (arPos >= ret.length) {
String[] tmp = new String[ret.length + 1];
System.arraycopy(ret, 0, tmp, 0, ret.length);
ret = tmp;
}
lastWord = curPos;
curPos = text.indexOf(' ', curPos + 1);
if (curPos < 0) {
if (f.substringWidth(text, lastCut, text.length() - lastCut) < width
|| lastCut == lastAcceptPos) {
ret[arPos] = text.substring(lastCut);
break;
}
else {
ret[arPos++] = text.substring(lastCut, lastAcceptPos);
lastCut = lastAcceptPos;
curPos = lastCut;
}
}
else {
if (f.substringWidth(text, lastCut, curPos - lastCut) < width) {
lastAcceptPos = curPos + 1;
}
else if (lastAcceptPos != lastCut) {
ret[arPos++] = text.substring(lastCut, lastAcceptPos);
lastCut = lastAcceptPos;
}
else {
ret[arPos++] = text.substring(lastCut, lastWord);
curPos = lastWord;
lastAcceptPos = curPos + 1;
lastCut = lastAcceptPos;
}
}
}
if (arPos + 1 != ret.length) {
String[] tmp = new String[arPos + 1];
System.arraycopy(ret, 0, tmp, 0, tmp.length);
ret = tmp;
}
return ret;
}
}
Der InfoScreen
package de.jbb.info;
import javax.microedition.lcdui.Canvas;
import javax.microedition.lcdui.Font;
import javax.microedition.lcdui.Graphics;
public class InfoScreen extends Canvas {
private String[] heads;
private String[][] txts;
private Font font;
private int backgroundColor;
private int backgroundHeadColor;
private int foregroundColor;
private int foregroundHeadColor;
private int scrollColor;
private int scrollBarColor;
private int maxHeight;
private int curY;
private int lastY;
public InfoScreen(String[] heads, String[] txts, Font font) {
if (heads.length != txts.length) {
throw new IllegalArgumentException("heads.length and txts.length must be equal");
}
this.font = font;
this.heads = heads;
this.txts = new String[txts.length][0];
int txtLineCount = 0;
for (int i = 0; i < txts.length; i++) {
this.txts[i] = TextTools.getViewableTextLines(txts[i], font, getWidth() - 15);
txtLineCount += this.txts[i].length;
}
this.maxHeight = (font.getHeight() + 2) * (heads.length + txtLineCount);
}
protected void paint(Graphics g) {
int curHeight = this.curY;
g.setColor(this.backgroundColor);
g.fillRect(0, 0, getWidth(), getHeight());
g.setFont(font);
for (int i = 0; i < this.heads.length; i++) {
curHeight = drawHeadline(g, this.heads[i], curHeight);
curHeight = drawText(g, this.txts[i], curHeight);
}
if (this.maxHeight > getHeight()) {
g.setColor(this.scrollColor);
g.fillRect(getWidth() - 5, 0, 4, getHeight());
g.setColor(this.scrollBarColor);
g.fillRect(
getWidth() - 5,
(-this.curY * 100) / ((this.maxHeight * 100) / getHeight()),
4,
(getHeight() * 100) / ((this.maxHeight * 100) / getHeight())
);
}
}
private int drawHeadline(Graphics g, String head, int curHeight) {
g.setColor(this.backgroundHeadColor);
g.fillRect(0, curHeight, getWidth() - 5, g.getFont().getHeight() + 2);
g.setColor(this.foregroundHeadColor);
g.drawString(head, 5, curHeight, Graphics.LEFT | Graphics.TOP);
curHeight += g.getFont().getHeight() + 2;
return curHeight;
}
private int drawText(Graphics g, String[] text, int curHeight) {
g.setColor(this.foregroundColor);
for (int i = 0; i < text.length; i++) {
g.drawString(text[i], 5, curHeight, Graphics.LEFT | Graphics.TOP);
curHeight += g.getFont().getHeight() + 2;
}
return curHeight;
}
protected void keyPressed(int keyCode) {
doStep(keyCode);
}
protected void keyRepeated(int keyCode) {
doStep(keyCode);
}
protected void pointerPressed(int x, int y) {
this.lastY = y;
}
protected void pointerDragged(int x, int y) {
if (this.lastY != y) {
this.curY += y - this.lastY;
if (this.curY > 0) {
this.curY = 0;
}
else if (this.curY < getHeight() - this.maxHeight) {
this.curY = getHeight() - this.maxHeight;
}
this.lastY = y;
repaint();
}
}
private void doStep(int keyCode) {
if (this.maxHeight > getHeight()) {
if (keyCode == KEY_NUM2 || getGameAction(keyCode) == UP) {
this.curY += font.getHeight();
if (this.curY > 0) {
this.curY = 0;
}
repaint();
}
else if (keyCode == KEY_NUM8 || getGameAction(keyCode) == DOWN) {
this.curY -= font.getHeight();
if (this.curY < getHeight() - this.maxHeight) {
this.curY = getHeight() - this.maxHeight;
}
repaint();
}
}
}
public int getBackgroundColor() {
return this.backgroundColor;
}
public void setBackgroundColor(int backgroundColor) {
this.backgroundColor = backgroundColor;
}
public int getBackgroundHeadColor() {
return this.backgroundHeadColor;
}
public void setBackgroundHeadColor(int backgroundHeadColor) {
this.backgroundHeadColor = backgroundHeadColor;
}
public int getForegroundColor() {
return this.foregroundColor;
}
public void setForegroundColor(int foregroundColor) {
this.foregroundColor = foregroundColor;
}
public int getForegroundHeadColor() {
return this.foregroundHeadColor;
}
public void setForegroundHeadColor(int foregroundHeadColor) {
this.foregroundHeadColor = foregroundHeadColor;
}
public int getScrollBarColor() {
return this.scrollBarColor;
}
public void setScrollBarColor(int scrollBarColor) {
this.scrollBarColor = scrollBarColor;
}
public int getScrollColor() {
return this.scrollColor;
}
public void setScrollColor(int scrollColor) {
this.scrollColor = scrollColor;
}
}
Ein Beispiel-MIDlet
package de.jbb.info;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Font;
import javax.microedition.midlet.*;
public class InfoMIDlet extends MIDlet implements CommandListener {
private boolean first = true;
private Display disp;
private Command exit;
private InfoScreen info;
public void startApp() {
if (first) {
String[] heads = {
"Info",
"Verwendung",
"Copyright"
};
String[] txts = {
"Dies ist ein Informationsbildschirm, der für Low-Level Java ME " +
"Anwendungen genutzt werden kann. Er ermöglicht die Darstellung " +
"von viel Text mit jeweils einer Überschrift. Ist der Text zu " +
"groß für das Display, kann auch mit den Richtungstasten oder " +
"'2' und '8' gescrollt werden.",
"Der InfoScreen ist ein gewöhnliches Canvas, welchem im Konstruktor " +
"als ersten Parameter die Überschriften, und als zweiten Parameter " +
"die eigentlichen Texte zu den Überschriften übergeben werden.",
"Java-Blog-Buch.de, Stefan Kiesel, 2010"
};
disp = Display.getDisplay(this);
exit = new Command("Beenden", Command.EXIT, 0);
info = new InfoScreen(heads, txts, Font.getFont(Font.FONT_STATIC_TEXT));
info.addCommand(exit);
info.setCommandListener(this);
info.setBackgroundColor(0); // Schwarz
info.setBackgroundHeadColor(255 << 16 | 255 << 8 | 255); // Weiß
info.setForegroundColor(info.getBackgroundHeadColor());
info.setForegroundHeadColor(info.getBackgroundColor());
info.setScrollColor(200 << 16 | 200 << 8 | 200); // helles Grau
info.setScrollBarColor(50 << 16 | 50 << 8 | 50); // dunkles Grau
first = false;
}
disp.setCurrent(info);
}
public void commandAction(Command c, Displayable d) {
destroyApp(true);
}
public void destroyApp(boolean unconditional) {
notifyDestroyed();
}
public void pauseApp() {}
}
Pages: 1 2