在Java中,如何使Graphics.drawString()居中?

43

我目前正在为我的Java游戏设计菜单系统,我想知道如何让Graphics.drawString()中的文本居中,这样如果我想要绘制一个文本,它的中心点在X: 50Y: 50,而文本的宽度为30像素,高度为10像素,则文本将从X: 35Y: 45处开始。

我能在绘制前确定文本的宽度吗?
那么这就是简单的数学问题。

编辑:我也想知道是否可以获取文本的高度,以便我也可以垂直居中。

任何帮助都将不胜感激!


2
看起来是这个的重复:https://dev59.com/qnVC5IYBdhLWcg3wixw0 - mwarren
这是Swing让你为之努力的事情。试试这个回答:https://dev59.com/M2Ag5IYBdhLWcg3wU5m8 如果你刚开始写游戏,JavaFX是Java平台中最现代的图形工具包,比Swing更好的选择。 - richj
@mwarren 这部分是重复的,但有一件事情。我想知道如何获取文本的高度,因为 FontMetrics.getHeight() / 2 并不能给我文本“真实”高度的一半... @richj 我已经完成了大部分工作,所以我认为我不会转向JavaFX。那将是另一个游戏的事情。 - Daniel Kvist
fontMetrics.getAscent() 对于你的目的可能会更好一些。它不包括“leading”。 - caprica
4个回答

99

我使用了这个问题上的答案。

我使用的代码大致如下:

/**
 * Draw a String centered in the middle of a Rectangle.
 *
 * @param g The Graphics instance.
 * @param text The String to draw.
 * @param rect The Rectangle to center the text in.
 */
public void drawCenteredString(Graphics g, String text, Rectangle rect, Font font) {
    // Get the FontMetrics
    FontMetrics metrics = g.getFontMetrics(font);
    // Determine the X coordinate for the text
    int x = rect.x + (rect.width - metrics.stringWidth(text)) / 2;
    // Determine the Y coordinate for the text (note we add the ascent, as in java 2d 0 is top of the screen)
    int y = rect.y + ((rect.height - metrics.getHeight()) / 2) + metrics.getAscent();
    // Set the font
    g.setFont(font);
    // Draw the String
    g.drawString(text, x, y);
}

13
如果 Graphics g 是来自系统的,你不应该对其进行处理。 - Gilbert Le Blanc
3
请注意,此方法不使用给定矩形的 x 和 y 值。相反,应该是 int x = rect.x + (rect.width - metrics.stringWidth(text)) / 2; 和 int y = rect.y + ((rect.height - metrics.getHeight()) / 2) + metrics.getAscent(); - Ishan Jain

8
当我需要绘制文本时,通常需要将文本居中在一个边界矩形中。
/**
 * This method centers a <code>String</code> in 
 * a bounding <code>Rectangle</code>.
 * @param g - The <code>Graphics</code> instance.
 * @param r - The bounding <code>Rectangle</code>.
 * @param s - The <code>String</code> to center in the
 * bounding rectangle.
 * @param font - The display font of the <code>String</code>
 * 
 * @see java.awt.Graphics
 * @see java.awt.Rectangle
 * @see java.lang.String
 */
public void centerString(Graphics g, Rectangle r, String s, 
        Font font) {
    FontRenderContext frc = 
            new FontRenderContext(null, true, true);

    Rectangle2D r2D = font.getStringBounds(s, frc);
    int rWidth = (int) Math.round(r2D.getWidth());
    int rHeight = (int) Math.round(r2D.getHeight());
    int rX = (int) Math.round(r2D.getX());
    int rY = (int) Math.round(r2D.getY());

    int a = (r.width / 2) - (rWidth / 2) - rX;
    int b = (r.height / 2) - (rHeight / 2) - rY;

    g.setFont(font);
    g.drawString(s, r.x + a, r.y + b);
}

0
var text = "trying something";
graphics.setFont(font);    
var textWidth = graphics.getFontMetrics().stringWidth(text);
var horizontalPosition = ((yourBufferedImage.getWidth())/2) - (textWidth/2);
var verticalPosition = yourBufferedImage.getHeight()/2;
graphics.drawString(text, horizontalPosition, verticalPosition);

目前您的回答写得不太清楚。请[编辑]以添加更多细节,帮助其他人了解它如何回答所提出的问题。您可以在帮助中心找到有关编写好回答的更多信息。 - Community

0
我创建了一个函数来使文本保持在图像中心。
    private static void setTextCenter(Graphics2D graphics2DImage, String string,
                                        BufferedImage bgImage) {
    int stringWidthLength = (int)
            graphics2DImage.getFontMetrics().getStringBounds(string, graphics2DImage).getWidth();
    int stringHeightLength = (int)
            graphics2DImage.getFontMetrics().getStringBounds(string, graphics2DImage).getHeight();

    int horizontalCenter = bgImage.getWidth() / 2 - stringWidthLength / 2;
    int verticalCenter = bgImage.getHeight() / 2 - stringHeightLength / 2;
    graphics2DImage.drawString(string, horizontalCenter, verticalCenter);
}

其中,graphics2DImage是。

Graphics2D graphics2DImage = bgImage.createGraphics();
graphics2DImage.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
            RenderingHints.VALUE_ANTIALIAS_ON);

    graphics2DImage.drawImage(bgImage, 0, 0, null);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接