Làm cách nào để tính chiều dài (tính bằng pixel) của một chuỗi trong Java?
Thích hợp mà không cần sử dụng Swing.
CHỈNH SỬA: Tôi muốn vẽ chuỗi bằng drawString () trong Java2D và sử dụng độ dài để gói từ.
Làm cách nào để tính chiều dài (tính bằng pixel) của một chuỗi trong Java?
Thích hợp mà không cần sử dụng Swing.
CHỈNH SỬA: Tôi muốn vẽ chuỗi bằng drawString () trong Java2D và sử dụng độ dài để gói từ.
Câu trả lời:
Nếu bạn chỉ muốn sử dụng AWT, thì hãy sử dụng Graphics.getFontMetrics
(tùy chọn chỉ định phông chữ, đối với phông chữ không phải mặc định) để lấy a FontMetrics
và sau đó FontMetrics.stringWidth
tìm chiều rộng cho chuỗi được chỉ định.
Ví dụ: nếu bạn có một Graphics
biến được gọi là g
, bạn sẽ sử dụng:
int width = g.getFontMetrics().stringWidth(text);
Đối với các bộ công cụ khác, bạn sẽ cần cung cấp thêm thông tin cho chúng tôi - nó sẽ luôn phụ thuộc vào bộ công cụ.
Graphics
, không phải FontMetrics
. Nhưng bạn đang gọi Toolkit.getFontMetrics
, thực sự không được dùng nữa, và đó không phải là điều mà phương pháp này nói về ... bạn cần phải thực sự cẩn thận về loại điều này, đặc biệt là trước khi bạn bắt đầu nói về việc báo cáo lỗi ...
Toolkit.getFontMetrics
đề xuất thay thế.
Nó không phải lúc nào cũng phụ thuộc vào bộ công cụ hoặc không phải lúc nào cũng cần sử dụng phương pháp FontMetrics vì nó yêu cầu người ta phải có được đối tượng đồ họa trước tiên không có trong vùng chứa web hoặc trong môi trường không có đầu.
Tôi đã thử nghiệm điều này trong một dịch vụ web và nó tính toán chiều rộng văn bản.
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());
Thêm các giá trị cần thiết vào các thứ nguyên này để tạo bất kỳ lợi nhuận cần thiết nào.
Sử dụng phương thức getWidth trong lớp sau:
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();
}
}
Và bây giờ cho một cái gì đó hoàn toàn khác. Phần sau giả định phông chữ arial và đưa ra phỏng đoán dựa trên phép nội suy tuyến tính của ký tự so với chiều rộng.
// 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;
}
Thú vị, nhưng có lẽ không thực tế lắm.
Cá nhân tôi đang tìm kiếm thứ gì đó để cho phép tôi tính toán vùng chuỗi nhiều dòng, vì vậy tôi có thể xác định xem vùng đã cho có đủ lớn để in chuỗi hay không - với việc bảo toàn phông chữ cụ thể.
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;
}