JavaFX: CSS не обрабатывается во время рендеринга текста вне экрана

Я пытаюсь предварительно визуализировать некоторые элементы Text вне экрана, чтобы получить их ширину, прежде чем отображать их позже на экране:

Group offScreenRoot = new Group();
Scene offScreen = new Scene(offScreenRoot, 1024, 768);
Set<Text> textSet = new HashSet<>();

Text textText = new Text(getText());
textSet.add(textText);

Text idText = new Text(getId());

textSet.add(idText);

for (String s : getStrings()) {
    textSet.add(new Text(s));
}
for (Text text : textSet) {
    text.setStyle("-fx-font-size: 48;"); // <- HERE!
    text.applyCss();
    offScreenRoot.getChildren().add(text);
}
for (Text text : textSet) {
    System.out.println(text.getLayoutBounds().getWidth());
}

Я применяю большой размер шрифта через CSS, но это не подхватывается. Вместо этого Text настолько широк, насколько это было бы возможно, отображая размер шрифта по умолчанию (я думаю).

Есть ли способ отобразить Text вне экрана и получить фактическое значение ширины в соответствии с размером шрифта CSS?


person s.d    schedule 21.03.2018    source источник


Ответы (1)


Я не уверен, что понимаю цель вашего кода. Было бы проще с MCVE, помните об этом в следующий раз.

Я думаю, вы допустили несколько простых ошибок. Глядя на определение applyCss Вы должны применить applyCss к родительскому узлу, а не к узлу.
Еще одна важная вещь в документе:

При условии, что сцена узла не равна нулю

И, к сожалению, когда вы применяете свой CSS, сцена текста становится нулевой, поскольку она еще не добавлена ​​к его родителю.

text.applyCss();
offScreenRoot.getChildren().add(text);

Таким образом, есть два решения, как описано в коде ниже в комментарии (и особенно в цикле for, где вы добавляете тексты к родителю):

public class MainOffscreen extends Application {

   private List<String> stringsList = new ArrayList<>();

   @Override
   public void start(Stage primaryStage) throws Exception {
      // Populates stringsList
      stringsList.add("String1");
      stringsList.add("String2");
      stringsList.add("String3");
      stringsList.add("String4");

      VBox offscreenRootVbox = new VBox(10.0);
      Scene offScreen = new Scene(offscreenRootVbox, 900, 700);

      // Replace the Hashset by list in order to keep order, more interesting for testing.
      List<Text> textSet = new ArrayList();

      // Text text.
      Text textText = new Text("Text");
      textSet.add(textText);

      // Text id.
      Text idText = new Text("Id");
      textSet.add(idText);

      // Populate String list.
      for(String s: stringsList) {
         textSet.add(new Text(s));
      }

      // Print the width of Texts before applying Css.
      for(Text text: textSet) {
         System.out.println("BEFORE Width of " + text.getText() + " : " + text.getLayoutBounds().getWidth());
      }
      System.out.println("\n----------\n");

      for(Text text: textSet) {
         text.setStyle("-fx-font-size: 48;"); // <- HERE!
         // First add it to the parent.
         offscreenRootVbox.getChildren().add(text);

         // Either apply the CSS on the each Text, or Apply it on the parent's Text, I choose the
         // second solution.
         // text.applyCss();
      }
      // Apply the css on the parent's node
      offscreenRootVbox.applyCss();

      for(Text text: textSet) {
         System.out.println("AFTER Width of " + text.getText() + " : " + text.getLayoutBounds().getWidth());
      }

      // primaryStage.setScene(offScreen);
      // primaryStage.show();
   }
}

И это дает этот вывод:

BEFORE Width of Text : 22.13671875
BEFORE Width of Id : 10.259765625
BEFORE Width of String1 : 37.845703125
BEFORE Width of String2 : 37.845703125
BEFORE Width of String3 : 37.845703125
BEFORE Width of String4 : 37.845703125

----------

AFTER Width of Text : 88.546875
AFTER Width of Id : 41.0390625
AFTER Width of String1 : 151.3828125
AFTER Width of String2 : 151.3828125
AFTER Width of String3 : 151.3828125
AFTER Width of String4 : 151.3828125

Надеюсь, это поможет вам.

person Pagbo    schedule 22.03.2018