sim.util.gui.WordWrap Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of mason Show documentation
Show all versions of mason Show documentation
MASON is a fast discrete-event multiagent simulation library core in Java, designed to be the foundation for large custom-purpose Java simulations, and also to provide more than enough functionality for many lightweight simulation needs. MASON contains both a model library and an optional suite of visualization tools in 2D and 3D.
The newest version!
/*
Copyright 2006 by Sean Luke and George Mason University
Licensed under the Academic Free License version 3.0
See the file "LICENSE" for more information
*/
package sim.util.gui;
import java.util.*;
import java.awt.*;
interface WordWrapScanner
{
// returns the index of the LAST character to fit within
// the boundaries starting at startIndex and moving to a string
// length defined by nextLoc
public int scan(StringBuilder buf, int startIndex, double nextLoc);
}
class CharColumnScanner implements WordWrapScanner
{
/** nextLoc is expected to be the number of columns */
// presently does a simple linear search
public int scan(StringBuilder buf, int start, double nextLoc)
{
int nextIndex = start + ((int)nextLoc) - 1;
if (buf.length() <= nextIndex)
nextIndex = buf.length() - 1;
// determine if there's a \n first, and if so, use it
// as the breaking point
for(int x=start; x < nextIndex; x++)
if (buf.charAt(x) == '\n')
nextIndex = x - 1;
return nextIndex;
}
}
class FontMetricsScanner implements WordWrapScanner
{
FontMetrics metrics;
public FontMetricsScanner(FontMetrics metrics)
{
this.metrics = metrics;
}
// nextLoc is expected to be the number of columns
// presently does a simple linear search, very expensive.
public int scan(StringBuilder buf, int start, double nextLoc)
{
// gather the array
char[] chars = new char[buf.length() - start];
buf.getChars(start,buf.length(), chars, 0);
// start computing the lengths. Don't bother if we get to a \n
for(int x = 0; x < chars.length; x++)
{
if (chars[x] == '\n')
return start + x - 1;
int len = metrics.charsWidth(chars,0,x+1);
if (len > nextLoc) // including x was bad
return start + x - 1;
}
// everything fit
return buf.length() - 1;
}
}
/** WordWrap is a simple word-wrapping class which provides word-wrap either to columns of raw text; or to some number
of pixels (given a font). It's not terribly efficient but works reasonably well. Tabs are considered to be the same length as spaces. The input is the string to wrap, and the output is the same string with returns inserted in the appropriate location. */
// in the future we might provide arbitrary scanners to determine maximal length, but right now it's just these two.
public class WordWrap implements java.io.Serializable
{
/** Wraps a string to a given number of columns. */
public static String wrap(String string, int numColumns)
{
return wrap(string, numColumns, new CharColumnScanner());
}
/** Wraps a string to a given number of pixels in width, given a font whose metrics are provided as well. */
public static String wrap(String string, int numPixels, FontMetrics metrics)
{
return wrap(string, numPixels, new FontMetricsScanner(metrics));
}
static String wrap(String string, double desiredLength, WordWrapScanner scanner)
{
StringBuilder buf = new StringBuilder(string);
int s = 0;
int e;
while(true)
{
if (s==buf.length()) // gone too far
return buf.toString();
e = scanner.scan(buf,s,desiredLength) + 1;
if (e>=buf.length()) // up to last character
return buf.toString();
char ce = buf.charAt(e);
if (ce=='\n')
{
s = e + 1;
}
else if (Character.isWhitespace(ce))
{
int top = e;
while(top < buf.length() - 1 && // not last character
Character.isWhitespace(buf.charAt(top)) && // it's whitespace
buf.charAt(top) != '\n') // but it's not an '\n'
top++;
buf.delete(e,top); // yank out all whitespace to the next value
if (buf.charAt(e)!='\n') // not already a \n, need to add one
buf.insert(e,'\n');
s = e + 1;
}
else // not whitespace
{
int l = e;
while(l > s && // don't back beyond s
!Character.isWhitespace(buf.charAt(l))) // not a whitespace char
l--;
if (l==s && !Character.isWhitespace(buf.charAt(l))) // oops, all non-whitespace, must split
{
buf.insert(e, '\n');
s = e + 1;
}
else
{
buf.insert(l+1, '\n');
s = l + 2;
}
}
}
}
/** A useful auxillary method: once you're word-wrapped your text, you can use this to break it into
multiple strings at the \n position. */
public static String[] split(String str)
{
StringTokenizer tok = new StringTokenizer(str, "\n");
String[] s = new String[tok.countTokens()];
int x=0;
while(tok.hasMoreTokens())
s[x++] = tok.nextToken();
return s;
}
/** A useful auxillary method: once you've word-wrapped your text, you can use this to convert it into
'HTML' style, where < is converted into <, & is converted into
&, and \n or \r are converted into <br>.
You can use this to make multi-line buttons and multi-line menus like this:
String myText = "Here is the big text that we want to have word-wrapped";
int myNumberOfPixels = 50; // our word-wrap pixel length
JButton button = new JButton();
String wrappedText = sim.util.WordWrap.wrap(myText, myNumberOfPixels, button.getFontMetrics(button.getFont()));
button.setText("<html>" + sim.util.WordWrap.toHTML(wrappedText) + "</html>");
*/
public static String toHTML(final String text)
{
StringBuilder buf = new StringBuilder();
char[] c = text.toCharArray();
for(int x=0;x");
break;
case '&':
buf.append("&");
break;
case '<':
buf.append("<");
break;
default:
buf.append(c[x]);
break;
}
}
return buf.toString();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy