Java:获得FontMetrics实例的更方便的方法

时间:2010-05-02 13:00:36

标签: java java-2d fontmetrics

是否有更友好的方式来获取FontMetrics的实例而不是

FontMetrics fm = Graphics.getFontMetrics(Font);

我讨厌这种方式,原因如下:

如果您想在游戏中创建一个菜单,并且您希望屏幕中心的所有菜单项都需要fontmetrics。但是,大多数情况下,菜单项是可点击的。所以我创建了一个Rectangles数组,并且所有矩形都适合于项目,因此当按下鼠标时,我可以简单地使用

for (int i = 0; i < rects.length; i++)
if (rects[i].contains(mouseX, mouseY)) { ... }

但是为了创建rects,我还需要FontMetrics作为它们的坐标。所以这意味着我必须在菜单的paint-method中构造所有的矩形。

所以我想要一种获取FontMetrics的方法,这样我就可以在构造函数调用的方法中构造Rectangles。

6 个答案:

答案 0 :(得分:10)

对我而言,最简单的方法是:

Font font = new Font("Helvetica",Font.PLAIN,12);
Canvas c = new Canvas();
FontMetrics fm = c.getFontMetrics(font);

优点:

  1. 如果你调用c.getGraphics(),它将返回null(因此没有图形对象)
  2. 这个(画布)也可以在无头模式下工作。
  3. 现在你可以轻松获得高度和宽度......

答案 1 :(得分:5)

真正正确的答案是使用Toolkit。

Font font = new Font("Courier New", Font.PLAIN, 14);
FontMetrics fm = Toolkit.getDefaultToolkit().getFontMetrics(font);

答案 2 :(得分:2)

一旦背景组件(即菜单后面的任何内容)被渲染,它就会有一个Graphics对象,您可以使用它来获取给定字体的指标,只需一次。

您当然不希望在paint方法中执行此操作,该方法应尽可能轻量级。我将此代码挂在一个首次呈现组件时调用的侦听器上。它可以将生成的FontMetrics对象存储在稍后可以访问它的位置,可以使用paint方法绘制这些菜单项框。

不是在最后时刻确定菜单图形的测量值,而是在paint时确定,而不是创建一些组件来表示菜单。您可以将这些组件放在Glass Pane more info here上,这样它们就可以浮动到其他所有组件上,并且您将获得额外的好处,即这些组件都能够接受鼠标点击并在其上触发侦听器事件,并且他们只捕捉自己几何体上的事件,你甚至不需要弄清楚点击的哪个部分被点击了,如果有的话。

此处使用组件的另一个好处是,您可以完全满足摆弄字体指标的要求。有现成的菜单项,或者您可以使用JLabels,并且可以指定它们的对齐方式,您可以使用LayoutManager将框的大小调整为最大标签的宽度,依此类推

答案 3 :(得分:1)

假设菜单文本已修复,您可以预先将文本绘制到具有Alpha透明度的BufferedImage,然后进行计算。然后,当您需要菜单文本时,只需绘制图像。

你仍然需要做一些偏移计算来使图像居中(假设面板尺寸可以改变),但这些应该相对轻量级。

答案 4 :(得分:0)

我认为这是一个很好的解决方案

private static HashMap<Font, FontMetrics> fontmetrics = new HashMap<Font, FontMetrics>();


public static FontMetrics getFontMetrics(Font font)
{
    if (fontmetrics.containsKey(font))
    {
        return fontmetrics.get(font);
    }
    FontMetrics fm = createFontMetrics(font);
    fontmetrics.put(font, fm);
    return fm;
}

private static FontMetrics createFontMetrics(Font font)
{
    BufferedImage bi = new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB_PRE);
    Graphics g = bi.getGraphics();
    FontMetrics fm = g.getFontMetrics(font);
    g.dispose();
    bi = null;
    return fm;
}

答案 5 :(得分:0)

除了Lonzak所说的,这是怎么回事:

public static FontMetrics getFontMetrics(Font font){
    GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
    GraphicsDevice gd = ge.getDefaultScreenDevice();
    GraphicsConfiguration config = gd.getDefaultConfiguration();

    Canvas c = new Canvas(config);
    return c.getFontMetrics(font);
}

您可以将'config'变量存储为静态变量,因此它在一些实用程序字体类中构造一次,该类包含游戏/开发环境的其他字体相关信息。我猜你也可以用canvas变量做到这一点。