JavaFX — размер метки не инициализирован

#java #javafx #javafx-2 #size #font-size

#java #javafx #javafx-2 #размер #размер шрифта

Вопрос:

Я работаю над приложением, которое позволяет пользователю рисовать графики, то есть ребра и узлы. В качестве узлов я в настоящее время использую простые элементы метки JavaFX. При рисовании краев мне нужно учитывать границы метки, однако ширина и высота меток, похоже, инициализируются только после ее «рисования». Например, при запуске приложения границы метки имеют ширину / высоту 0, но если метка перемещается пользователем, ширина / высота верны.

Есть ли возможность заставить JavaFX отображать текущие элементы? Код довольно сложный, но следующее дает представление о том, что я хочу сделать:

 stackpane = new StackPane();
text = new Label("Test");
text.setStyle("-fx-border-color:black; -fx-padding:3px;");
stackpane.getChildren().addAll(text);
...
// is it possible to force JavaFX to draw the text here?
...
// some calculations with the bounds of the label
Node node = getLabel();
Bounds bounds = node.getBoundsInParent();
double height = bounds.getHeight();
double width = bounds.getWidth();
  

Я также попытался обернуть текст в прямоугольник, а затем вручную установить ширину / высоту прямоугольника. Это работает, но узлы имеют метки разной длины, и, следовательно, ручная настройка не всегда подходит.

Комментарии:

1. Вы можете попытаться привязать свою логику к изменениям node.boundsInParentProperty()

2. @SergeyGrinev Я вижу, как это могло бы работать, но я не знаю, как это реализовать. Я немного отредактировал код: как бы мне добиться привязки переменной height к высоте границ?

Ответ №1:

Вы можете попытаться привязать свою логику к изменениям node.boundsInParentProperty()

 public class SmartBorder extends Application {

    @Override
    public void start(Stage primaryStage) {

        final Label txt = new Label("Example");
        txt.relocate(100, 100);

        Pane root = new Pane();

        final Rectangle border = new Rectangle();
        border.setFill(Color.TRANSPARENT);
        border.setStroke(Color.RED);

        // here we autoupdate border 
        txt.boundsInParentProperty().addListener(new ChangeListener<Bounds>() {

            @Override
            public void changed(ObservableValue<? extends Bounds> ov, Bounds old, Bounds b) {
                border.setX(b.getMinX() - 1);
                border.setY(b.getMinY() - 1);
                border.setWidth(b.getWidth() 2);
                border.setHeight(b.getHeight() 2);
            }
        });

        root.getChildren().addAll(txt, border);

        // click to see automatic border reaction
        root.setOnMouseClicked(new EventHandler<MouseEvent>() {

            @Override
            public void handle(MouseEvent t) {
                txt.relocate(Math.random()*200, Math.random()*200);
                txt.setText(Math.random()   "");
            }
        });
        Scene scene = new Scene(root, 300, 250);

        primaryStage.setTitle("Hello World!");
        primaryStage.setScene(scene);
        primaryStage.show();
    }
}
  

Комментарии:

1. Сработало отлично! Большое спасибо, особенно за подробный пример.