Как рассчитать ширину шрифта?

Я использую java для рисования текста, но мне сложно рассчитать ширину строки. например: zheng 中国 ... Как долго будет занимать эта строка?


person MemoryLeak    schedule 06.10.2009    source источник


Ответы (6)


Для одной строки вы можете получить метрики для данного шрифта чертежа и использовать их для вычисления размера строки. Например:

String      message = new String("Hello, StackOverflow!");
Font        defaultFont = new Font("Helvetica", Font.PLAIN, 12);
FontMetrics fontMetrics = new FontMetrics(defaultFont);
//...
int width = fontMetrics.stringWidth(message);

Если у вас есть более сложные требования к макету текста, например, размещение абзаца текста в пределах заданной ширины, вы можете создать _ 2_, например, в этом примере (из документации):

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);
person gavinb    schedule 06.10.2009
comment
Невозможно создать экземпляр типа FontMetrics. - person Sam Washburn; 19.10.2011
comment
Использование: FontMetrics fontMetrics = g.getFontMetrics (); - person Thomas Padron-McCarthy; 20.10.2011
comment
java.awt.FontMetrics является абстрактным; невозможно создать экземпляр FontMetrics metrics = new FontMetrics (font); Я где-то еще нашел, что вам нужно поставить пустую пару фигурных скобок после (шрифта) и перед точкой с запятой. Понятия не имею почему. Метрики FontMetrics = новый FontMetrics (font) {}; - person Ed Poor; 26.08.2013
comment
@EdPoor FontMetrics - это абстрактный класс (без абстрактных методов). Вы создаете анонимный подкласс, который ничего не отменяет, следовательно, это может быть конкретный класс. Интересно, что в javadoc для FontMetrics говорится: Примечание для подклассов: поскольку многие из этих методов образуют замкнутые, взаимно рекурсивные циклы, вы должны позаботиться о том, чтобы реализовать хотя бы один из методов в каждом таком цикле, чтобы предотвратить бесконечную рекурсию при использовании вашего подкласса. . то есть new FontMetrics (font) {} может работать, но на самом деле он может делать или не делать правильные вещи. Странный выбор, если верить документам - person James; 26.08.2013
comment
@gavinb, как я могу использовать его для текста html - person Yashpal Singla; 14.02.2014

См. Graphics.getFontMetrics () и FontMetrics.stringWidth ().

person Bombe    schedule 06.10.2009

вот простое приложение, которое может показать вам, как использовать FontMetrics при проверке ширины строки:

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


}
person akf    schedule 06.10.2009

Взгляните на эту отличную презентацию, особенно на часть «Измерение текста». В нем объясняются доступные размеры и их использование: Расширенные разделы Java 2D ™ для Настольные приложения.

Дополнительная информация приведена в FAQ по Java2D: в чем разница между логическим, визуальным и границы пикселей?

person Peter Štibraný    schedule 06.10.2009
comment
Ссылка на темы Advanced Java 2D ™ для настольных приложений мертва. - person dastrobu; 12.10.2015

Используйте метод getWidth в следующем классе:

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

}
person Ed Poor    schedule 26.08.2013

Вы можете найти его в 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();
person Mergen Wu    schedule 02.04.2015
comment
Пожалуйста, объясните свое решение - person Jens; 02.04.2015