¿Cómo calcular la longitud (en píxeles) de una cadena en Java?
Preferible sin usar Swing.
EDITAR: Me gustaría dibujar la cadena usando drawString () en Java2D y usar la longitud para el ajuste de palabras.
¿Cómo calcular la longitud (en píxeles) de una cadena en Java?
Preferible sin usar Swing.
EDITAR: Me gustaría dibujar la cadena usando drawString () en Java2D y usar la longitud para el ajuste de palabras.
Respuestas:
Si solo desea usar AWT, use Graphics.getFontMetrics
(especificando opcionalmente la fuente, para una que no sea la predeterminada) para obtener un FontMetrics
y luego FontMetrics.stringWidth
para encontrar el ancho de la cadena especificada.
Por ejemplo, si tiene una Graphics
variable llamada g
, usaría:
int width = g.getFontMetrics().stringWidth(text);
Para otros conjuntos de herramientas, deberá proporcionarnos más información; siempre dependerá del conjunto de herramientas.
Graphics
, no FontMetrics
. Pero estás llamando Toolkit.getFontMetrics
, lo que de hecho está desaprobado, y no es de lo que habla este método ... debes tener mucho cuidado con este tipo de cosas, especialmente antes de comenzar a hablar sobre informar errores ...
Toolkit.getFontMetrics
sugiere en su lugar.
No siempre es necesario que dependa del kit de herramientas o no siempre es necesario utilizar el enfoque FontMetrics, ya que requiere que primero se obtenga un objeto gráfico que está ausente en un contenedor web o en un entorno sin cabeza.
He probado esto en un servlet web y calcula el ancho del 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());
Agregue los valores necesarios a estas dimensiones para crear cualquier margen requerido.
Utilice el método getWidth en la siguiente clase:
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();
}
}
Y ahora algo completamente diferente. Lo siguiente asume una fuente arial y hace una suposición salvaje basada en una interpolación lineal de caracteres frente a ancho.
// 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;
}
Interesante, pero quizás no muy práctico.
Personalmente, estaba buscando algo que me permitiera calcular el área de la cadena de varias líneas, para poder determinar si el área dada es lo suficientemente grande para imprimir la cadena, conservando una fuente 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;
}