it-swarm.com.ru

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

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

23
Don Wills

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

  1. Поместите строку для измерения в текстовый объект.
  2. Получите ширину границ макета объекта Text.

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

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

Это работает, потому что он вызывает передачу макета для текста, который вычисляет его границы макета . Сцена в шаге 2 требуется, потому что это именно так, как работает процессор CSS (ему нужен узел, который должен быть расположен в сцене, чтобы быть в состоянии сделать свою работу). Обязательно прочитайте связанный 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);
    }
}
33
jewelsea

Это решение работает до 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!

16
Stas

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

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

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

9
Leonardo Santos
Bounds bounds = TextBuilder.create (). Text (text) .font (шрифт) .build (). GetLayoutBounds (); 
 Double width = bounds.getWidth (); 
 Double height = bounds.getHeight () ;
1
dongfangshangren