13

I use drawString() method to draw string using Graphics, but I want to center my text in a rectangle. How should I do that?

tenorsax
  • 21,123
  • 9
  • 60
  • 107
Luka Tiger
  • 298
  • 2
  • 4
  • 10
  • 1
    Your title states, you're using `JTextField`, but not your question. So which is true? – Mordechai Jan 11 '13 at 18:51
  • Your title is: *Java center text in textfield* but your post says: *I use `drawString()` method to draw string on Graphics, but I want to center my text in a rectangle. How should I do that?* how does this correspond – David Kroukamp Jan 11 '13 at 18:59
  • To correct my question: I have a rectangle somewhere in the JFrame.... I want to draw string centered in that rectangle. How should i do that? – Luka Tiger Jan 11 '13 at 23:00
  • Read about the [`FontMetrics`](http://docs.oracle.com/javase/6/docs/api/java/awt/FontMetrics.html) class – Mordechai Jan 11 '13 at 18:53

2 Answers2

32

I've used this to center text on a JPanel

        Graphics2D g2d = (Graphics2D) g;
        FontMetrics fm = g2d.getFontMetrics();
        Rectangle2D r = fm.getStringBounds(stringTime, g2d);
        int x = (this.getWidth() - (int) r.getWidth()) / 2;
        int y = (this.getHeight() - (int) r.getHeight()) / 2 + fm.getAscent();
        g.drawString(stringTime, x, y);
Gilbert Le Blanc
  • 50,182
  • 6
  • 67
  • 111
  • 3
    Centring text vertically is little more involved, because of the text ascent and the way that text is rendered. From memory, it should be more like y = ((getHeight() - fm.getHeight()) / 2) + fm.getAscent(); ... Try drawing a line across the components centre line and compare the two method, if my memory is serving me well, I believe this will be more properly centered ... +1 – MadProgrammer Jan 11 '13 at 20:12
  • 1
    You might also like to have a read through [this](http://stackoverflow.com/questions/1055851/how-do-you-draw-a-string-centered-vertically-in-java) – MadProgrammer Jan 11 '13 at 20:39
  • 1
    I think I liked the appearance better when I centered the baseline. :-) – Gilbert Le Blanc Jan 11 '13 at 20:42
  • 1
    It comes down to what you want, I prefer the text to be vertically based on the visual centre position, but that's just me ;) – MadProgrammer Jan 11 '13 at 21:24
21

Centering text has a lot of "options". Do you center absolutely or based on the base line??

enter image description here

Personally, I prefer the absolute center position, but it depends on what you are doing...

public class CenterText {

    public static void main(String[] args) {
        new CenterText();
    }

    public CenterText() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame("Test");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }

        });
    }

    public class TestPane extends JPanel {

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            int height = getHeight();
            String text = "This is a test xyx";

            g.setColor(Color.RED);
            g.drawLine(0, height / 2, getWidth(), height / 2);

            FontMetrics fm = g.getFontMetrics();
            int totalWidth = (fm.stringWidth(text) * 2) + 4;

            // Baseline
            int x = (getWidth() - totalWidth) / 2;
            int y = (getHeight() - fm.getHeight()) / 2;
            g.setColor(Color.BLACK);

            g.drawString(text, x, y + ((fm.getDescent() + fm.getAscent()) / 2));

            // Absolute...
            x += fm.stringWidth(text) + 2;
            y = ((getHeight() - fm.getHeight()) / 2) + fm.getAscent();
            g.drawString(text, x, y);

        }

    }

}
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366