2008-11-03 26 views
72

¿Cómo se calcula la longitud (en píxeles) de una cadena en Java?Calcular el ancho de visualización de una cadena en Java

Preferible sin usar Swing.

EDIT: Me gustaría dibujar la cadena usando el drawString() en Java2D y usar la longitud para el ajuste de palabras.

+4

Sin oscilación? ¿Qué dispositivo estás usando? ¿Qué fuente? ¿Qué tamaño? ¿Que estilo? Todas estas cosas cambian el ancho de la pantalla. –

+1

@S. Lott. Lo tienes en uno. Estuve tentado de cerrar esto como no cuestionario. –

+1

@David Arno: soy un softie en el n00bz. Agregaré la etiqueta [principiante]. –

Respuesta

108

Si lo que desea es utilizar AWT, a continuación, utilizar Graphics.getFontMetrics (opcionalmente especificar el tipo de letra, por una no-default) para obtener una FontMetrics y luego FontMetrics.stringWidth para encontrar el ancho de la cadena especificada.

Por ejemplo, si tiene una variable llamada Graphicsg, tendrá que utilizar:

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

Para otros juegos de herramientas, tendrá que darnos más información - que siempre va a ser dependiente de kit de herramientas .

+6

Podría ser más claro si proporciona un ejemplo de uso, inicialmente intenté usarlo como un método estático, como lo ha escrito de esa manera. – Aequitas

+0

¡Desaprobado! ¡pero sigue siendo el mejor método !, ¿por qué desaprueban un método cuando no hay una mejor manera de hacerlo? ¡Simplemente no entiendo! – Zich

+2

@Zich: No estoy seguro de qué método está diciendo que está en desuso, ninguno de ellos está marcado como obsoleto en la documentación de Java 8 por lo que puedo ver ... –

38

No siempre tiene que ser dependiente del kit de herramientas o no siempre se necesita usar el enfoque de FontMetrics ya que primero se requiere obtener un objeto de gráficos 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()); 

Añadir los valores necesarios para estas dimensiones para crear cualquier margen requerido.

+1

No creo que la creación de una affinTransform y un fontRenderContext de esta manera dará como resultado un buen comportamiento. Supongo que font.getTransfrom() sería más lógico. – Lyth

+1

Su ejemplo todavía está utilizando la funcionalidad AWT. Con SWT Font, por ejemplo, no va a funcionar, esta es la razón por la que "siempre va a depender el juego de herramientas" –

+1

@Olofu Mark - getStringBounds solo da los límites lógicos. Para hacerlo mejor, debería usar getBounds() y el objeto LineMetrics para recuperar la altura real, incluido, ascenso + descenso. – Jones

7

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

} 
0

Yo personalmente estaba buscando algo que me permita calcular el área de cadena de varias líneas, por lo que podría determinar si el área dada es suficientemente grande como para imprimir la cadena - con la preservación de la fuente específica.

espero que sería seguro un tiempo a otro tipo que puedan querer hacer trabajo similar en Java por lo que sólo quería compartir la solución:

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; 
} 
Cuestiones relacionadas