我知道这是一个简单的概念,但我用的字体规格挣扎。 水平居中是不是太辛苦,但垂直似乎有点困难。
我使用的FontMetrics的getAscent,getLeading,以各种组合的getXXXX方法试过,但不管是什么我已经试过文本始终是关闭的几个像素。 有没有要测量的文本的精确高度,使其恰好为中心的方式。
我知道这是一个简单的概念,但我用的字体规格挣扎。 水平居中是不是太辛苦,但垂直似乎有点困难。
我使用的FontMetrics的getAscent,getLeading,以各种组合的getXXXX方法试过,但不管是什么我已经试过文本始终是关闭的几个像素。 有没有要测量的文本的精确高度,使其恰好为中心的方式。
请注意,你就需要精确地考虑您的垂直居中的意思。
字体呈现在基线,沿着文本的底部运行。 垂直空间分配如下:
---
^
| 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,顺便说一句,不leeding;通常排版它是/是在一个印刷板线之间插入的引线间距)。
所以对于居中文本上行字母和下行,你想要的
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。
对我来说,伦敦定盘减去fm.getDescent()
从y坐标。
另一种选择是的getBounds从方法的TextLayout类 。
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);