/*----------------------------------------------------------------*
* Klasse : LineBuffer
* Aufgabe: Ein einfacher Zeilenpuffer zur formatierten Ausgabe
* tabellarischer Daten.
* Autor : zzzzz
* Erstellt am: 11.02.2002
*-----------------------------------------------------------------*
* Bemerkungen:
* Dies ist eine sehr einfache Implementierung eines Zeilenpuffers
* Man könnte zusätzlich zu den Spaltenbreiten und Ausrichtung
* Fromatter-Objekte verwenden, die abhängig vom Typ andere
* Ausgabe erzeugen würden.
* z.B. DateFormatter, NumberFormatter etc.
*-----------------------------------------------------------------*
* Änderungen:
*----------------------------------------------------------------*/
/**
* Diese Klasse ist die Implementierung eines einfachen Zeilenpuffers
* zur formatierten Ausgabe tabellarischer Daten.
*
* @author zzzzzzzzzzz
* @version 0.nix
*/
public class LineBuffer {
/** Linksbündig */
public static final int LEFT = 1;
/** Rechtsbündig */
public static final int RIGHT = 2;
/** Zentriert */
public static final int CENTER = 3;
/** Spaltenbreiten */
int []widths = null;
/** Spaltenbreiten */
int []alignment = null;
/** Zeilendaten */
Object []values = null;
/** Spaltenpuffer, so breit, wie die breiteste Spalte */
char []colbuf = null;
/** Trennzeichen */
char separator = ' ';
/** Zeilenpuffer */
StringBuffer buffer = null;
/**
* Konstruktor. Neuen Zeilenpuffer erstellen.
*
* @param widths Array mit den Spaltenbreiten
* @param alignment Spaltenausrichtung
* @param separator Trennzeichen
* @throws IllegalArgumentException, wenn widths=null oder leer
*/
public LineBuffer(int []widths, int []alignment, char separator) {
if(widths==null)
throw new NullPointerException(
"LineBuffer.construct(...). widths[] must not be null!"
);
if(widths.length==0)
throw new IllegalArgumentException(
"LineBuffer.construct(...). widths[] must not be empty!"
);
if(alignment==null)
throw new NullPointerException(
"LineBuffer.construct(...). alignment[] must not be null!"
);
if(alignment.length==0)
throw new IllegalArgumentException(
"LineBuffer.construct(...). alignment[] must not be empty!"
);
if(alignment.length!=widths.length)
throw new IllegalArgumentException(
"LineBuffer.construct(...). alignment.length does not much widths.length!"
);
this.widths = widths;
this.alignment=alignment;
this.values = new Object[widths.length];
this.separator = separator;
// Längste Spalte und gesamtlänge ermitteln
int maxLen = 0;
int length = widths.length-1;
for(int i=0;i<widths.length;i++) {
maxLen = maxLen<widths[i]?widths[i]:maxLen;
length += widths[i];
}
this.colbuf = new char[maxLen];
java.util.Arrays.fill(this.colbuf, ' ');
this.buffer = new StringBuffer(length);
}
/**
* Trennzeichen setzen
*
* @param separator Trennzeichen
*/
public void setSeparator(char separator) {
this.separator = separator;
}
/**
* Alle Werte der Zeile entfernen
*/
public void clear() {
java.util.Arrays.fill(values, null);
}
/**
* Ganze Zeile setzen. Das Array 'newValues' muß nicht gleich
* lang sein, wie die Anzahl der Felder in der Zeile.
* Es werden höchstens so viele Werte kopiert, wie die Zeile
* lang ist.
*
* @param newValues Array mit Objekten
* @throws IllegalArgumentException, wenn newValues=null oder leer
*/
public void setValues(Object []newValues) {
if(newValues==null)
throw new NullPointerException(
"LineBuffer.setValues(...). newValues[] must not be null!"
);
if(newValues.length==0)
throw new IllegalArgumentException(
"LineBuffer.setValues(...). newValues[] must not be empty!"
);
clear();
System.arraycopy(
newValues, 0, values, 0,
Math.min(values.length,newValues.length)
);
}
/**
* Werte an Position 'index' setzen.
*
* @param index Position des zu setzenden Objektes
* @param value Zu setzendes Objekt
* @throws ArrayIndexOutOfBoundsException
*/
public void setObject(int index, Object value) {
if(index<0 || index>=values.length)
throw new ArrayIndexOutOfBoundsException(
"LineBuffer.setObject(...). index is out of range!"
);
values[index] = value;
}
/**
* Setzt einen Int-Wert an der gegeben Position im Puffer.
*
* @param index Position des zu setzenden Objektes
* @param value Zu setzender Wert
*/
public void setInt(int index, int value) {
setObject(index, new Integer(value));
}
/**
* Setzt einen Long-Wert an der gegeben Position im Puffer.
*
* @param index Position des zu setzenden Objektes
* @param value Zu setzender Wert
*/
public void setLong(int index, long value) {
setObject(index, new Long(value));
}
/**
* Setzt einen Float-Wert an der gegeben Position im Puffer.
*
* @param index Position des zu setzenden Objektes
* @param value Zu setzender Wert
*/
public void setFloat(int index, float value) {
setObject(index, new Float(value));
}
/**
* Setzt einen Double-Wert an der gegeben Position im Puffer.
*
* @param index Position des zu setzenden Objektes
* @param value Zu setzender Wert
*/
public void setDouble(int index, double value) {
setObject(index, new Double(value));
}
/**
* Setzt einen Char-Wert an der gegeben Position im Puffer.
*
* @param index Position des zu setzenden Objektes
* @param value Zu setzender Wert
*/
public void setChar(int index, char value) {
setObject(index, new Character(value));
}
/**
* Setzt einen Char-Wert an der gegeben Position im Puffer.
*
* @param index Position des zu setzenden Objektes
* @param value Zu setzender Wert
*/
public void setByte(int index, byte value) {
setObject(index, new Byte(value));
}
/**
* Setzt einen Boolean-Wert an der gegeben Position im Puffer.
*
* @param index Position des zu setzenden Objektes
* @param value Zu setzender Wert
*/
public void setBoolean(int index, boolean value) {
setObject(index, new Boolean(value));
}
/**
* Aktuelle Zeile in den gegebenen StringBuffer schreiben
*
* @param buf Zielpuffer
* @return Zielpuffer
*/
public StringBuffer appendTo(StringBuffer buf) {
for(int i=0;i<widths.length;i++) {
buf.append(colbuf, 0, widths[i]);
if(values[i]!=null) {
String str = values[i].toString();
int pos1, pos2;
switch (alignment[i]) {
case RIGHT:
pos1 = buf.length() - str.length();
pos2 = buf.length();
break;
case CENTER:
pos1 = buf.length() - widths[i] + ((widths[i]-str.length())/2);
pos2 = pos1 + str.length();
break;
case LEFT:
default:
pos1 = buf.length() - widths[i];
pos2 = pos1 + str.length();
}
buf.replace(pos1, pos2, str);
}
buf.append(separator);
}
buf.delete(buf.length()-1, buf.length());
return buf;
}
/**
* Aktuellen Zeilenpuffer ausgeben
*
* @return Formatierte Zeile als String
*/
public String toString() {
buffer.delete(0, buffer.length());
appendTo(buffer);
return buffer.toString();
}
/**
* Einfaches Demo starten.
*/
public static void main(String argv[]) {
// Ausgabepuffer erstellen
StringBuffer buf = new StringBuffer();
// Zeilenpuffer mit 5 Spalten je 5 Zeichen lang
// und | als Feldtrennzeichen erstellen
LineBuffer line = new LineBuffer(
new int[] {5, 5, 5, 5, 5},
new int[] {LEFT, RIGHT, RIGHT, CENTER, RIGHT},
'|'
);
// Überschriften ausgeben
line.setValues(new Object[] {"Feld1","Feld2","Feld3","Feld4","Feld5"});
buf.append("\n").append(line).append("\n");
line.setValues(new Object[] {"-----","-----","-----","-----","-----"});
line.appendTo(buf).append("\n");
// Paar Zeilen in Ausgabepuffer ausgeben
for(int i=1; i<=20; i++) {
line.setInt(0, (int)(Math.random()*(((i%2)==0)?9999:999)));
line.setInt(1, (int)(Math.random()*999));
line.setInt(2, (int)(Math.random()*99));
line.setInt(3, (int)(Math.random()*999));
line.setInt(4, (int)(Math.random()*(((i%2)==0)?9999:999)));
line.appendTo(buf).append("\n");
}
// Ausgabepuffer in String umwandeln und ausgeben
System.out.print(buf.toString());
/*
Test: Zeitmessung bei 1000000 Zeilen
Aufruf: java LineBuffer>ausgabe.txt
long time=System.currentTimeMillis();
for(int i=1; i<=1000000; i++) {
line.setInt(0, (int)(Math.random()*(((i%2)==0)?9999:999)));
line.setInt(1, (int)(Math.random()*999));
line.setInt(2, (int)(Math.random()*99));
line.setInt(3, (int)(Math.random()*999));
line.setInt(4, (int)(Math.random()*(((i%2)==0)?9999:999)));
line.appendTo(buf).append("\n");
if((i%100)==0) {
System.out.print(buf.toString());
buf.delete(0, buf.length());
}
}
// Ausgabepuffer in String umwandeln und ausgeben
System.out.print(buf.toString());
System.out.print("Zeit in ms: "+(System.currentTimeMillis()-time));
*/
}
}