2012-10-22 17 views
17

Wygląda na to, że nie ma połączenia API do obliczania szerokości (w pikselach) ciągu tekstowego w Java FX 2.2. Pojawiły się sugestie obejścia na innych forach, ale moje wysiłki w celu utworzenia lub znalezienia dowolnego kodu, który zwraca szerokość ciągu, przy użyciu domyślnej czcionki lub innej, nie powiodły się. Każda pomoc będzie doceniona.Jak obliczyć szerokość piksela w języku JavaFX?

Odpowiedz

27

Jeśli tylko pomiar domyślną czcionkę bez CSS:

  1. miejsce napisu należy mierzyć w obiekcie tekstowym.
  2. Uzyskaj szerokość granic układu obiektu Tekst.

Jeśli trzeba zastosować CSS:

  1. Umieść String być mierzony w obiekcie tekstowym.
  2. Utwórz rzutowaną scenę i umieść obiekt Tekst w scenie.
  3. Zrób migawkę tekstu (jeśli korzystasz z Java 7) lub zadzwoń pod numer applyCss dla języka Java 8.
  4. Uzyskaj szerokość granic układu obiektu Tekst.

Działa, ponieważ wymusza przejście układu na tekście, który oblicza jego ograniczenia. Scena w kroku 2 jest wymagana, ponieważ tak działa procesor CSS (potrzebuje węzła, który będzie umiejscowiony w scenie, aby móc wykonać to zadanie). Zdecydowanie przeczytaj połączone javadoc dla applyCss, jeśli chcesz dalej zrozumieć przetwarzanie.

Przykładowy kod

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

wyjście Przykładowy program (wyświetla szerokość w pikselach dowolnego fragmentu tekstu):

Sample Program Output

Jak (jeśli w ogóle) będzie ta zmiana, jeśli tekst został wydrukowany w tekście graficznym z ustawioną czcionką?

Zastosuj czcionkę do obiektu tekstowego zawierającego tę samą wiadomość, którą wydrukujesz na płótnie. W przeciwieństwie do pomiaru tekstu naniesionego na wykres sceny, elementy naniesione na płótno nie mają nałożonych na nie CSS, więc nie trzeba umieszczać obiektu Tekst w scenie i stosować CSS przed pomiarem tekstu. Możesz zmierzyć granice układu obiektu tekstowego i będzie on taki sam jak granice tekstu drukowanego w obszarze roboczym z tą samą czcionką.

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

to narzędzie oblicza szerokość łańcucha zgodnie z systemem operacyjnym, który działa, jeśli chcę obliczyć szerokość tekstu w systemach Windows i Mac OX? –

+0

Tak, zostanie zwrócona prawidłowa szerokość, niezależnie od używanego systemu operacyjnego. – jewelsea

+0

Czy to rozwiązanie będzie również uwzględniało stylizowany tekst, jeśli styl zostanie zastosowany do tekstu przed zrobieniem migawki? – Brendan

14

Co o tym:

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

Można to również wykorzystać w testach jednostkowych i innych, ponieważ (w przeciwieństwie do migawki) nie wymaga to wykonywania kodu w wątku aplikacji FX. –

+4

Niestety jest to odradzany dostęp ... Nie ma go na api od wersji Java 8.25 – msj121

+0

Co to jest 'gc' ...? – Supuhstar

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

TextBuilder jest przestarzały. – msj121

+0

Nie działa dla javafx 8, ponieważ klasa 'TextBuilder' została usunięta. – fabian

3

Próbowałem to:

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

i wydaje się, że działa poprawnie.

Powiązane problemy