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);
优点:
- 如果你调用c.getGraphics()它将返回null(因此没有图形对象)
- 这个(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变量做到这一点。