Как рассчитать ширину пикселя строки в JavaFX? - программирование
Подтвердить что ты не робот

Как рассчитать ширину пикселя строки в JavaFX?

Похоже, что нет API-вызова для вычисления ширины (в пикселях) текстовой строки в Java FX 2.2. Были предложения об обходных решениях на других форумах, но мои попытки создать или найти любой код, который возвращает ширину строки, либо с использованием шрифта по умолчанию, либо иным образом, потерпели неудачу. Любая помощь будет оценена.

4b9b3361

Ответ 1

Если вы просто измеряете шрифт по умолчанию без CSS:

  • Поместите String для измерения в текстовом объекте.
  • Получить ширину границ текстового объекта.

Если вам нужно применить CSS:

  • Поместите String для измерения в текстовом объекте.
  • Создайте выделенную сцену и поместите объект Text в сцену.
  • Сделайте снимок текста (если вы используете Java 7) или вызовите applyCss для Java 8.
  • Получить ширину границ текстового объекта.

Это работает, потому что он заставляет макет передать текст, который вычисляет его границы макета. Сцена на шаге 2 требуется, потому что это как раз то, как работает процессор CSS (для того, чтобы выполнять свою работу, требуется node). Определенно прочитайте связанный javadoc для applyCss, если вы хотите понять дальнейшую обработку.

Пример кода

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

Как (если вообще) это изменится, если текст будет напечатан в графическом контексте с заданным шрифтом?

Применить шрифт к текстовому объекту, содержащему одно и то же сообщение, которое вы начертите на холсте. В отличие от того, когда вы измеряете текст, нанесенный на график сцены, элементы, нанесенные на холст, не применяют к ним 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);
    }
}

Ответ 2

Это решение работает до тех пор, пока 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();

С тех пор эти классы были удалены и недоступны в новой версии java!

Ответ 3

Я пробовал это:

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

и кажется, что он работает нормально.

Ответ 4

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