Java中计算字符串的显示宽度

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/258486/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 12:07:48  来源:igfitidea点击:

Calculate the display width of a string in Java

javastring-length

提问by eflles

How to calculate the length (in pixels) of a string in Java?

如何在 Java 中计算字符串的长度(以像素为单位)?

Preferable without using Swing.

最好不使用 Swing。

EDIT: I would like to draw the string using the drawString() in Java2D and use the length for word wrapping.

编辑:我想在 Java2D 中使用 drawString() 绘制字符串并使用长度进行自动换行。

采纳答案by Jon Skeet

If you just want to use AWT, then use Graphics.getFontMetrics(optionally specifying the font, for a non-default one) to get a FontMetricsand then FontMetrics.stringWidthto find the width for the specified string.

如果您只想使用 AWT,则使用Graphics.getFontMetrics(可选地指定字体,对于非默认字体)获取 aFontMetrics然后FontMetrics.stringWidth查找指定字符串的宽度。

For example, if you have a Graphicsvariable called g, you'd use:

例如,如果您有一个Graphics名为的变量g,您将使用:

int width = g.getFontMetrics().stringWidth(text);

For other toolkits, you'll need to give us more information - it's always going to be toolkit-dependent.

对于其他工具包,您需要向我们提供更多信息——它总是依赖于工具包。

回答by Olofu Mark

It doesn't always need to be toolkit-dependent or one doesn't always need use the FontMetrics approach since it requires one to first obtain a graphics object which is absent in a web container or in a headless enviroment.

它并不总是需要依赖于工具包,或者并不总是需要使用 FontMetrics 方法,因为它需要首先获取 Web 容器或无头环境中不存在的图形对象。

I have tested this in a web servlet and it does calculate the text width.

我已经在 Web servlet 中对此进行了测试,它确实计算了文本宽度。

import java.awt.Font;
import java.awt.font.FontRenderContext;
import java.awt.geom.AffineTransform;

...

String text = "Hello World";
AffineTransform affinetransform = new AffineTransform();     
FontRenderContext frc = new FontRenderContext(affinetransform,true,true);     
Font font = new Font("Tahoma", Font.PLAIN, 12);
int textwidth = (int)(font.getStringBounds(text, frc).getWidth());
int textheight = (int)(font.getStringBounds(text, frc).getHeight());


Add the necessary values to these dimensions to create any required margin.

将必要的值添加到这些维度以创建任何所需的边距。

回答by Ed Poor

Use the getWidth method in the following class:

在以下类中使用 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();
  }

}

回答by wmioduszewski

I personally was searching for something to let me compute the multiline string area, so I could determine if given area is big enough to print the string - with preserving specific font.

我个人正在寻找一些东西来让我计算多行字符串区域,这样我就可以确定给定的区域是否足够大来打印字符串 - 并保留特定的字体。

I hope it would safe some time to another guy who may want to do similar job in java so just wanted to share the solution:

我希望这对另一个可能想在 Java 中做类似工作的人来说是安全的,所以只想分享解决方案:

private static Hashtable hash = new Hashtable();
private Font font;
private LineBreakMeasurer lineBreakMeasurer;
private int start, end;

public PixelLengthCheck(Font font) {
    this.font = font;
}

public boolean tryIfStringFits(String textToMeasure, Dimension areaToFit) {
    AttributedString attributedString = new AttributedString(textToMeasure, hash);
    attributedString.addAttribute(TextAttribute.FONT, font);
    AttributedCharacterIterator attributedCharacterIterator =
            attributedString.getIterator();
    start = attributedCharacterIterator.getBeginIndex();
    end = attributedCharacterIterator.getEndIndex();

    lineBreakMeasurer = new LineBreakMeasurer(attributedCharacterIterator,
            new FontRenderContext(null, false, false));

    float width = (float) areaToFit.width;
    float height = 0;
    lineBreakMeasurer.setPosition(start);

    while (lineBreakMeasurer.getPosition() < end) {
        TextLayout textLayout = lineBreakMeasurer.nextLayout(width);
        height += textLayout.getAscent();
        height += textLayout.getDescent() + textLayout.getLeading();
    }

    boolean res = height <= areaToFit.getHeight();

    return res;
}

回答by John Henckel

And now for something completelydifferent. The following assumes arial font, and makes a wild guess based on a linear interpolation of character vs width.

现在是完全不同的东西。以下假设为 arial 字体,并基于字符与宽度的线性插值进行了粗略的猜测。

// Returns the size in PICA of the string, given space is 200 and 'W' is 1000.
// see https://p2p.wrox.com/access/32197-calculate-character-widths.html

static int picaSize(String s)
{
    // the following characters are sorted by width in Arial font
    String lookup = " .:,;'^`!|jl/\i-()JfIt[]?{}sr*a\"ce_gFzLxkP+0123456789<=>~qvy$SbduEphonTBCXY#VRKZN%GUAHD@OQ&wmMW";
    int result = 0;
    for (int i = 0; i < s.length(); ++i)
    {
        int c = lookup.indexOf(s.charAt(i));
        result += (c < 0 ? 60 : c) * 7 + 200;
    }
    return result;
}

Interesting, but perhaps not very practical.

有趣,但可能不太实用。