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.
java
string-length
eflles
fonte
fonte
Respostas:
Se você quiser apenas usar AWT, use
Graphics.getFontMetrics
(opcionalmente especificando a fonte, para uma fonte não padrão) para obter umFontMetrics
e, em seguida,FontMetrics.stringWidth
para encontrar a largura da string especificada.Por exemplo, se você tem uma
Graphics
variável chamadag
, 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.
fonte
Graphics
, nãoFontMetrics
. Mas você está chamandoToolkit.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.
fonte
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(); } }
fonte
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.
fonte
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; }
fonte