43

I'm currently working on the menu system for my Java game, and I wonder how I can center the text from Graphics.drawString(), so that if I want to draw a text whose center point is at X: 50 and Y: 50, and the text is 30 pixels wide and 10 pixels tall, the text will start at X: 35 and Y: 45.

Can I determine the width of the text before I draw it?
Then it would be easy maths.

EDIT: I also wonder if I can get the height of the text, so that I can center it vertically too.

Any help is appreciated!

Daniel Kvist
  • 3,032
  • 5
  • 26
  • 51
  • 2
    Looks like a duplicate of this: http://stackoverflow.com/questions/258486/calculate-the-display-width-of-a-string-in-java – mwarren Dec 30 '14 at 13:26
  • This is something that Swing makes you work for. Try this answer: http://stackoverflow.com/questions/23729944/java-how-to-visually-center-a-specific-string-not-just-a-font-in-a-rectangle If you've just started writing your game, JavaFX is the most modern graphics toolkit included with the Java platform and might be a better choice than Swing. – richj Dec 30 '14 at 15:25
  • @mwarren It is partly a duplicate, but there is one thing however. I wonder how I can get the height of the text, because `FontMetrics.getHeight() / 2` doesn't give me half of the "real" height of the text... @richj I've done pretty much already, so I think that I won't switch to JavaFX. That will be for another game. – Daniel Kvist Dec 30 '14 at 18:56
  • fontMetrics.getAscent() might be a bit better for your purposes. It does not include the "leading". – caprica Dec 30 '14 at 19:02

4 Answers4

99

I used the answer on this question.

The code I used looks something like this:

/**
 * 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);
}
Community
  • 1
  • 1
Daniel Kvist
  • 3,032
  • 5
  • 26
  • 51
  • 13
    If the Graphics g comes from the system, you should not dispose it. – Gilbert Le Blanc Nov 26 '15 at 16:21
  • 3
    Please note that this method does not use x and y of rectangle given. Instead it should be int x = rect.x + (rect.width - metrics.stringWidth(text)) / 2; and int y = rect.y + ((rect.height - metrics.getHeight()) / 2) + metrics.getAscent(); – Ishan Jain Apr 10 '17 at 09:08
8

When I have to draw text, I usually need to center the text in a bounding rectangle.

/**
 * 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);
}
Gilbert Le Blanc
  • 50,182
  • 6
  • 67
  • 111
0

I did create a function to keep the text in center of the image

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

where, graphics2DImage is.

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

    graphics2DImage.drawImage(bgImage, 0, 0, null);
Kishan Solanki
  • 13,761
  • 4
  • 85
  • 82
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);
  • As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Jul 27 '22 at 02:09