2012-10-22 31 views
17

Dường như không có lệnh gọi API để tính chiều rộng (tính bằng pixel) của chuỗi văn bản trong Java FX 2.2. Đã có đề xuất giải pháp trên các diễn đàn khác, nhưng những nỗ lực của tôi để tạo hoặc tìm bất kỳ mã nào trả về chiều rộng của chuỗi, hoặc sử dụng phông chữ mặc định hoặc cách khác, đã thất bại. Bất kỳ trợ giúp sẽ được đánh giá cao.Cách tính chiều rộng pixel của một String trong JavaFX?

Trả lời

27

Nếu bạn chỉ đo phông chữ mặc định mà không CSS:

  1. Đặt String để được đo bằng một đối tượng văn bản.
  2. Nhận chiều rộng của giới hạn bố cục của đối tượng Văn bản.

Nếu bạn cần phải áp dụng CSS:

  1. Đặt String để được đo bằng một đối tượng văn bản.
  2. Tạo cảnh quay và đặt đối tượng Text trong Scene.
  3. Chụp nhanh Bản văn (nếu bạn đang sử dụng Java 7) hoặc gọi applyCss cho Java 8.
  4. Lấy chiều rộng của giới hạn bố cục của đối tượng Văn bản.

Điều này có tác dụng vì nó buộc phải vượt qua bố cục trên Văn bản tính giới hạn bố cục của nó. Cảnh trong bước 2 là bắt buộc vì đó chỉ là cách xử lý CSS hoạt động (nó cần một nút được đặt trong một cảnh để có thể thực hiện công việc của mình). Chắc chắn đọc javadoc được liên kết cho applyCss nếu bạn muốn hiểu thêm về xử lý.

Mẫu Mã

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(); 
    } 
} 

chương trình mẫu đầu ra (hiển thị chiều rộng bằng pixel của một mảnh tùy ý các văn bản):

Sample Program Output

thế nào (nếu có) sẽ sự thay đổi này nếu văn bản được in vào một đồ họa với một phông chữ được thiết lập?

Áp dụng phông chữ cho đối tượng văn bản chứa cùng một thông báo bạn sẽ vẽ với canvas. Không giống như khi bạn đang đo văn bản được vẽ biểu đồ cảnh, các mục được vẽ vào khung vẽ không có CSS ​​áp dụng cho chúng, do đó bạn không cần phải đặt đối tượng Văn bản trong một cảnh và đã áp dụng CSS cho nó trước khi đo văn bản. Bạn có thể đo các giới hạn bố trí của đối tượng văn bản của bạn và nó sẽ giống như giới hạn của văn bản được vẽ trong canvas với cùng một phông chữ.

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

là công cụ này tính chiều rộng của chuỗi theo hệ điều hành hoạt động trên nếu tôi muốn tính chiều rộng văn bản trên Windows và Mac OX? –

+0

Có, chiều rộng chính xác sẽ được trả lại, bất kể hệ điều hành được sử dụng. – jewelsea

+0

Giải pháp này cũng có tính đến văn bản được tạo kiểu nếu kiểu được áp dụng cho văn bản trước khi chụp nhanh không? – Brendan

14

gì về điều này:

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

Điều này cũng có thể được sử dụng trong các bài kiểm tra đơn vị và ở nơi khác, bởi vì (trái với ảnh chụp nhanh) nó không yêu cầu mã được thực hiện trên một chuỗi ứng dụng FX. –

+4

Đáng buồn thay đây là một truy cập nản lòng ... Nó không phải là trên api như của Java 8.25 – msj121

+0

'gc' ... là gì? – Supuhstar

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

TextBuilder không được chấp nhận. – msj121

+0

Không hoạt động với javafx 8, vì lớp 'TextBuilder' đã bị xóa. – fabian

3

Tôi cố gắng này:

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

và có vẻ như là làm việc tốt.

Các vấn đề liên quan