วิธีคำนวณความยาว (เป็นพิกเซล) ของสตริงใน Java
เหมาะกว่าโดยไม่ต้องใช้ Swing
แก้ไข: ฉันต้องการวาดสตริงโดยใช้ drawString () ใน Java2D และใช้ความยาวสำหรับการตัดคำ
วิธีคำนวณความยาว (เป็นพิกเซล) ของสตริงใน Java
เหมาะกว่าโดยไม่ต้องใช้ Swing
แก้ไข: ฉันต้องการวาดสตริงโดยใช้ drawString () ใน Java2D และใช้ความยาวสำหรับการตัดคำ
คำตอบ:
หากคุณต้องการใช้ AWT ให้ใช้Graphics.getFontMetrics
(ระบุแบบอักษรเป็นทางเลือกสำหรับแบบอักษรที่ไม่ใช่ค่าเริ่มต้น) เพื่อรับFontMetrics
และFontMetrics.stringWidth
ค้นหาความกว้างของสตริงที่ระบุ
ตัวอย่างเช่นหากคุณมีGraphics
ตัวแปรที่เรียกว่าg
คุณจะใช้:
int width = g.getFontMetrics().stringWidth(text);
สำหรับชุดเครื่องมืออื่น ๆ คุณจะต้องให้ข้อมูลเพิ่มเติมกับเราซึ่งจะขึ้นอยู่กับชุดเครื่องมือเสมอ
Graphics
ไม่ใช่FontMetrics
. แต่คุณกำลังโทรหาToolkit.getFontMetrics
ซึ่งเลิกใช้งานจริงและวิธีนี้ไม่ได้พูดถึงอะไร ... คุณต้องระวังเรื่องประเภทนี้โดยเฉพาะอย่างยิ่งก่อนที่คุณจะเริ่มพูดถึงการรายงานข้อบกพร่อง ...
Toolkit.getFontMetrics
แนะนำแทน
ไม่จำเป็นต้องขึ้นอยู่กับชุดเครื่องมือเสมอไปหรือไม่จำเป็นต้องใช้วิธี FontMetrics เสมอไปเนื่องจากต้องใช้วิธีการหนึ่งในการรับวัตถุกราฟิกที่ไม่มีอยู่ในคอนเทนเนอร์ของเว็บหรือในสภาพแวดล้อมที่ไม่มีหัว
ฉันได้ทดสอบสิ่งนี้ในเว็บ servlet และคำนวณความกว้างของข้อความ
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());
เพิ่มค่าที่จำเป็นให้กับมิติเหล่านี้เพื่อสร้างระยะขอบที่ต้องการ
ใช้เมธอด getWidth ในคลาสต่อไปนี้:
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();
}
}
และตอนนี้สำหรับสิ่งที่แตกต่างไปจากเดิมอย่างสิ้นเชิง ต่อไปนี้ถือว่าเป็นฟอนต์ arial และทำการเดาแบบไวด์ตามการแก้ไขเชิงเส้นของอักขระเทียบกับความกว้าง
// 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;
}
น่าสนใจ แต่อาจไม่เป็นประโยชน์มากนัก
โดยส่วนตัวแล้วฉันกำลังค้นหาบางสิ่งบางอย่างเพื่อให้ฉันคำนวณพื้นที่สตริงแบบหลายบรรทัดดังนั้นฉันจึงสามารถระบุได้ว่าพื้นที่ที่กำหนดนั้นใหญ่พอที่จะพิมพ์สตริงหรือไม่โดยรักษาแบบอักษรเฉพาะไว้
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;
}