Предполагая, что никакие преобразования не были применены к линии или StackPane
, вы можете вычислить положение StackPane
на основе свойств линии, подобных этому
stackPane.layoutX = (line.startX + line.endX - stackPane.width) / 2;
(Выполните соответствующие действия для координат y.)
transformX
и transformY
могут быть просто добавлены, но для общих преобразований потребуется
- Прослушивание изменений преобразований
- Используйте
localToParent
в начальных / конечных координатах линии, чтобы получить местоположение в родительском элементе.
Я рекомендую использовать Bindings.createDoubleBindings
для сложных двойных привязок, кстати, так как это значительно упрощает чтение формулы вычисления значений.
* ** 1 022 тысяча двадцать-один * Пример
Я использую Label
, так как это также обеспечивает функциональность фона / границы.
@Override
public void start(Stage primaryStage) throws IOException {
Label label = new Label();
label.setStyle("-fx-background-color: white; -fx-border-color: black;");
label.setPadding(new Insets(2, 4, 2, 4));
Line line = new Line(300, 300, 300, 100);
label.layoutXProperty().bind(Bindings.createDoubleBinding(
() -> (line.getStartX() + line.getEndX() - label.getWidth()) / 2,
line.startXProperty(), line.endXProperty(), label.widthProperty()));
label.layoutYProperty().bind(Bindings.createDoubleBinding(
() -> (line.getStartY() + line.getEndY() - label.getHeight()) / 2,
line.startYProperty(), line.endYProperty(), label.heightProperty()));
DoubleProperty angle = new SimpleDoubleProperty();
line.endXProperty().bind(Bindings.createDoubleBinding(() -> 300 + 200 * Math.sin(angle.get()), angle));
line.endYProperty().bind(Bindings.createDoubleBinding(() -> 300 + 200 * Math.cos(angle.get()), angle));
Timeline timeline = new Timeline(
new KeyFrame(Duration.ZERO, new KeyValue(angle, 0d, Interpolator.LINEAR)),
new KeyFrame(Duration.seconds(10), new KeyValue(angle, Math.PI * 2, Interpolator.LINEAR)));
timeline.setCycleCount(Animation.INDEFINITE);
label.textProperty().bind(timeline.currentTimeProperty().asString());
timeline.play();
Scene scene = new Scene(new Pane(line, label), 600, 600);
primaryStage.setScene(scene);
primaryStage.show();
}