Java tutorial
import java.awt.FontMetrics; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.List; /** * Globally available utility classes, mostly for string manipulation. * * @author Jim Menard, <a href="mailto:jimm@io.com">jimm@io.com</a> */ public class StringUtils { protected static final int DEFAULT_MAX_MESSAGE_WIDTH = 78; /** * Returns a list of substrings created by splitting the given string at the * given delimiter. The return value will be <code>null</code> if the string * is <code>null</code>, else it will be a non-empty list of strings. If * <var>delim</var> is <code>null</code> or is not found in the string, the * list will contain one element: the original string. * <p> * This isn't the same thing as using a tokenizer. <var>delim</var> is a * literal string, not a set of characters any of which may be a delimiter. * * @param str * the string we're splitting * @param delim * the delimter string */ public static List split(String str, String delim) { if (str == null) return null; ArrayList list = new ArrayList(); if (delim == null) { list.add(str); return list; } int subStart, afterDelim = 0; int delimLength = delim.length(); while ((subStart = str.indexOf(delim, afterDelim)) != -1) { list.add(str.substring(afterDelim, subStart)); afterDelim = subStart + delimLength; } if (afterDelim <= str.length()) list.add(str.substring(afterDelim)); return list; } /** * Returns a string consisting of all members of a collection separated by the * specified string. The <code>toString</code> method of each collection * member is called to convert it to a string. * * @param c * a collection of objects * @param joinWith * the string that will separate each member of the collection */ public static String join(Collection c, String joinWith) { if (c == null) return ""; StringBuffer buf = new StringBuffer(); boolean first = true; for (Iterator iter = c.iterator(); iter.hasNext();) { if (first) first = false; else if (joinWith != null) buf.append(joinWith); buf.append(iter.next().toString()); } return buf.toString(); } /** * Returns an array of strings, one for each line in the string. Lines end * with any of cr, lf, or cr lf. A line ending at the end of the string will * not output a further, empty string. * <p> * This code assumes <var>str</var> is not <code>null</code>. * * @param str * the string to split * @return a non-empty list of strings */ public static List splitIntoLines(String str) { ArrayList strings = new ArrayList(); int len = str.length(); if (len == 0) { strings.add(""); return strings; } int lineStart = 0; for (int i = 0; i < len; ++i) { char c = str.charAt(i); if (c == '\r') { int newlineLength = 1; if ((i + 1) < len && str.charAt(i + 1) == '\n') newlineLength = 2; strings.add(str.substring(lineStart, i)); lineStart = i + newlineLength; if (newlineLength == 2) // skip \n next time through loop ++i; } else if (c == '\n') { strings.add(str.substring(lineStart, i)); lineStart = i + 1; } } if (lineStart < len) strings.add(str.substring(lineStart)); return strings; } /** * Appends a string to a string buffer, adding extra newlines so the message * is not too wide. Max width is not guaranteed; if there is no space in a * line before <code>DEFAULT_MAX_MESSAGE_WIDTH</code> then the next one * after it will be used insetead. Each line will be trimmed before and after * it's added, so some whitespace may be goofed up. This is used for error * message wrapping, so it's not critical that whitespace be preserved. * <p> * TODO Looks for space, not all whitespace. This should probably change. * * @param buf * the string buffer * @param str * the string */ public static void splitUp(StringBuffer buf, String str) { splitUp(buf, str, DEFAULT_MAX_MESSAGE_WIDTH); } /** * Appends a string to a string buffer, adding extra newlines so the message * is not too wide. Max width is not guaranteed; if there is no space in a * line before <var>maxWidth</var> then the next one after it will be used * instead. Each line will be trimmed before and after it's added, so some * whitespace may be goofed up. This is used for error message wrapping, so * it's not critical that whitespace be preserved. * <p> * TODO Looks for space, not all whitespace. This should probably change. * * @param buf * the string buffer * @param str * the string * @param maxWidth * maximum number of chars in each line */ public static void splitUp(StringBuffer buf, String str, int maxWidth) { if (str == null) return; str = str.trim(); while (str.length() >= maxWidth) { int pos = str.lastIndexOf(' ', maxWidth); if (pos == -1) { // No spaces before; look for first one after pos = str.indexOf(' ', maxWidth); if (pos == -1) break; } buf.append(str.substring(0, pos).trim()); buf.append("\n"); str = str.substring(pos + 1).trim(); } buf.append(str); } }