How can I center Graphics.drawString() in Java?
Asked Answered
A

4

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!

Aidoneus answered 30/12, 2014 at 13:15 Comment(4)
Looks like a duplicate of this: #258986Pascal
This is something that Swing makes you work for. Try this answer: #23730444 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.Valenti
@Pascal 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... @Valenti I've done pretty much already, so I think that I won't switch to JavaFX. That will be for another game.Aidoneus
fontMetrics.getAscent() might be a bit better for your purposes. It does not include the "leading".Rey
A
100

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);
}
Aidoneus answered 2/1, 2015 at 10:0 Comment(2)
If the Graphics g comes from the system, you should not dispose it.Duodecimal
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();Crackle
D
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);
}
Duodecimal answered 30/12, 2014 at 19:8 Comment(0)
M
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);
Mcnamee answered 15/6, 2020 at 9:43 Comment(0)
S
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);
Sallie answered 24/7, 2022 at 18:26 Comment(1)
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.Venetis

© 2022 - 2024 — McMap. All rights reserved.