簡體   English   中英

錨點不跟隨多邊形 - JavaFX

[英]Anchor Points Do Not Follow Polygon - JavaFX

目前我有一個多邊形,可以根據需要調整大小和形狀。 問題是當我移動多邊形時,錨點保持固定在它們的位置並且不隨多邊形移動,我真的很困惑,希望有人可以幫助或指導我。

public Polygon createStartingFloorPlan(ActionEvent event) throws IOException {
    Polygon fp = new Polygon();
    ObjectProperty<Point2D> mousePosition = new SimpleObjectProperty<>();
    fp.getPoints().setAll(
            150d, 50d,
            450d, 50d,
            750d, 50d,
            750d, 350d,
            750d, 650d,
            450d, 650d,
            150d, 650d,
            150d, 350d

    );

    fp.setOnMousePressed(new EventHandler<MouseEvent>() {
        @Override
        public void handle(MouseEvent event) {
            mousePosition.set(new Point2D(event.getSceneX(), event.getSceneY()));
        }
    });

    fp.setOnMouseDragged(new EventHandler<MouseEvent>() {
        @Override
        public void handle(MouseEvent event) {
            double deltaX = event.getSceneX() - mousePosition.get().getX();
            double deltaY = event.getSceneY() - mousePosition.get().getY();
            fp.setLayoutX(fp.getLayoutX()+deltaX);
            fp.setLayoutY(fp.getLayoutY()+deltaY);
            mousePosition.set(new Point2D(event.getSceneX(), event.getSceneY()));
            createControlAnchorsFor(fp.getPoints());
        }
    });

    fp.setStroke(Color.FORESTGREEN);
    fp.setStrokeWidth(4);
    fp.setStrokeLineCap(StrokeLineCap.ROUND);
    fp.setFill(Color.CORNSILK.deriveColor(0, 1.2, 1, 0.6));
    container.getChildren().add(fp);
    container.getChildren().addAll(createControlAnchorsFor(fp.getPoints()));
    return fp;
}


private ObservableList<Anchor> createControlAnchorsFor(final ObservableList<Double> points) {
    ObservableList<Anchor> anchors = FXCollections.observableArrayList();

    for (int i = 0; i < points.size(); i += 2) {
        final int idx = i;

        DoubleProperty xProperty = new SimpleDoubleProperty(points.get(i));
        DoubleProperty yProperty = new SimpleDoubleProperty(points.get(i + 1));

        xProperty.addListener(new ChangeListener<Number>() {
            @Override
            public void changed(ObservableValue<? extends Number> ov, Number oldX, Number x) {
                points.set(idx, (double) x);
            }
        });

        yProperty.addListener(new ChangeListener<Number>() {
            @Override
            public void changed(ObservableValue<? extends Number> ov, Number oldY, Number y) {
                points.set(idx + 1, (double) y);
            }
        });
        anchors.add(new Anchor(Color.GOLD, xProperty, yProperty));

    }

    return anchors;
}

// a draggable anchor displayed around a point.
class Anchor extends Circle {
    private final DoubleProperty x, y;

    Anchor(Color color, DoubleProperty x, DoubleProperty y) {
        super(x.get(), y.get(), 10);
        setFill(color.deriveColor(1, 1, 1, 0.5));
        setStroke(color);
        setStrokeWidth(2);
        setStrokeType(StrokeType.OUTSIDE);

        this.x = x;
        this.y = y;

        x.bind(centerXProperty());
        y.bind(centerYProperty());
        enableDrag();
    }

    // make a node movable by dragging it around with the mouse.
    private void enableDrag() {
        final Delta dragDelta = new Delta();
        setOnMousePressed(new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent mouseEvent) {
                // record a delta distance for the drag and drop operation.
                dragDelta.x = getCenterX() - mouseEvent.getX();
                dragDelta.y = getCenterY() - mouseEvent.getY();
                getScene().setCursor(Cursor.MOVE);
            }
        });
        setOnMouseReleased(new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent mouseEvent) {
                getScene().setCursor(Cursor.HAND);
            }
        });
        setOnMouseDragged(new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent mouseEvent) {
                double newX = mouseEvent.getX() + dragDelta.x;
                if (newX > 0 && newX < getScene().getWidth()) {
                    setCenterX(newX);
                }
                double newY = mouseEvent.getY() + dragDelta.y;
                if (newY > 0 && newY < getScene().getHeight()) {
                    setCenterY(newY);
                }
            }
        });
        setOnMouseEntered(new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent mouseEvent) {
                if (!mouseEvent.isPrimaryButtonDown()) {
                    getScene().setCursor(Cursor.HAND);
                }
            }
        });
        setOnMouseExited(new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent mouseEvent) {
                if (!mouseEvent.isPrimaryButtonDown()) {
                    getScene().setCursor(Cursor.DEFAULT);
                }
            }
        });
    }

    // records relative x and y co-ordinates.
    private class Delta {
        double x, y;
    }

}

問題在此處輸入圖片說明

假設沒有應用於節點的變換(layoutX + pointX, layoutY + pointY)則繪制Polygon點的坐標為(layoutX + pointX, layoutY + pointY)

但是,您永遠不會調整AnchorlayoutXlayoutY屬性。 要解決此問題,您可以將它們綁定到Polygon的屬性:

private ObservableList<Anchor> createControlAnchorsFor(Polygon polygon, final ObservableList<Double> points) {
    ...

    Anchor anchor = new Anchor(Color.GOLD, xProperty, yProperty);

    anchor.layoutXProperty().bind(polygon.layoutXProperty());
    anchor.layoutYProperty().bind(polygon.layoutYProperty());

    anchors.add(anchor);

    ...

}

此外,我建議使用自定義DoubleProperty類,而不是將SimpleDoubleProperty與偵聽器一起使用,因為這樣可以使代碼更具可讀性,並且每個坐標將對象數量減少一個:

private static class ListWriteDoubleProperty extends SimpleDoubleProperty {
    private final ObservableList<Double> list;
    private final int index;

    public ListWriteDoubleProperty(ObservableList<Double> list, int index) {
        super(list.get(index));
        this.list = list;
        this.index = index;
    }

    @Override
    protected void invalidated() {
        list.set(index, get());
    }

}
DoubleProperty xProperty = new ListWriteDoubleProperty(points, i);
DoubleProperty yProperty = new ListWriteDoubleProperty(points, i + 1);
// no more listeners/final index copy required...

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM