Wraps the given string so it fits on the specified lines. - Android java.lang

Android examples for java.lang:String Format

Description

Wraps the given string so it fits on the specified lines.

Demo Code

/*******************************************************************************
 * Copyright (c) 2011 MadRobot./*  w w w .j ava 2s  .c  om*/
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Lesser Public License v2.1
 * which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
 * 
 * Contributors:
 *  Elton Kent - initial API and implementation
 ******************************************************************************/
//package com.java2s;
import java.util.ArrayList;
import android.graphics.Paint;

public class Main {
    /**
     * Wraps the given string so it fits on the specified lines. First of all it
     * is split at the line-breaks ('\n'), subsequently the substrings are split
     * when they do not fit on a single line.
     * 
     * @param string
     *            The string which should be wrapped
     * @param font
     *            The font which is used to display the font
     * @param firstLineWidth
     *            The allowed width for the first line
     * @param lineWidth
     *            The allowed width for all other lines, lineWidth >=
     *            firstLineWidth
     * @return The array containing the substrings
     */
    public static final String[] doTextWrap(final String string,
            final Paint font, int firstLineWidth, final int lineWidth) {
        boolean hasLineBreaks = (string.indexOf('\n') != -1);
        float completeWidth = font.measureText(string);
        if (((completeWidth <= firstLineWidth) && !hasLineBreaks)) { // ||
            // (value.
            // length()
            // <= 1) ) {
            // the given string fits on the first line:
            // if (hasLineBreaks) {
            // return split( "complete/linebreaks:" + completeWidth + "> " +
            // value, '\n');
            // } else {
            return new String[] { string };
            // }
        }
        // the given string does not fit on the first line:
        ArrayList<String> lines = new ArrayList<String>();
        if (!hasLineBreaks) {
            wrap(string, font, completeWidth, firstLineWidth, lineWidth,
                    lines);
        } else {
            // now the string will be splitted at the line-breaks and
            // then each line is processed:
            char[] valueChars = string.toCharArray();
            int lastIndex = 0;
            char c = ' ';
            int lineBreakCount = 0;
            for (int i = 0; i < valueChars.length; i++) {
                c = valueChars[i];
                boolean isCRLF = ((c == 0x0D)
                        && (i < valueChars.length - 1) && (valueChars[i + 1] == 0x0A));
                if ((c == '\n') || (i == valueChars.length - 1) || isCRLF) {
                    lineBreakCount++;
                    String line = null;
                    if (i == valueChars.length - 1) {
                        line = new String(valueChars, lastIndex, (i + 1)
                                - lastIndex);
                        // System.out.println("wrap: adding last line " + line
                        // );
                    } else {
                        line = new String(valueChars, lastIndex, i
                                - lastIndex);
                        // System.out.println("wrap: adding " + line );
                    }
                    completeWidth = font.measureText(line);
                    if (completeWidth <= firstLineWidth) {
                        lines.add(line);
                    } else {
                        wrap(line, font, completeWidth, firstLineWidth,
                                lineWidth, lines);
                    }
                    if (isCRLF) {
                        i++;
                    }
                    lastIndex = i + 1;
                    // after the first line all line widths are the same:
                    firstLineWidth = lineWidth;
                } // for each line
            } // for all chars
              // special case for lines that end with \n: add a further line
            if ((lineBreakCount > 1) && ((c == '\n') || (c == 10))) {
                lines.add(" ");
            }
        }
        String[] ret = new String[lines.size()];
        lines.toArray(ret);
        // new String[lines.size()];
        // System.out.println("Array Size " + ret.length);
        return ret;// (String[]) CollectionUtil.toArray(lines);//
        // ines.toArray(new
        // String
        // [lines.size()]);
    }

    /**
     * <p>
     * Wraps a single line of text, identifying words by <code>' '</code>.
     * </p>
     * 
     * <p>
     * New lines will be separated by the system property line separator. Very
     * long words, such as URLs will <i>not</i> be wrapped.
     * </p>
     * 
     * <p>
     * Leading spaces on a new line are stripped. Trailing spaces are not
     * stripped.
     * </p>
     * 
     * <pre>
     * WordUtils.wrap(null, *) = null
     * WordUtils.wrap("", *) = ""
     * </pre>
     * 
     * @param str
     *            the String to be word wrapped, may be null
     * @param wrapLength
     *            the column to wrap the words at, less than 1 is treated as 1
     * @return a line with newlines inserted, <code>null</code> if null input
     */
    public static String wrap(String str, int wrapLength) {
        return wrap(str, wrapLength, null, false);
    }

    /**
     * <p>
     * Wraps a single line of text, identifying words by <code>' '</code>.
     * </p>
     * 
     * <p>
     * Leading spaces on a new line are stripped. Trailing spaces are not
     * stripped.
     * </p>
     * 
     * <pre>
     * WordUtils.wrap(null, *, *, *) = null
     * WordUtils.wrap("", *, *, *) = ""
     * </pre>
     * 
     * @param str
     *            the String to be word wrapped, may be null
     * @param wrapLength
     *            the column to wrap the words at, less than 1 is treated as 1
     * @param newLineStr
     *            the string to insert for a new line, <code>null</code> uses
     *            the system property line separator
     * @param wrapLongWords
     *            true if long words (such as URLs) should be wrapped
     * @return a line with newlines inserted, <code>null</code> if null input
     */
    public static String wrap(String str, int wrapLength,
            String newLineStr, boolean wrapLongWords) {
        if (str == null) {
            return null;
        }
        if (newLineStr == null) {
            newLineStr = "\n";// SystemUtils.LINE_SEPARATOR;
        }
        if (wrapLength < 1) {
            wrapLength = 1;
        }
        int inputLineLength = str.length();
        int offset = 0;
        StringBuilder wrappedLine = new StringBuilder(inputLineLength + 32);

        while ((inputLineLength - offset) > wrapLength) {
            if (str.charAt(offset) == ' ') {
                offset++;
                continue;
            }
            int spaceToWrapAt = str.lastIndexOf(' ', wrapLength + offset);

            if (spaceToWrapAt >= offset) {
                // normal case
                wrappedLine.append(str.substring(offset, spaceToWrapAt));
                wrappedLine.append(newLineStr);
                offset = spaceToWrapAt + 1;

            } else {
                // really long word or URL
                if (wrapLongWords) {
                    // wrap really long word one line at a time
                    wrappedLine.append(str.substring(offset, wrapLength
                            + offset));
                    wrappedLine.append(newLineStr);
                    offset += wrapLength;
                } else {
                    // do not wrap really long word, just extend beyond limit
                    spaceToWrapAt = str.indexOf(' ', wrapLength + offset);
                    if (spaceToWrapAt >= 0) {
                        wrappedLine.append(str.substring(offset,
                                spaceToWrapAt));
                        wrappedLine.append(newLineStr);
                        offset = spaceToWrapAt + 1;
                    } else {
                        wrappedLine.append(str.substring(offset));
                        offset = inputLineLength;
                    }
                }
            }
        }

        // Whatever is left in line is short enough to just pass through
        wrappedLine.append(str.substring(offset));

        return wrappedLine.toString();
    }

    /**
     * Wraps the given string so that the substrings fit into the the given
     * line-widths. It is expected that the specified lineWidth >=
     * firstLineWidth. The resulting substrings will be added to the given
     * ArrayList. When the complete string fits into the first line, it will be
     * added to the list. When the string needs to be split to fit on the lines,
     * it is tried to split the string at a gap between words. When this is not
     * possible, the given string will be split in the middle of the
     * corresponding word.
     * 
     * 
     * @param value
     *            The string which should be wrapped
     * @param font
     *            The font which is used to display the font
     * @param completeWidth
     *            The complete width of the given string for the specified font.
     * @param firstLineWidth
     *            The allowed width for the first line
     * @param lineWidth
     *            The allowed width for all other lines, lineWidth >=
     *            firstLineWidth
     * @param list
     *            The list to which the substrings will be added.
     */
    private static void wrap(String value, Paint font, float completeWidth,
            float firstLineWidth, float lineWidth, ArrayList<String> list) {
        char[] valueChars = value.toCharArray();
        int startPos = 0;
        int lastSpacePos = -1;
        int lastSpacePosLength = 0;
        int currentLineWidth = 0;
        for (int i = 0; i < valueChars.length; i++) {
            char c = valueChars[i];
            currentLineWidth += font.measureText(String.valueOf(c));// .charWidth(c);
            if (c == '\n') {
                list.add(new String(valueChars, startPos, i - startPos));
                lastSpacePos = -1;
                startPos = i + 1;
                currentLineWidth = 0;
                firstLineWidth = lineWidth;
                i = startPos;
            } else if ((currentLineWidth > firstLineWidth) && (i > 0)) {
                if ((c == ' ') || (c == '\t')) {
                    list.add(new String(valueChars, startPos, i - startPos));
                    startPos = ++i;
                    currentLineWidth = 0;
                    lastSpacePos = -1;
                } else if (lastSpacePos == -1) {
                    if (i > startPos + 1) {
                        i--;
                    }
                    // System.out.println("value=" + value + ", i=" + i +
                    // ", startPos=" + startPos);
                    list.add(new String(valueChars, startPos, i - startPos));
                    startPos = i;
                    currentLineWidth = 0;
                } else {
                    currentLineWidth -= lastSpacePosLength;
                    list.add(new String(valueChars, startPos, lastSpacePos
                            - startPos));
                    startPos = lastSpacePos + 1;
                    lastSpacePos = -1;
                }
                firstLineWidth = lineWidth;
            } else if ((c == ' ') || (c == '\t')) {
                lastSpacePos = i;
                lastSpacePosLength = currentLineWidth;
            }

        }
        // add tail:
        list.add(new String(valueChars, startPos, valueChars.length
                - startPos));

    }
}

Related Tutorials