65.9K
CodeProject 正在变化。 阅读更多。
Home

如何在 AWT 中创建换行和/或多行标签。

starIconstarIconstarIconstarIconstarIcon

5.00/5 (1投票)

2001 年 8 月 13 日

1分钟阅读

viewsIcon

72883

如何在 AWT 中创建换行和/或多行标签

引言

VWrappingLabel 基于 Symantec 的 WrappingLabel。以下摘自 Daniel Kirkdorffers Visual Cafe Tips,这是最初发现这段代码的地方的一段简短描述。

Symantec 的 WrappingLabel 是一个非常方便的组件。除了能够自动换行标签文本以适应组件的宽度之外,WrappingLabel 还可以作为基本 Label 组件的一个很好的替代品,在您想要修改标签的前景色或背景色时使用。

许多人询问 WrappingLabel 是否可以考虑换行符“\n”在换行时强制换行。不幸的是,WrappingLabel 会忽略换行符。但是,为了响应这种兴趣,Paul Williams 编写了 WrappingLabel 的另一个版本,该版本可以处理换行符。我拥有源代码、编译后的类文件和 .desc 描述文件的副本。在 Visual Café 中使用此组件的关键是在代码中使用 setText() 方法设置标签的文本,而不是在设计时在属性列表窗口中设置文本。否则,Visual Café 会将“\n”替换为“\\n”。Paul 还添加了一个很好的功能,即通过 setHAlignStyle()setVAlignStyle() 方法或通过替代构造函数设置文本的水平和垂直对齐方式。

感谢 Paul Williams,他曾就职于 Criterion Inc. 我试图联系您,但似乎您的旧电子邮件地址已经失效了。我保证我只做了一些小的修改。

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;

/**
 * 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);
    }
}
© . All rights reserved.