如何在Java中绘制一个垂直居中的字符串?

我知道这是一个简单的概念,但我正在努力使用字体指标。 水平居中并不太难,但垂直方向看起来有点困难。

我尝试过各种组合使用FontMetrics getAscent,getLeading,getXXXX方法,但无论我尝试过什么,文本总是偏离几个像素。 有没有办法测量文本的确切高度,使其完全居中。

请注意,您需要准确考虑垂直居中的含义。

字体在基线上呈现,沿文本底部运行。 垂直空间分配如下:

--- ^ | leading | -- ^ YY | YY | YY | ascent Y yy | Y yy | Y yy -- baseline ______Y________y_________ | yv descent yy -- 

前导只是字体在行之间的推荐空间。 为了在两点之间垂直居中,你应该忽略前导(它的导线,BTW,而不是le ;;在一般的排版中,它是/是在印版中的线之间插入的引线间距)。

因此,为了使文本上升和下降器居中,您需要

 baseline=(top+((bottom+1-top)/2) - ((ascent + descent)/2) + ascent; 

如果没有最终的“+上升”,你就可以获得字体顶部的位置; 因此,添加上升从顶部到基线。

此外,请注意字体高度应包括前导,但某些字体不包括它,并且由于舍入差异,字体高度可能不完全相等(前导+上升+下降)。

我在这里找到了一个食谱。

关键方法似乎是getStringBounds()getAscent()

 // Find the size of string s in font f in the current Graphics context g. FontMetrics fm = g.getFontMetrics(f); java.awt.geom.Rectangle2D rect = fm.getStringBounds(s, g); int textHeight = (int)(rect.getHeight()); int textWidth = (int)(rect.getWidth()); int panelHeight= this.getHeight(); int panelWidth = this.getWidth(); // Center text horizontally and vertically int x = (panelWidth - textWidth) / 2; int y = (panelHeight - textHeight) / 2 + fm.getAscent(); g.drawString(s, x, y); // Draw the string. 

(注意:上面的代码由MIT许可证涵盖,如页面上所述。)

不确定这有用,但drawString(s, x, y)在y处设置文本的基线

我正在做一些垂直居中,并且在我注意到文档中提到的行为之前无法让文本看起来正确。 我假设字体的底部是y。

对我来说,修复是从y坐标中减去fm.getDescent()

另一个选项是TextLayout类的getBounds方法。

 Font f; // code to create f String TITLE = "Text to center in a panel."; FontRenderContext context = g2.getFontRenderContext(); TextLayout txt = new TextLayout(TITLE, f, context); Rectangle2D bounds = txt.getBounds(); int xString = (int) ((getWidth() - bounds.getWidth()) / 2.0 ); int yString = (int) ((getHeight() + bounds.getHeight()) / 2.0); // g2 is the graphics object g2.setFont(f); g2.drawString(TITLE, xString, yString);