如何在Java中绘制垂直中心的字符串?

2022-09-02 05:12:41

我知道这是一个简单的概念,但我正在为字体指标而苦苦挣扎。水平居中并不太难,但垂直似乎有点困难。

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


答案 1

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

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

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

行距只是字体建议的行间距。为了在两点之间垂直居中,您应该忽略引线(它是ledding,BTW,而不是leeding;在一般排版中,它是/是插入印刷版中行之间的引线间距)。

因此,对于文本升序和降序居中,您需要

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

没有最终的“+上升”,您就有字体顶部的位置;因此,添加上升将从顶部到基线。

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


答案 2

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

关键的方法似乎是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 许可证中。


推荐