【问题标题】:Java - Accurate Font Height without GraphicsJava - 没有图形的准确字体高度
【发布时间】:2015-03-22 09:52:02
【问题描述】:

我有一个名为 GUIText 的对象,它具有字符串文本、字体、字体样式、颜色和装饰(下划线、上划线、删除线)。我可以使用这种方法来获取 GUIText 的宽度,根据它的文本和字体:

public int getWidth() {
    return Display.getCanvas().getFontMetrics(this.font.toJavaFont()).stringWidth(
            this.text);
}

(Display.getCanvas() 返回一个 JComponent)。
我知道 getFontMetrics().getHeight(),但这会返回一个太大的数字。实际上,font.getSize() 比 getFontMetrics().getHeight() 更接近实际高度,但并不准确。我需要知道这一点,这样我才能在 GUIText 上画一条线以进行上划线装饰。

【问题讨论】:

  • FontMetrics#getHeight 将返回字体的总高度(从字体的最高点到最低点),如果没有,这通常意味着字体没有提供正确的度量信息
  • 您还应该查看Working with text APIs,了解有关如何测量字体和渲染器的更多信息

标签: java fonts


【解决方案1】:

也许TextLayout 类是您正在寻找的。它会给你确切的尺寸:

import javax.swing.*;
import java.awt.*;
import java.awt.font.*;
import java.awt.geom.*;

public class DrawTest extends JPanel
{
    String text;

    public DrawTest(String text)
    {
        this.text = text;
        setFont( new Font("Arial", Font.PLAIN, 24) );
    }

    public void paintComponent(Graphics g)
    {
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D)g;
        g2d.setFont( getFont() );
        g2d.setPaint(Color.RED);

        //  Draw text using FontMetrics

        FontMetrics fm = g2d.getFontMetrics();
        Rectangle2D rect = fm.getStringBounds(text, g2d);
        rect.setRect(rect.getX() + 100, rect.getY() + 50, rect.getWidth(), rect.getHeight());
        g2d.draw(rect);

        //  Draw text using TextLayout

        g2d.setPaint(Color.BLACK);

        Point2D loc = new Point2D.Float(100, 50);
        FontRenderContext frc = g2d.getFontRenderContext();
        TextLayout layout = new TextLayout(text, getFont(), frc);
        layout.draw(g2d, (float)loc.getX(), (float)loc.getY());

        Rectangle2D bounds = layout.getBounds();
        bounds.setRect(bounds.getX()+loc.getX(), bounds.getY()+loc.getY(), bounds.getWidth(), bounds.getHeight());
        g2d.draw(bounds);
    }

    private static void createAndShowUI()
    {
        DrawTest text = new DrawTest("This is some ugly test");

        JFrame frame = new JFrame("SSCCE");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add( text );
        frame.setSize(400, 200);
        frame.setLocationByPlatform( true );
        frame.setVisible( true );
    }

    public static void main(String[] args)
    {
        EventQueue.invokeLater(new Runnable()
        {
            public void run()
            {
                createAndShowUI();
            }
        });
    }
}

【讨论】:

  • 我无权访问 Graphics 对象
  • @MCMastery,如果您没有 Graphics 对象,您如何期望“画一条线……”?
  • 当我画一条线时,我就有了。
  • 我用我自己做的一个类作为画东西的中间人
  • When I draw a line I have it. - 那就是你应该进行计算的时候。摆脱“中间人”。
猜你喜欢
  • 2012-04-13
  • 1970-01-01
  • 1970-01-01
  • 2020-09-01
  • 2010-12-18
  • 2010-12-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多