Automatischer Wortumbruch
Bei der Ausgabe von langen Strings mit println() ist der Zeilenumbruch häufig ungeschickterweise mitten in einem Wort. Das ist unschön und lässt sich durch ein kleines Programm schnell beheben.
Zum Einsatz kommen soll der java.util.StringTokenizer. Er soll dann Texte auf Leerzeichen untersuchen und dann erkennen, ob ein Wort noch in eine Zeile passt. Wenn nicht, soll automatisch eine neue Zeile begonnen werden.
class FormatBlock
{
public static void formatWithTextWith( String s, int len )
{
StringTokenizer st = new StringTokenizer( s, " ", true );
String word;
int currentLineLen = 0;
while ( st.hasMoreTokens() )
{
int wordLen = (word = st.nextToken()).length();
if ( currentLineLen + wordLen <= len )
{
System.out.print( word );
currentLineLen += wordLen;
}
else
{
boolean firstIsSpace = word.charAt(0)==' ';
System.out.println();
System.out.print( (firstIsSpace ? "" : word) );
currentLineLen = firstIsSpace ? 0 : wordLen;
}
}
}
static public void main( String args[] )
{
String s =
"There is a new Word macro virus circulating called Melissa. "+
"The virus propagates via email. Attached to the email is "+
"a Word file that when opened will launch a macro that will "+
"send the same message to the first 50 recipients of your "+
"Outlook address book. The subject line is \"important"+
"Message From <some user name>\". The body consist of the "+
"text \"Here is that document you asked for... don't "+
"show anyone else;-)\". The infected documents contains "+
"passwords to porn web sites.";
for ( int i=0; i < 30; i++ )
System.out.print( '*' );
System.out.println();
formatWithTextWidth( s, 30 );
}
}
Die Methode formatWithTextWidth() ist statisch angelegt und erwartet die Zeichenfolge sowie als zweiten Parameter die Breite der Textspalte. Wir erzeugen dann einen StringTokenizer, dessen einziger Trenner das Leerzeichen ist. Würden wir diesen Delimiter-String nicht neu setzen, könnten wir der Funktion nicht übergeben, die Delimiter auch als Token zu bekommen. So überlesen wir aber auch die Tabulatoren. Die Sonderbehandlung, jeden Tabulator mit einer festen Länge zu berechnen, belassen wir als Übung.
Nach der Erzeugung merken wir uns die aktuelle Zeilenlänge immer in currentLineLen. Wir lesen ein Wort, und wenn die Größe currentLineLen plus die Länge des neuen Worts die Zeilenbreite len überschreitet, geben wir einen Zeilenvorschub aus. Direkt nach diesem folgt dann das Wort, dass in die alte Zeile nicht mehr hineinpasste. Dieses Wort ist entweder ein trennendes Leerzeichen oder ein anderes Token. Falls es ein Leerzeichen war, dann wollen wir es allerdings am Zeilenanfang unterdrücken. Ist word demnach das Leerzeichen, dann ist es nur ein Zeichen - was schnell getestet werden kann - und geben es nicht aus. Der Test mit charAt() ist effizienter als der mit equals().