src/main/java/com/mxgraph/util/mxUtils.java
public static String[] wordWrap(String text, FontMetrics metrics,
			double width)
	{
		List<String> result = new ArrayList<String>();
		// First split the processing into lines already delimited by
		// newlines. We want the result to retain all newlines in position.
		String[] lines = text.split("\n");

		for (int i = 0; i < lines.length; i++)
		{
			int lineWidth = 0; // the display width of the current line
			int charCount = 0; // keeps count of current position in the line
			StringBuilder currentLine = new StringBuilder();

			// Split the words of the current line by spaces and tabs
			// The words are trimmed of tabs, space and newlines, therefore
			String[] words = lines[i].split("\\s+");

			// Need to a form a stack of the words in reverse order
			// This is because if a word is split during the process 
			// the remainder of the word is added to the front of the 
			// stack and processed next
			Stack<String> wordStack = new Stack<String>();

			for (int j = words.length - 1; j >= 0; j--)
			{
				wordStack.push(words[j]);
			}

			while (!wordStack.isEmpty())
			{
				String word = wordStack.pop();

				// Work out what whitespace exists before this word.
				// and add the width of the whitespace to the calculation
				int whitespaceCount = 0;

				if (word.length() > 0)
				{
					// Concatenate any preceding whitespace to the
					// word and calculate the number of characters of that
					// whitespace
					char firstWordLetter = word.charAt(0);
					int letterIndex = lines[i].indexOf(firstWordLetter,
							charCount);
					String whitespace = lines[i].substring(charCount,
							letterIndex);
					whitespaceCount = whitespace.length();
					word = whitespace.concat(word);
				}

				double wordLength;

				// If the line width is zero, we are at the start of a newline
				// We don't proceed preceeding whitespace in the width
				// calculation
				if (lineWidth > 0)
				{
					wordLength = metrics.stringWidth(word);
				}
				else
				{
					wordLength = metrics.stringWidth(word.trim());
				}

				// Does the width of line so far plus the width of the 
				// current word exceed the allowed width?
				if (lineWidth + wordLength > width)
				{
					if (lineWidth > 0)
					{
						// There is already at least one word on this line
						// and the current word takes the overall width over
						// the allowed width. Because there is something on
						// the line, complete the current line, reset the width
						// counter, create a new line and put the current word
						// back on the stack for processing in the next round
						result.add(currentLine.toString());
						currentLine = new StringBuilder();
						wordStack.push(word.trim());
						lineWidth = 0;
					}
					else if (mxConstants.SPLIT_WORDS)
					{
						// There are no words on the current line and the 
						// current word does not fit on it. Find the maximum
						// number of characters of this word that just fit
						// in the available width
						word = word.trim();

						for (int j = 1; j <= word.length(); j++)
						{
							wordLength = metrics.stringWidth(word.substring(0,
									j));

							if (lineWidth + wordLength > width)
							{
								// The last character took us over the allowed
								// width, deducted it unless there is only one
								// character, in which case we have to use it
								// since we can't split it...
								j = j > 1 ? j - 1 : j;
								String chars = word.substring(0, j);
								currentLine = currentLine.append(chars);
								// Return the unprocessed part of the word 
								// to the stack
								wordStack
										.push(word.substring(j, word.length()));
								result.add(currentLine.toString());
								currentLine = new StringBuilder();
								lineWidth = 0;
								// Increment char counter allowing for white 
								// space in the original word
								charCount = charCount + chars.length()
										+ whitespaceCount;
								break;
							}
						}
					}
					else
					{
						// There are no words on the current line, but
						// we are not splitting.
						word = word.trim();
						result.add(word);
						currentLine = new StringBuilder();
						lineWidth = 0;
						// Increment char counter allowing for white 
						// space in the original word
						charCount = word.length() + whitespaceCount;
					}
				}
				else
				{
					// The current word does not take the total line width
					// over the allowed width. Append the word, removing
					// preceeding whitespace if it is the first word in the
					// line.
					if (lineWidth > 0)
					{
						currentLine = currentLine.append(word);
					}
					else
					{
						currentLine = currentLine.append(word.trim());
					}

					lineWidth += wordLength;
					charCount += word.length();
				}
			}

			result.add(currentLine.toString());
		}

		return result.toArray(new String[result.size()]);
	}
/**
	 * Returns the specified text in lines that fit within the specified
	 * width when the specified font metrics are applied to the text
	 * @param text the text to wrap
	 * @param metrics the font metrics to calculate the text size for
	 * @param width the width that the text must fit within
	 * @return the input text split in lines that fit the specified width
	 */
Returns the specified text in lines that fit within the specified
width when the specified font metrics are applied to the text
@param text the text to wrap
@param metrics the font metrics to calculate the text size for
@param width the width that the text must fit within
@return the input text split in lines that fit the specified width
Returns the specified text in lines that fit within the specified width when the specified font metrics are applied to the text @param text the text to wrap @param metrics the font metrics to calculate the text size for @param width the width that the text must fit within @return the input text split in lines that fit the specified width
public static String[] wordWrap(String text, FontMetrics metrics,
			double width)
	{
		List<String> result = new ArrayList<String>();
		String[] lines = text.split("\n");
		for (int i = 0; i < lines.length; i++)
		{
			int lineWidth = 0; 
			int charCount = 0; 
			StringBuilder currentLine = new StringBuilder();
			String[] words = lines[i].split("\\s+");
			Stack<String> wordStack = new Stack<String>();
			for (int j = words.length - 1; j >= 0; j--)
			{
				wordStack.push(words[j]);
			}
			while (!wordStack.isEmpty())
			{
				String word = wordStack.pop();
				int whitespaceCount = 0;
				if (word.length() > 0)
				{
					char firstWordLetter = word.charAt(0);
					int letterIndex = lines[i].indexOf(firstWordLetter,
							charCount);
					String whitespace = lines[i].substring(charCount,
							letterIndex);
					whitespaceCount = whitespace.length();
					word = whitespace.concat(word);
				}
				double wordLength;
				if (lineWidth > 0)
				{
					wordLength = metrics.stringWidth(word);
				}
				else
				{
					wordLength = metrics.stringWidth(word.trim());
				}
				if (lineWidth + wordLength > width)
				{
					if (lineWidth > 0)
					{
						result.add(currentLine.toString());
						currentLine = new StringBuilder();
						wordStack.push(word.trim());
						lineWidth = 0;
					}
					else if (mxConstants.SPLIT_WORDS)
					{
						word = word.trim();
						for (int j = 1; j <= word.length(); j++)
						{
							wordLength = metrics.stringWidth(word.substring(0,
									j));
							if (lineWidth + wordLength > width)
							{
								j = j > 1 ? j - 1 : j;
								String chars = word.substring(0, j);
								currentLine = currentLine.append(chars);
								wordStack
										.push(word.substring(j, word.length()));
								result.add(currentLine.toString());
								currentLine = new StringBuilder();
								lineWidth = 0;
								charCount = charCount + chars.length()
										+ whitespaceCount;
								break;
							}
						}
					}
					else
					{
						word = word.trim();
						result.add(word);
						currentLine = new StringBuilder();
						lineWidth = 0;
						charCount = word.length() + whitespaceCount;
					}
				}
				else
				{
					if (lineWidth > 0)
					{
						currentLine = currentLine.append(word);
					}
					else
					{
						currentLine = currentLine.append(word.trim());
					}
					lineWidth += wordLength;
					charCount += word.length();
				}
			}
			result.add(currentLine.toString());
		}
		return result.toArray(new String[result.size()]);
	}
public static String [ ] wordWrap ( String text , FontMetrics metrics , double width ) { List < String > result = new ArrayList < String > ( ) ; String [ ] lines = text . split ( "\n" ) ; for ( int i = 0 ; i < lines . length ; i ++ ) { int lineWidth = 0 ; int charCount = 0 ; StringBuilder currentLine = new StringBuilder ( ) ; String [ ] words = lines [ i ] . split ( "\\s+" ) ; Stack < String > wordStack = new Stack < String > ( ) ; for ( int j = words . length - 1 ; j >= 0 ; j -- ) { wordStack . push ( words [ j ] ) ; } while ( ! wordStack . isEmpty ( ) ) { String word = wordStack . pop ( ) ; int whitespaceCount = 0 ; if ( word . length ( ) > 0 ) { char firstWordLetter = word . charAt ( 0 ) ; int letterIndex = lines [ i ] . indexOf ( firstWordLetter , charCount ) ; String whitespace = lines [ i ] . substring ( charCount , letterIndex ) ; whitespaceCount = whitespace . length ( ) ; word = whitespace . concat ( word ) ; } double wordLength ; if ( lineWidth > 0 ) { wordLength = metrics . stringWidth ( word ) ; } else { wordLength = metrics . stringWidth ( word . trim ( ) ) ; } if ( lineWidth + wordLength > width ) { if ( lineWidth > 0 ) { result . add ( currentLine . toString ( ) ) ; currentLine = new StringBuilder ( ) ; wordStack . push ( word . trim ( ) ) ; lineWidth = 0 ; } else if ( mxConstants . SPLIT_WORDS ) { word = word . trim ( ) ; for ( int j = 1 ; j <= word . length ( ) ; j ++ ) { wordLength = metrics . stringWidth ( word . substring ( 0 , j ) ) ; if ( lineWidth + wordLength > width ) { j = j > 1 ? j - 1 : j ; String chars = word . substring ( 0 , j ) ; currentLine = currentLine . append ( chars ) ; wordStack . push ( word . substring ( j , word . length ( ) ) ) ; result . add ( currentLine . toString ( ) ) ; currentLine = new StringBuilder ( ) ; lineWidth = 0 ; charCount = charCount + chars . length ( ) + whitespaceCount ; break ; } } } else { word = word . trim ( ) ; result . add ( word ) ; currentLine = new StringBuilder ( ) ; lineWidth = 0 ; charCount = word . length ( ) + whitespaceCount ; } } else { if ( lineWidth > 0 ) { currentLine = currentLine . append ( word ) ; } else { currentLine = currentLine . append ( word . trim ( ) ) ; } lineWidth += wordLength ; charCount += word . length ( ) ; } } result . add ( currentLine . toString ( ) ) ; } return result . toArray ( new String [ result . size ( ) ] ) ; }
Returns the specified text in lines that fit within the specified
 width when the specified font metrics are applied to the text
 @param text the text to wrap
 @param metrics the font metrics to calculate the text size for
 @param width the width that the text must fit within
 @return the input text split in lines that fit the specified width
Returns the specified text in lines that fit within the specified width when the specified font metrics are applied to the text @param text the text to wrap @param metrics the font metrics to calculate the text size for @param width the width that the text must fit within @return the input text split in lines that fit the specified width
// First split the processing into lines already delimited by // newlines. We want the result to retain all newlines in position. // the display width of the current line // keeps count of current position in the line // Split the words of the current line by spaces and tabs // The words are trimmed of tabs, space and newlines, therefore // Need to a form a stack of the words in reverse order // This is because if a word is split during the process  // the remainder of the word is added to the front of the  // stack and processed next // Work out what whitespace exists before this word. // and add the width of the whitespace to the calculation // Concatenate any preceding whitespace to the // word and calculate the number of characters of that // whitespace // If the line width is zero, we are at the start of a newline // We don't proceed preceeding whitespace in the width // calculation // Does the width of line so far plus the width of the  // current word exceed the allowed width? // There is already at least one word on this line // and the current word takes the overall width over // the allowed width. Because there is something on // the line, complete the current line, reset the width // counter, create a new line and put the current word // back on the stack for processing in the next round // There are no words on the current line and the  // current word does not fit on it. Find the maximum // number of characters of this word that just fit // in the available width // The last character took us over the allowed // width, deducted it unless there is only one // character, in which case we have to use it // since we can't split it... // Return the unprocessed part of the word  // to the stack // Increment char counter allowing for white  // space in the original word // There are no words on the current line, but // we are not splitting. // Increment char counter allowing for white  // space in the original word // The current word does not take the total line width // over the allowed width. Append the word, removing // preceeding whitespace if it is the first word in the // line.