Wie berechnet man die Länge (in Pixel) eines Strings in Java?
Am besten ohne Swing.
BEARBEITEN: Ich möchte den String mit drawString () in Java2D zeichnen und die Länge für den Zeilenumbruch verwenden.
Wie berechnet man die Länge (in Pixel) eines Strings in Java?
Am besten ohne Swing.
BEARBEITEN: Ich möchte den String mit drawString () in Java2D zeichnen und die Länge für den Zeilenumbruch verwenden.
Antworten:
Wenn Sie nur AWT verwenden möchten, verwenden Sie Graphics.getFontMetrics
(optional die Schriftart angeben , für eine nicht standardmäßige), um eine zu erhalten FontMetrics
und dann FontMetrics.stringWidth
die Breite für die angegebene Zeichenfolge zu ermitteln.
Wenn Sie beispielsweise eine Graphics
Variable namens haben g
, verwenden Sie:
int width = g.getFontMetrics().stringWidth(text);
Für andere Toolkits müssen Sie uns weitere Informationen geben - es wird immer Toolkit-abhängig sein.
Graphics
, nicht FontMetrics
. Aber Sie rufen an Toolkit.getFontMetrics
, was in der Tat veraltet ist und worüber diese Methode nicht spricht ... Sie müssen bei solchen Dingen wirklich vorsichtig sein, insbesondere bevor Sie über das Melden von Fehlern sprechen ...
Toolkit.getFontMetrics
stattdessen vorschlagen .
Es muss nicht immer vom Toolkit abhängig sein oder es muss nicht immer der FontMetrics-Ansatz verwendet werden, da zuerst ein Grafikobjekt abgerufen werden muss, das in einem Webcontainer oder in einer kopflosen Umgebung fehlt.
Ich habe dies in einem Web-Servlet getestet und es berechnet die Textbreite.
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());
Fügen Sie diesen Dimensionen die erforderlichen Werte hinzu, um den erforderlichen Rand zu erstellen.
Verwenden Sie die Methode getWidth in der folgenden Klasse:
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();
}
}
Und jetzt zu etwas ganz anderem. Das Folgende nimmt eine ariale Schriftart an und macht eine wilde Vermutung basierend auf einer linearen Interpolation von Zeichen gegen Breite.
// 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;
}
Interessant, aber vielleicht nicht sehr praktisch.
Ich persönlich habe nach etwas gesucht, mit dem ich den mehrzeiligen Zeichenfolgenbereich berechnen kann, damit ich feststellen kann, ob der angegebene Bereich groß genug ist, um die Zeichenfolge zu drucken - unter Beibehaltung einer bestimmten Schriftart.
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;
}