Come calcolare la lunghezza (in pixel) di una stringa in Java?
Preferibile senza usare Swing.
EDIT: vorrei disegnare la stringa usando drawString () in Java2D e usare la lunghezza per il wrapping delle parole.
Come calcolare la lunghezza (in pixel) di una stringa in Java?
Preferibile senza usare Swing.
EDIT: vorrei disegnare la stringa usando drawString () in Java2D e usare la lunghezza per il wrapping delle parole.
Risposte:
Se vuoi solo usare AWT, usa Graphics.getFontMetrics(opzionalmente specificando il carattere, per uno non predefinito) per ottenere un FontMetricse poi FontMetrics.stringWidthper trovare la larghezza per la stringa specificata.
Ad esempio, se hai una Graphicsvariabile chiamata g, dovresti usare:
int width = g.getFontMetrics().stringWidth(text);
Per altri toolkit, dovrai fornirci maggiori informazioni: dipenderà sempre dal toolkit.
Graphics, no FontMetrics. Ma stai chiamando Toolkit.getFontMetrics, che è davvero deprecato e di cui non parla questo metodo ... devi stare molto attento a questo genere di cose, in particolare prima di iniziare a parlare di segnalazione di bug ...
Toolkit.getFontMetricssuggerisce.
Non è sempre necessario che sia dipendente dal toolkit o non è sempre necessario utilizzare l'approccio FontMetrics poiché richiede prima di ottenere un oggetto grafico che è assente in un contenitore web o in un ambiente senza testa.
L'ho testato in un servlet web e calcola la larghezza del testo.
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());
Aggiungi i valori necessari a queste dimensioni per creare qualsiasi margine richiesto.
Utilizza il metodo getWidth nella seguente 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 ora qualcosa di completamente diverso. Quanto segue assume il carattere ariale e fa un'ipotesi selvaggia basata su un'interpolazione lineare di carattere rispetto alla larghezza.
// 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, ma forse non molto pratico.
Personalmente stavo cercando qualcosa che mi permettesse di calcolare l'area della stringa multilinea, in modo da poter determinare se l'area data è abbastanza grande da stampare la stringa, preservando il carattere specifico.
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;
}