Como calcular o comprimento (em pixels) de uma string em Java?
Preferível sem usar Swing.
EDIT: Eu gostaria de desenhar a string usando o drawString () em Java2D e usar o comprimento para quebra de linha.
Como calcular o comprimento (em pixels) de uma string em Java?
Preferível sem usar Swing.
EDIT: Eu gostaria de desenhar a string usando o drawString () em Java2D e usar o comprimento para quebra de linha.
Respostas:
Se você quiser apenas usar AWT, use Graphics.getFontMetrics
(opcionalmente especificando a fonte, para uma fonte não padrão) para obter um FontMetrics
e, em seguida, FontMetrics.stringWidth
para encontrar a largura da string especificada.
Por exemplo, se você tem uma Graphics
variável chamada g
, você usa:
int width = g.getFontMetrics().stringWidth(text);
Para outros kits de ferramentas, você precisará nos fornecer mais informações - sempre dependerá do kit de ferramentas.
Graphics
, não FontMetrics
. Mas você está chamando Toolkit.getFontMetrics
, o que está de fato obsoleto, e não é sobre o que esse método fala ... você precisa ter muito cuidado com esse tipo de coisa, principalmente antes de começar a falar sobre relatar bugs ...
Toolkit.getFontMetrics
sugerem.
Nem sempre precisa ser dependente do kit de ferramentas ou nem sempre é necessário usar a abordagem FontMetrics, pois ela exige que primeiro se obtenha um objeto gráfico que está ausente em um contêiner da web ou em um ambiente sem periféricos.
Eu testei isso em um servlet da web e ele calcula a largura do texto.
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());
Adicione os valores necessários a essas dimensões para criar qualquer margem necessária.
Use o método getWidth na seguinte classe:
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();
}
}
E agora algo completamente diferente. O seguinte assume uma fonte arial e faz uma suposição com base em uma interpolação linear de caracteres x largura.
// 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;
}
Interessante, mas talvez não muito prático.
Eu pessoalmente estava procurando por algo que me permitisse calcular a área da string multilinha, para que eu pudesse determinar se determinada área é grande o suficiente para imprimir a string - preservando a fonte específica.
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;
}