2012-10-22 57 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(); 

,它似乎是工作的罰款。

相關問題