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; /** * Netistä löytynyt lähdekoodi monirivisen textlabelin toteuttamiseen, * ei ole muokattu, joten ei ole myöskään kommentoitu erikseen... * * VWrappingLabel is based on Symantec's class WrappingLabel; however, this * class can format the text vertically, too. It also wraps text at newlines * embedded in the label's text. * * @see symantec.awt.WrappingLabel * @author Paul F. Williams (mailto:paul@criterioninc.com) * Criterion, Inc. (http://www.criterioninc.com) * @author Kyle Morris (mailto:morriskg@nexusfusion.com) * */ public class VWrappingLabel extends Canvas { //-------------------------------------------------- // constants //-------------------------------------------------- //-------------------------------------------------- // class variables //-------------------------------------------------- //-------------------------------------------------- // member variables //-------------------------------------------------- protected String text; protected float m_nHAlign; protected float m_nVAlign; protected int baseline; protected FontMetrics fm; //-------------------------------------------------- // constructors //-------------------------------------------------- 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); } //-------------------------------------------------- // accessor members //-------------------------------------------------- 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(); } //-------------------------------------------------- // member methods //-------------------------------------------------- public String paramString() { return ""; } public void paint(Graphics g) { if (text != null) { Dimension d; int currentY = 0; Vector lines; // Set up some class variables fm = getFontMetrics(getFont()); baseline = fm.getMaxAscent(); // Get the maximum height and width of the current control d = getSize(); lines = breakIntoLines (text, d.width); //if (m_nVAlign == V_ALIGN_CENTER) if (m_nVAlign == Canvas.CENTER_ALIGNMENT) { int center = (d.height / 2); currentY = center - ( (lines.size() / 2) * fm.getHeight() ); } //else if (m_nVAlign == V_ALIGN_BOTTOM) else if (m_nVAlign == Canvas.BOTTOM_ALIGNMENT) { currentY = d.height - ( lines.size() * fm.getHeight() ); } // now we have broken into substrings, print them Enumeration elements = lines.elements(); while (elements.hasMoreElements()) { drawAlignedString(g, (String)(elements.nextElement()), 0, currentY, d.width); currentY += fm.getHeight(); } // We're done with the font metrics... fm = null; } } protected Vector breakIntoLines (String s, int width) { int fromIndex = 0; int pos = 0; int bestpos; String largestString; Vector lines = new Vector(); // while we haven't run past the end of the string... while (fromIndex != -1) { // Automatically skip any spaces at the beginning of the line while (fromIndex < text.length() && text.charAt(fromIndex) == ' ') { ++fromIndex; // If we hit the end of line while skipping spaces, we're done. if (fromIndex >= text.length()) break; } // fromIndex represents the beginning of the line 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 && // there is a newline and either ((spacePos == -1) || // 1. there is no space, or (spacePos != -1 && newlinePos < spacePos))) // 2. the newline is first { pos = newlinePos; bHardNewline = true; } else { pos = spacePos; bHardNewline = false; } // Couldn't find another space? if (pos == -1) { s = text.substring(fromIndex); } else { s = text.substring(fromIndex, pos); } // If the string fits, keep track of it. if (fm.stringWidth(s) < width) { largestString = s; bestpos = pos; // If we've hit the end of the string or a newline, use it. if (bHardNewline) bestpos++; if (pos == -1 || bHardNewline) break; } else { break; } ++pos; } if (largestString == null) { // Couldn't wrap at a space, so find the largest line // that fits and print that. Note that this will be // slightly off -- the width of a string will not necessarily // be the sum of the width of its characters, due to kerning. 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); } public Dimension getMinimumSize() { return new Dimension(100,20); } }