001: /*
002: * This is free software, licensed under the Gnu Public License (GPL)
003: * get a copy from <http://www.gnu.org/licenses/gpl.html>
004: * $Id: Column.java,v 1.6 2005/06/18 04:58:13 hzeller Exp $
005: * author: Henner Zeller <H.Zeller@acm.org>
006: */
007: package henplus.view;
008:
009: import java.util.ArrayList;
010: import java.util.StringTokenizer;
011:
012: /**
013: * One column in the table.
014: * This column contains both: the actual data to be printed and the
015: * state to print it; this state is represented by the 'position', the
016: * internal row if this is an multirow column. This is ok, since this
017: * Column is only used once to be filled and once to be printed.
018: */
019: public class Column {
020:
021: private final static String NULL_TEXT = "[NULL]";
022: private final static int NULL_LENGTH = NULL_TEXT.length();
023:
024: private String columnText[]; // multi-rows
025: private int width;
026:
027: /** This holds a state for the renderer */
028: private int pos;
029:
030: public Column(long value) {
031: this (String.valueOf(value));
032: }
033:
034: public Column(String text) {
035: if (text == null) {
036: width = NULL_LENGTH;
037: columnText = null;
038: } else {
039: width = 0;
040: StringTokenizer tok = new StringTokenizer(text, "\n\r");
041: columnText = new String[tok.countTokens()];
042: for (int i = 0; i < columnText.length; ++i) {
043: String line = (String) tok.nextElement();
044: int lWidth = line.length();
045: columnText[i] = line;
046: if (lWidth > width) {
047: width = lWidth;
048: }
049: }
050: }
051: pos = 0;
052: }
053:
054: /**
055: * Split a line at the nearest whitespace.
056: */
057: private String[] splitLine(String str, int autoCol) {
058: ArrayList/*<String>*/tmpRows = new ArrayList/*<String>*/(5);
059: int lastPos = 0;
060: int pos = lastPos + autoCol;
061: final int strLen = str.length();
062: while (pos < strLen) {
063: while (pos > lastPos
064: && !Character.isWhitespace(str.charAt(pos))) {
065: pos--;
066: }
067: if (pos == lastPos) { // no whitespace found: hard cut
068: tmpRows.add(str.substring(lastPos, lastPos + autoCol));
069: lastPos = lastPos + autoCol;
070: } else {
071: tmpRows.add(str.substring(lastPos, pos));
072: lastPos = pos + /* skip space: */1;
073: }
074: pos = lastPos + autoCol;
075: }
076: if (lastPos < strLen - 1) {
077: tmpRows.add(str.substring(lastPos));
078: }
079: return (String[]) tmpRows.toArray(new String[tmpRows.size()]);
080: }
081:
082: /**
083: * replaces a row with multiple other rows.
084: */
085: private String[] replaceRow(String[] orig, int pos, String[] other) {
086: String result[] = new String[orig.length + other.length - 1];
087: System.arraycopy(orig, 0, result, 0, pos);
088: System.arraycopy(other, 0, result, pos, other.length);
089: System.arraycopy(orig, pos + 1, result, pos + other.length,
090: orig.length - pos - 1);
091: return result;
092: }
093:
094: /**
095: * Set autowrapping at a given column.
096: */
097: void setAutoWrap(int autoWrapCol) {
098: if (autoWrapCol < 0 || columnText == null)
099: return;
100: width = 0;
101: for (int i = 0; i < columnText.length; ++i) {
102: int colWidth = columnText[i].length();
103: if (colWidth > autoWrapCol) {
104: String[] multiRows = splitLine(columnText[i],
105: autoWrapCol);
106: for (int j = 0; j < multiRows.length; ++j) {
107: int l = multiRows[j].length();
108: if (l > width) {
109: width = l;
110: }
111: }
112: columnText = replaceRow(columnText, i, multiRows);
113: i += multiRows.length; // next loop pos here.
114: } else {
115: if (colWidth > width) {
116: width = colWidth;
117: }
118: }
119: }
120: }
121:
122: // package private methods for the table renderer.
123: int getWidth() {
124: return width;
125: }
126:
127: boolean hasNextLine() {
128: return (columnText != null && pos < columnText.length);
129: }
130:
131: boolean isNull() {
132: return (columnText == null);
133: }
134:
135: String getNextLine() {
136: String result = "";
137: if (columnText == null) {
138: if (pos == 0)
139: result = NULL_TEXT;
140: } else if (pos < columnText.length) {
141: result = columnText[pos];
142: }
143: ++pos;
144: return result;
145: }
146: }
147:
148: /*
149: * Local variables:
150: * c-basic-offset: 4
151: * compile-command: "ant -emacs -find build.xml"
152: * End:
153: */
|