Java:获得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。

对我来说最简单的方法是:

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

优点:

  1. 如果你调用c.getGraphics()它将返回null(因此没有图形对象)
  2. 这个(canvas)也可以在无头模式下工作。

现在您可以轻松获得高度和宽度……

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

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

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

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

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

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

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

您仍然需要进行一些偏移计算以使图像居中(假设面板大小可以改变),但这些应该相对轻量级。

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

 private static HashMap fontmetrics = new HashMap(); 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; } 

除了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变量做到这一点。