Monday, October 13, 2008

A better Alert

Alert is a good screen for short messages like: "Settings saved", "Restored default values", "Network error", etc. A TextBox can only be used for user input. If you want to show a help text, with multiple lines, there is another way. On a previous post I showed a way to use Font.stringWidth, now we will see one more.
Assume you have the following attributes:

String [] message;
int messageFirstLineShown;
Command nextCommand;

First you will have to break your message in lines that fit the screen.

char[] chars = ("My long text that will not fit the screen with just one line.\n"
    + "Second line.\nThird line").toCharArray();
StringBuffer buffer = new StringBuffer();
Vector vLines = new Vector();

for (int i = 0; i < chars.length; i++) {
  if (chars[i] == ' ' || chars[i] == '.') {
  String s = buffer.toString();
  // filled a line
  if (Font.getDefaultFont().stringWidth(s) > getWidth()) {
  vLines.addElement(s.substring(0, s.lastIndexOf(' ')));
  buffer.setLength(0);
  buffer.append(s.substring(s.lastIndexOf(' ') + 1));
  }
  buffer.append(chars[i]);
  } else if (chars[i] == '\n') {
  vLines.addElement(buffer.toString());
  buffer.setLength(0);
  } else {
  buffer.append(chars[i]);
  }
}
vLines.addElement(buffer.toString());
this.message = new String[vLines.size()];
vLines.copyInto(this.message);
this.messageFirstLineShown = 0;

When the time comes when you need to paint the message, use the following code:

int y = 0;
for (int i = this.messageFirstLineShown; i < message.length; i++) {
    g.drawString(this.message[i], 0, y, Graphics.LEFT | Graphics.TOP);
    y += g.getFont().getHeight();
}

If you have more lines in message than the screen can show, you will need to add a nextCommand = Command("Next", Command.OK, 1)  to increase the value of messageFirstLineShown.
To know if this is the case check if ((getHeight() / Font.getDefaultFont().getHeight()) > message.length) and at commandAction add the following treatment:

int maxLines = this.getHeight() / Font.getDefaultFont().getHeight();
int remainingLines = this.message.length - this.messageFirstLineShown;

this.messageFirstLineShown += maxLines;
if (remainingLines < maxLines) {
    this.removeCommand(nextCommand);
}

No comments: