2016-12-04 62 views
2

目前我有一個多邊形,可以根據需要調整大小和形狀。問題是,當我移動多邊形時,錨點保持固定位置,不隨多邊形移動,我非常困惑,希望有人能夠幫助或引導我。錨點不遵循多邊形 - 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; 
    } 

} 

問題 enter image description here

+0

我想你使用本實施例[jewelsea示例](https://gist.github.com/jewelsea/5375786),所以它是適應它不是很複雜,你只是增加了多邊形的點數。 –

+1

是的,但那不能回答我的問題,當您移動它時,如何讓錨點跟隨多邊形。 jewelsea的例子沒有按照方式移動多邊形的功能,只是說。 – TheBeliever12

+0

進行雙向綁定,以便在拖動多邊形時點也移動! –

回答

2

其中Polygon的點繪製的(layoutX + pointX, layoutY + pointY)假設沒有施加到節點變換座標。

儘管如此,您從來不會調整和layoutY的屬性。爲了解決這個問題,你可以將它們綁定到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 s的聽衆,因爲這個,你做一下代碼更易讀,也由每一個減少的對象的數量座標:

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... 
+0

謝謝!你是最好的!! :) – TheBeliever12