Java'da bir dizenin uzunluğu (piksel cinsinden) nasıl hesaplanır?
Swing kullanmadan tercih edilir.
DÜZENLEME: Java2D'de drawString () kullanarak dizeyi çizmek ve kelime kaydırma için uzunluğu kullanmak istiyorum.
Java'da bir dizenin uzunluğu (piksel cinsinden) nasıl hesaplanır?
Swing kullanmadan tercih edilir.
DÜZENLEME: Java2D'de drawString () kullanarak dizeyi çizmek ve kelime kaydırma için uzunluğu kullanmak istiyorum.
Yanıtlar:
Sadece AWT'yi kullanmak istiyorsanız, a almak için Graphics.getFontMetrics
(isteğe bağlı olarak yazı tipini, varsayılan olmayan bir yazı tipini belirtmek) FontMetrics
ve ardından FontMetrics.stringWidth
belirtilen dizenin genişliğini bulmak için kullanın.
Örneğin, Graphics
adında bir değişkeniniz varsa g
, şunu kullanırsınız:
int width = g.getFontMetrics().stringWidth(text);
Diğer araç takımları için, bize daha fazla bilgi vermeniz gerekecek - her zaman araç takımına bağlı olacaktır.
Graphics
değil FontMetrics
. Ama arıyorsun Toolkit.getFontMetrics
, ki bu gerçekten kullanımdan kaldırıldı ve bu yöntemin bahsettiği şey bu değil ... Bu tür şeyler hakkında gerçekten dikkatli olmalısın, özellikle hataları bildirmeden önce ...
Toolkit.getFontMetrics
onun yerine öneren, kullanımdan kaldırılmamış yöntemleri kullanırdım.
Her zaman araç setine bağlı olması gerekmez veya her zaman FontMetrics yaklaşımının kullanılması gerekmez, çünkü ilk önce bir web kabında veya başsız bir ortamda bulunmayan bir grafik nesnesini elde etmeyi gerektirir.
Bunu bir web sunucu uygulamasında test ettim ve metin genişliğini hesaplıyor.
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());
Gerekli marjı oluşturmak için bu boyutlara gerekli değerleri ekleyin.
Aşağıdaki sınıfta getWidth yöntemini kullanın:
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();
}
}
Ve şimdi tamamen farklı bir şey için . Aşağıdaki, bir yazı tipini varsayar ve karaktere karşı genişliğin doğrusal enterpolasyonuna dayalı vahşi bir tahmin yapar.
// 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;
}
İlginç, ama belki de pek pratik değil.
Kişisel olarak çok satırlı dize alanını hesaplamama izin verecek bir şey arıyordum, böylece belirli bir yazı tipini koruyarak verilen alanın dizeyi yazdıracak kadar büyük olup olmadığını belirleyebildim.
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;
}