I am using java to draw some text, but it is hard for me to calculate the string's width. for example: zheng中国... How long will this string occupy?
-
Possible duplicate of [Calculate the display width of a string in Java](http://stackoverflow.com/questions/258486/calculate-the-display-width-of-a-string-in-java) – Iman Nia Apr 09 '17 at 13:11
6 Answers
For a single string, you can obtain the metrics for the given drawing font, and use that to calculate the string size. For example:
String message = new String("Hello, StackOverflow!");
Font defaultFont = new Font("Helvetica", Font.PLAIN, 12);
FontMetrics fontMetrics = new FontMetrics(defaultFont);
//...
int width = fontMetrics.stringWidth(message);
If you have more complex text layout requirements, such as flowing a paragraph of text within a given width, you can create a java.awt.font.TextLayout
object, such as this example (from the docs):
Graphics2D g = ...;
Point2D loc = ...;
Font font = Font.getFont("Helvetica-bold-italic");
FontRenderContext frc = g.getFontRenderContext();
TextLayout layout = new TextLayout("This is a string", font, frc);
layout.draw(g, (float)loc.getX(), (float)loc.getY());
Rectangle2D bounds = layout.getBounds();
bounds.setRect(bounds.getX()+loc.getX(),
bounds.getY()+loc.getY(),
bounds.getWidth(),
bounds.getHeight());
g.draw(bounds);

- 19,278
- 3
- 45
- 60
-
21
-
3
-
java.awt.FontMetrics is abstract; cannot be instantiated FontMetrics metrics = new FontMetrics(font); I found somewhere else that you have to put an empty pair of curly braces after the (font) and before the semicolon. I have no idea why. FontMetrics metrics = new FontMetrics(font) {}; – Ed Poor Aug 26 '13 at 16:40
-
@EdPoor FontMetrics is an abstract class (with no abstract methods). You are generating an anonymous subclass that doesn't override anything, ergo it can be a concrete class. Interestingly, the javadoc for FontMetrics says: "Note to subclassers: Since many of these methods form closed, mutually recursive loops, you must take care that you implement at least one of the methods in each such loop to prevent infinite recursion when your subclass is used." i.e. new FontMetrics(font) {} might "work", but it may or may not actually do the right thing. Strange choices, if the docs are to be believed – James Aug 26 '13 at 17:05
-
here is a simple app that can show you how to use FontMetrics when testing the width of a String:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class GUITest {
JFrame frame;
public static void main(String[] args){
new GUITest();
}
public GUITest() {
frame = new JFrame("test");
frame.setSize(300,300);
addStuffToFrame();
SwingUtilities.invokeLater(new Runnable(){
public void run() {
frame.setVisible(true);
}
});
}
private void addStuffToFrame() {
JPanel panel = new JPanel(new GridLayout(3,1));
final JLabel label = new JLabel();
final JTextField tf = new JTextField();
JButton b = new JButton("calc sting width");
b.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
FontMetrics fm = label.getFontMetrics(label.getFont());
String text = tf.getText();
int textWidth = fm.stringWidth(text);
label.setText("text width for \""+text+"\": " +textWidth);
}
});
panel.add(label);
panel.add(tf);
panel.add(b);
frame.setContentPane(panel);
}
}

- 38,619
- 8
- 86
- 96
Take a look at this great presentation, especially "Text Measurement" part. It explains available sizes and their uses: Advanced Java 2D™ topics for Desktop Applications.
Some more information in Java2D FAQ: What is the difference between logical, visual and pixel bounds?

- 16,188
- 39
- 30

- 32,463
- 16
- 90
- 116
Use the getWidth method in the following class:
import java.awt.*;
import java.awt.geom.*;
import java.awt.font.*;
class StringMetrics {
Font font;
FontRenderContext context;
public StringMetrics(Graphics2D g2) {
font = g2.getFont();
context = g2.getFontRenderContext();
}
Rectangle2D getBounds(String message) {
return font.getStringBounds(message, context);
}
double getWidth(String message) {
Rectangle2D bounds = getBounds(message);
return bounds.getWidth();
}
double getHeight(String message) {
Rectangle2D bounds = getBounds(message);
return bounds.getHeight();
}
}

- 1,849
- 20
- 13
You can find it from Font.getStringBounds():
String string = "Hello World";
// Passing or initializing an instance of Font.
Font font = ...;
int width = (int) font.getStringBounds(string, new FontRenderContext(font.getTransform(), false, false)).getBounds().getWidth();

- 1
- 1