我试图在JPanel上以视觉方式居中用户提供的任意字符串.我已经在SO上阅读了几十个其他类似的问题和答案,但没有发现任何直接解决我遇到的问题.
在下面的代码示例中,getWidth()和getHeight()引用我放置文本字符串的JPanel的宽度和高度.我发现TextLayout.getBounds()非常好地告诉我包含文本的边界矩形的大小.因此,我认为通过计算文本边界矩形左下角的JPanel上的x和y位置,将文本矩形居中在JPanel矩形中会相对简单:
FontRenderContext context = g2d.getFontRenderContext();
messageTextFont = new Font("Arial", Font.BOLD, fontSize);
TextLayout txt = new TextLayout(messageText, messageTextFont, context);
Rectangle2D bounds = txt.getBounds();
xString = (int)((getWidth() - (int)bounds.getWidth()) / 2 );
yString = (int)((getHeight()/2) + (int)(bounds.getHeight()/2));
g2d.setFont(messageTextFont);
g2d.setColor(rxColor);
g2d.drawString(messageText, xString, yString);
Run Code Online (Sandbox Code Playgroud)
这适用于全部大写的字符串.但是,当我开始使用带有下行字符的小写字母(如g,p,y)进行测试时,文本不再居中.小写字母上的下延(在字体基线下方延伸的部分)在JPanel上绘制得太低,使文本看起来居中.
那时我发现(感谢SO)传递给drawString()的y参数指定了绘制文本的基线,而不是下限.因此,再次在SO的帮助下,我意识到我需要通过字符串中下划线的长度来调整文本的位置:
....
TextLayout txt = new TextLayout(messageText, messageTextFont, context);
Rectangle2D bounds = txt.getBounds();
int descent = (int)txt.getDescent();
xString = (int)((getWidth() - (int)bounds.getWidth()) / 2 );
yString = (int)((getHeight()/2) + (int)(bounds.getHeight()/2) - descent); …Run Code Online (Sandbox Code Playgroud)