У меня есть многоугольник, который я хочу увеличить в размерах при изменении размера окна. У меня есть DoubleBinding, который является базовой линией для размера всех моих фигур в сцене. Я использую этот DoubleBinding для создания ListBinding, который вычисляет, насколько большим должен быть полигон. Я пытался использовать Bindings.bindContent (list1, list2) для привязки ListBinding к точкам многоугольника, но, похоже, он не работает.

    Polygon triangle = new Polygon();

    ListBinding<Double> trianglePoints = new ListBinding<Double>() {
        {
            super.bind(width, height);
        }
        @Override
        protected ObservableList<Double> computeValue() {
            ObservableList<Double> points = FXCollections.observableArrayList();
            points.addAll(0.0, 0.0, width.get()/2, height.get()/4, 0.0, height.get()/2);
            return points;
        }
    };
    Bindings.bindContent(triangle.getPoints(), trianglePoints.get());

Я обнаружил, что если я добавляю InvalidationListener к точкам треугольника и вручную изменяю точки многоугольника, когда он срабатывает, это работает.

    trianglePoints.addListener((InvalidationListener)(listener) -> triangle.getPoints().setAll(trianglePoints.get()));

Что я делаю не так?

0
Misys 1 Апр 2017 в 01:24

2 ответа

Лучший ответ

Вы должны изменить свою привязку следующим образом:

Bindings.bindContent(triangle.getPoints(), trianglePoints);

Ваша предыдущая привязка не сработала, потому что trianglePoints.get() является просто результатом computeValue() вызова, т. Е. Создания ObservableList с некоторыми значениями, вычисленными на основе начальных width и height. Таким образом, дальнейшие изменения в свойствах width и height не были приняты во внимание.

2
Pavlo Viazovskyy 31 Мар 2017 в 23:11

Я рекомендую не использовать ListBinding. Вам не нужно пересматривать список снова и снова, вам просто нужно изменить некоторые пункты:

@Override
public void start(Stage primaryStage) {
    Polygon triangle = new Polygon(
            0, 0,
            0, 0,
            0, 0);

    StackPane root = new StackPane();
    root.getChildren().add(triangle);

    root.heightProperty().addListener((observable, oldH, newH) -> {
        double h = newH.doubleValue();
        triangle.getPoints().set(3, h / 4);
        triangle.getPoints().set(5, h / 2);
    });

    root.widthProperty().addListener((observable, oldW, newW) -> {
        double w = newW.doubleValue();
        triangle.getPoints().set(2, w / 2);
    });

    Scene scene = new Scene(root);

    primaryStage.setScene(scene);
    primaryStage.show();
}

Кроме того, это также возможно сделать, используя свойства масштаба (если вы не используете обводку или какую-то экзотическую заливку):

@Override
public void start(Stage primaryStage) {
    Polygon triangle = new Polygon(
            0, 0,
            0.5, 0.25,
            0, 0.5);

    StackPane root = new StackPane();
    root.getChildren().add(triangle);

    triangle.scaleXProperty().bind(root.widthProperty());
    triangle.scaleYProperty().bind(root.heightProperty());

    Scene scene = new Scene(root);

    primaryStage.setScene(scene);
    primaryStage.show();
}
1
fabian 1 Апр 2017 в 08:55