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

时间:2009-06-28 21:42:19

标签: java graphics

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

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

4 个答案:

答案 0 :(得分:48)

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

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

---
 ^
 |  leading
 |
 -- 
 ^              Y     Y
 |               Y   Y
 |                Y Y
 |  ascent         Y     y     y 
 |                 Y      y   y
 |                 Y       y y
 -- baseline ______Y________y_________
 |                         y                
 v  descent              yy
 --

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

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

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

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

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

答案 1 :(得分:11)

我找到了一份食谱here

关键方法似乎是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 License涵盖,如页面所示。​​)

答案 2 :(得分:2)

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

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

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

答案 3 :(得分:1)

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

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);