it-swarm.com.de

Wie berechnet man die Pixelbreite eines Strings in JavaFX?

Es scheint, dass es keinen API-Aufruf gibt, um die Breite (in Pixel) einer Textzeichenfolge in Java FX 2.2 zu berechnen. Es gab Vorschläge für Problemumgehungen in anderen Foren, aber meine Bemühungen, Code zu erstellen oder zu finden, der die Breite eines Strings zurückgibt, entweder mit der Standardschriftart oder anderweitig, sind fehlgeschlagen. Jede Hilfe wäre dankbar.

23
Don Wills

Wenn Sie nur die Standardschriftart ohne CSS messen:

  1. Platzieren Sie den zu messenden String in einem Textobjekt.
  2. Ermitteln Sie die Breite der Layoutgrenzen des Textobjekts.

Wenn Sie CSS anwenden müssen:

  1. Platzieren Sie den zu messenden String in einem Textobjekt.
  2. Erstellen Sie eine Wegwerf-Szene und platzieren Sie das Textobjekt in der Szene.
  3. Machen Sie eine Momentaufnahme des Textes (wenn Sie Java 7 verwenden) oder rufen Sie applyCss für Java 8 auf.
  4. Ermitteln Sie die Breite der Layoutgrenzen des Textobjekts.

Dies funktioniert, weil der Layout-Pass für den Text erzwungen wird, der die Layout-Begrenzungen berechnet. Die Szene in Schritt 2 ist erforderlich, da der CSS-Prozessor auf diese Weise funktioniert (es muss ein Knoten in einer Szene vorhanden sein) seine Arbeit machen können). Lesen Sie auf jeden Fall den verknüpften Javadoc für applyCss, wenn Sie die Verarbeitung weiter verstehen möchten.

Beispielcode

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

Beispielprogrammausgabe (zeigt die Breite eines beliebigen Texts in Pixel an):

Sample Program Output

Wie (wenn überhaupt) würde sich dies ändern, wenn der Text in einem Grafikkontext mit einer festgelegten Schriftart gedruckt wurde? 

Wenden Sie die Schriftart auf ein Textobjekt an, das dieselbe Nachricht enthält, die Sie auf der Leinwand plotten möchten. Anders als beim Messen von Text, der im Szenendiagramm geplottet wird, wird für Elemente, die auf eine Leinwand geplottet werden, kein CSS angewendet. Daher müssen Sie das Textobjekt nicht in einer Szene platzieren und CSS anwenden, bevor Sie den Text messen. Sie können die Layout-Begrenzungen Ihres Textobjekts messen. Dies entspricht den Begrenzungen des Texts, der innerhalb der Leinwand mit derselben Schriftart gezeichnet wird.

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);
    }
}
33
jewelsea

Diese Lösung funktioniert bis 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();

Diese Klassen wurden inzwischen entfernt und sind in der neueren Java-Version nicht verfügbar!

16
Stas

Ich habe das versucht:

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

und es scheint gut zu funktionieren.

9
Leonardo Santos
Bounds bounds = TextBuilder.create (). Text (text) .font (font) .build (). GetLayoutBounds (); 
 Double width = bounds.getWidth (); 
 Double height = bounds.getHeight () ;
1