2012-10-22 60 views
17

似乎没有API调用来计算Java FX 2.2中文本字符串的宽度(以像素为单位)。已经有其他论坛的解决方法的建议,但我努力创建或查找任何返回字符串宽度的代码,使用默认字体或其他方式都失败了。任何帮助,将不胜感激。如何计算JavaFX中字符串的像素宽度?

回答

27

如果你是刚刚测量的默认字体没有CSS:

  1. 将字符串在文本对象进行测量。
  2. 获取文本对象布局边界的宽度。

如果您需要申请CSS:在文本对象要测量的字符串

  1. 广场。
  2. 创建一次性场景并将Text对象放置在场景中。
  3. 拍摄文字快照(如果您使用的是Java 7)或致电applyCss用于Java 8.
  4. 获取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(); 
    } 
} 

样本程序输出(显示在文本中的任意一块的像素宽度):

Sample Program Output

如何(如果有的话)将如果文本被打印到带有set字体的graphicscontext,这种改变?

将字体应用于包含您将绘制到画布的相同消息的文本对象。与测量绘制到场景图形的文本不同的是,绘制到画布上的项目没有应用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); 
    } 
} 
+0

是这个工具根据操作系统计算字符串的宽度,如果我想计算Windows和Mac OX上的文本宽度? –

+0

是的,无论使用何种操作系统,都会返回正确的宽度。 – jewelsea

+0

如果在创建快照之前将样式应用于文本,此解决方案是否也会考虑样式文本? – Brendan

14

这个怎么样:

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(); 
+3

这也可以在单元测试和其他地方使用,因为(与快照相反)它不需要在FX应用程序线程上执行代码。 –

+4

不幸的是,这是一个令人沮丧的访问...它不是在Java 8.25以上的API中 – msj121

+0

什么是'gc' ...? – Supuhstar

1
Bounds bounds = TextBuilder.create().text(text).font(font).build().getLayoutBounds(); 
double width=bounds.getWidth(); 
double height=bounds.getHeight();
+3

TextBuilder已弃用。 – msj121

+0

对于javafx 8不起作用,因为'TextBuilder'类已被删除。 – fabian

3

我尝试这样做:

Text theText = new Text(theLabel.getText()); 
theText.setFont(theLabel.getFont()); 
double width = theText.getBoundsInLocal().getWidth(); 

,它似乎是工作的罚款。

相关问题