Introduction
VWrappingLabel
is based on the Symantec WrappingLabel
. Here is a brief blurb taken straight from Daniel Kirkdorffers Visual Cafe Tips, which was the place this code was found originally.
Symantec's WrappingLabel
is a very handy component. On top of the ability to automatically wrap label text to fit the width of the component, WrappingLabel
can work as a good substitute for the basic Label
component in cases where you want to modify foreground or background colors of your label.
A number of people have asked if it is possible for WrappingLabel
to take the newline character "\n" into consideration when wrapping to force a newline in certain places. Unfortunately WrappingLabel
eats newlines. However in response to the interest, Paul Williams has written another version of WrappingLabel
that does handle newlines. I have copies of the source code, compiled class file, and the .desc description file. The key to using this component in Visual Caf� is to set the text of the label with the setText()
method in code, as opposed to setting the text in the Property List window at design time. Visual Caf� will substitute "\n" with "\\n" otherwise. Paul has also added the nice feature of setting horizontal and vertical alignment of your text via the setHAlignStyle()
and setVAlignStyle()
methods, or through alternate constructors.
Kudos to Paul Williams formerly of Criterion Inc. I tried to contact you, but it seems your old email address is a dead end. I promise I only made a few minor modifications.
import java.awt.Canvas;
import java.awt.Graphics;
import java.awt.FontMetrics;
import java.awt.Dimension;
import java.awt.Label;
import java.util.Vector;
import java.util.Enumeration;
public class VWrappingLabel extends Canvas
{
protected String text;
protected float m_nHAlign;
protected float m_nVAlign;
protected int baseline;
protected FontMetrics fm;
public VWrappingLabel()
{
this("");
}
public VWrappingLabel(String s)
{
this(s, Canvas.LEFT_ALIGNMENT, Canvas.CENTER_ALIGNMENT);
}
public VWrappingLabel(String s, float nHorizontal, float nVertical)
{
setText(s);
setHAlignStyle(nHorizontal);
setVAlignStyle(nVertical);
}
public float getHAlignStyle() { return m_nHAlign; }
public float getVAlignStyle() { return m_nVAlign; }
public String getText() { return text; }
public void setHAlignStyle(float a)
{
m_nHAlign = a;
invalidate();
}
public void setVAlignStyle(float a)
{
m_nVAlign = a;
invalidate();
}
public void setText(String s)
{
text = s;
repaint();
}
public String paramString()
{
return "";
}
public void paint(Graphics g)
{
if (text != null)
{
Dimension d;
int currentY = 0;
Vector lines;
fm = getFontMetrics(getFont());
baseline = fm.getMaxAscent();
d = getSize();
lines = breakIntoLines (text, d.width);
if (m_nVAlign == Canvas.CENTER_ALIGNMENT)
{
int center = (d.height / 2);
currentY = center - ( (lines.size() / 2) * fm.getHeight() );
}
else if (m_nVAlign == Canvas.BOTTOM_ALIGNMENT)
{
currentY = d.height - ( lines.size() * fm.getHeight() );
}
Enumeration elements = lines.elements();
while (elements.hasMoreElements())
{
drawAlignedString(g,
(String)(elements.nextElement()),
0, currentY, d.width);
currentY += fm.getHeight();
}
fm = null;
}
}
protected Vector breakIntoLines (String s, int width)
{
int fromIndex = 0;
int pos = 0;
int bestpos;
String largestString;
Vector lines = new Vector();
while (fromIndex != -1)
{
while (fromIndex < text.length()
&& text.charAt(fromIndex) == ' ')
{
++fromIndex;
if (fromIndex >= text.length()) break;
}
pos = fromIndex;
bestpos = -1;
largestString = null;
while (pos >= fromIndex)
{
boolean bHardNewline = false;
int newlinePos = text.indexOf('\n', pos);
int spacePos = text.indexOf(' ', pos);
if (newlinePos != -1 &&
((spacePos == -1) ||
(spacePos != -1 &&
newlinePos < spacePos)))
{
pos = newlinePos;
bHardNewline = true;
}
else
{
pos = spacePos;
bHardNewline = false;
}
if (pos == -1)
{
s = text.substring(fromIndex);
}
else
{
s = text.substring(fromIndex, pos);
}
if (fm.stringWidth(s) < width)
{
largestString = s;
bestpos = pos;
if (bHardNewline)
bestpos++;
if (pos == -1 || bHardNewline) break;
}
else
{
break;
}
++pos;
}
if (largestString == null)
{
int totalWidth = 0;
int oneCharWidth = 0;
pos = fromIndex;
while (pos < text.length())
{
oneCharWidth = fm.charWidth(text.charAt(pos));
if ((totalWidth + oneCharWidth) >= width) break;
totalWidth += oneCharWidth;
++pos;
}
lines.addElement (text.substring(fromIndex, pos));
fromIndex = pos;
}
else
{
lines.addElement (largestString);
fromIndex = bestpos;
}
}
return lines;
}
protected void drawAlignedString(Graphics g,
String s, int x, int y, int width)
{
int drawx;
int drawy;
drawx = x;
drawy = y + baseline;
if (m_nHAlign != Canvas.LEFT_ALIGNMENT)
{
int sw;
sw = fm.stringWidth(s);
if (m_nHAlign == Canvas.CENTER_ALIGNMENT)
{
drawx += (width - sw) / 2;
}
else if (m_nHAlign == Canvas.RIGHT_ALIGNMENT)
{
drawx = drawx + width - sw;
}
}
g.drawString(s, drawx, drawy);
}
}