在 Java FX 2.2 中似乎没有 API 调用来计算文本字符串的宽度(以像素为单位)。在其他论坛上已经提出了解决方法的建议,但是我创建或查找返回字符串宽度的任何代码(使用默认字体或其他方式)的努力都失败了。任何帮助,将不胜感激。
问问题
38691 次
4 回答
49
如果您只是测量没有 CSS 的默认字体:
- 将要测量的字符串放在 Text 对象中。
- 获取 Text 对象的布局边界的宽度。
如果你需要应用 CSS:
- 将要测量的字符串放在 Text 对象中。
- 创建一次性场景并将文本对象放置在场景中。
- 拍摄文本的快照(如果您使用的是 Java 7)或为 Java 8 调用applyCss。
- 获取 Text 对象的布局边界的宽度。
这是有效的,因为它强制在 Text 上进行布局传递,计算它的布局边界。第 2 步中的场景是必需的,因为这正是 CSS 处理器的工作方式(它需要一个节点位于场景中才能完成其工作)。如果您想进一步了解处理过程,请务必阅读 applyCss 的链接 javadoc。
示例代码
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.text.Text;
import javafx.stage.Stage;
// displays the width in pixels of an arbitrary piece of text.
public class MeasureText extends Application {
public static void main(String[] args) { launch(args); }
@Override public void start(Stage stage) throws Exception {
final Text text = new Text("XYZZY");
new Scene(new Group(text));
// java 7 =>
// text.snapshot(null, null);
// java 8 =>
text.applyCss();
final double width = text.getLayoutBounds().getWidth();
stage.setScene(new Scene(new Label(Double.toString(width))));
stage.show();
}
}
示例程序输出(以像素为单位显示任意文本的宽度):
如果将文本打印到具有设置字体的图形上下文中,这将如何(如果有的话)发生变化?
将字体应用于包含您将在画布上绘制的相同消息的文本对象。与测量绘制到场景图的文本不同,绘制到画布的项目没有应用 CSS,因此您无需在测量文本之前将 Text 对象放在场景中并应用 CSS。您可以测量文本对象的布局边界,它将与使用相同字体在画布内绘制的文本的边界相同。
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.canvas.*;
import javafx.scene.control.Label;
import javafx.scene.layout.VBox;
import javafx.scene.text.*;
import javafx.stage.Stage;
// displays the width in pixels of an arbitrary piece of text (which has been plotted on a canvas).
public class MeasureText extends Application {
@Override
public void start(Stage stage) throws Exception {
final String msg = "XYZZY";
final Text text = new Text(msg);
Font font = Font.font("Arial", 20);
text.setFont(font);
final double width = text.getLayoutBounds().getWidth();
Canvas canvas = new Canvas(200, 50);
GraphicsContext gc = canvas.getGraphicsContext2D();
gc.setFont(font);
gc.fillText(msg, 0, 40);
stage.setScene(new Scene(
new VBox(new Label(Double.toString(width)), canvas))
);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
于 2012-10-22T21:53:23.213 回答
16
我试过这个:
Text theText = new Text(theLabel.getText());
theText.setFont(theLabel.getFont());
double width = theText.getBoundsInLocal().getWidth();
它似乎工作正常。
于 2016-12-26T03:27:11.040 回答
15
这个解决方案一直有效到 java 8:
float width = com.sun.javafx.tk.Toolkit.getToolkit().getFontLoader().computeStringWidth("", gc.getFont());
float height = com.sun.javafx.tk.Toolkit.getToolkit().getFontLoader().getFontMetrics(gc.getFont()).getLineHeight();
这些类已被删除,并且在较新的 java 版本中不可用!
于 2014-01-23T16:57:30.177 回答
1
边界 bounds = TextBuilder.create().text(text).font(font).build().getLayoutBounds(); 双倍宽度=bounds.getWidth(); 双倍高度=bounds.getHeight();
于 2014-03-06T11:21:27.583 回答