Java(AWT):在一个框中拟合文本

时间:2009-11-22 19:30:24

标签: java fonts awt

我有一个扩展Frame的应用程序。然后,它将使用以下内容显示几行文字:

Font f = new Font("Arial", Font.PLAIN, 10);
g.setFont(f);
g.drawString("Test|great Yes ^.", x, y + 10);

现在发生的事情是文本不适合在框中。例如。我期待文本适合[x,y] - [x +宽度,y + 10](不关心宽度),但它略低于y + 10线。现在对于大多数人物('T','e'等),这适合但是'|'并且'g'没有!它们低于y + 10线。看来你不能用:在y + characterHeight画画。但是有什么用呢?

要了解我的意思,这里有一些示例代码:

import java.awt.*;

public class test extends Frame
{
        public test()
        {
                /* retrieve max window size */
                GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
                GraphicsDevice[] gs = ge.getScreenDevices();
                GraphicsConfiguration [] gc = gs[0].getConfigurations();
                Rectangle r = gc[0].getBounds();
                setSize(r.width, r.height);
                setVisible(true);
        }

        public void paint(Graphics g)
        {
                final int windowWidth  = getSize().width;
                final int windowHeight = getSize().height;
                g.setColor(Color.BLUE);
                g.fillRect(0, 0, windowWidth, windowHeight);
                g.setColor(Color.WHITE);
                g.fillRect(0, 100, windowWidth, 110);
                int textHeight = 100;
                Font f = new Font("Arial", Font.PLAIN, textHeight);
                g.setFont(f);
                g.setColor(Color.BLACK);
                g.drawString("Test|great Yes ^.", 10, 100 + textHeight);
        }

        public void guiLoop()
        {
                for(;;) { try { Thread.sleep(1000); } catch(Exception e) { } }
        }

        public static void main(String [] args)
        {
                new test().guiLoop();
        }
}

我也尝试了以下代码:

public void paint(Graphics g)
{
        final int windowWidth  = getSize().width;
        final int windowHeight = getSize().height;
        g.setColor(Color.BLUE);
        g.fillRect(0, 0, windowWidth, windowHeight);
        g.setColor(Color.WHITE);
        g.fillRect(0, 100, windowWidth, 110);
        int textHeight = 100;

        String str = "Test|great Yes ^.";
        Font f = new Font("Arial", Font.PLAIN, textHeight);
        Rectangle2D boundingRectangle = f.getStringBounds(str, 0, str.length(), new FontRenderContext(null, false, false));
        f = f.deriveFont((float)(textHeight * (textHeight / boundingRectangle.getHeight())));
        boundingRectangle = f.getStringBounds(str, 0, str.length(), new FontRenderContext(null, false, false));
        g.drawString(str, 10, 100 + (int)boundingRectangle.getHeight());

        g.setFont(f);
        g.setColor(Color.BLACK);
        g.drawString(str, 10, 100 + textHeight);
}

这稍微好一点:文字较小,因此可能适合,但仍然存在y位置不正确的问题。

感谢所有帮助!

2 个答案:

答案 0 :(得分:4)

使用FontMetrics怎么样?您可以使用Graphicsg.getFontMetrics()对象获取它。

你可以检索最大下降或上升或直接高度(使用getHeight),因此你的实现将是字体独立的,它应该工作正常..检查文档here

编辑(解释评论): 没有一种直接的方法可以告诉字符串以适合盒子的方式绘制自己。你必须自己做..比如从最大字体大小开始并检查宽度是否适合盒子,否则减小尺寸并再试一次。对于高度,你应该首先决定(或获得)最大字体高度,然后你可以设置盒子应该有多少像素。

答案 1 :(得分:0)

我想我解决了一下:

boundingBoxHeight:文本应适合的框的高度 yOffset从哪里开始绘制字体

            Font f = new Font("Arial", Font.PLAIN, boundingBoxHeight);
            g.setFont(f);
            FontMetrics fm = g.getFontMetrics();
            double shrink = ((double)textHeight / (double)fm.getHeight());
            double newSize = (double)textHeight * shrink;
            double newAsc  = (double)fm.getAscent() * shrink;
            int yOffset = (int)newAsc - fm.getLeading();
            f = f.deriveFont((float)newSize);
            g.setFont(f);

            g.drawString(str, 10, 100 + yOffset);

虽然文本上方有很多空白。