2016-12-04 1 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

을 (https://gist.github.com/jewelsea/5375786), 그것의 너무 그것을 적용하기가별로 복잡하지 않아서 다각형의 포인트 수를 증가 시켰을뿐입니다. –

+1

그래,하지만 내 질문에 대답하지 않습니다, 당신이 그것을 이동할 때 어떻게 앵커 포인트 다각형을 따라 만들 수 있습니다. jewelsea 예제에는 다각형을 움직일 수있는 기능이 없었습니다. – TheBeliever12

+0

폴리곤을 드래그하면 점도 이동하도록 양방향 바인딩을 만드십시오! –

답변

2

Polygon의 점 (layoutX + pointX, layoutY + pointY) 노드에 적용된 변환이 없다는 가정된다 그려 좌표.

layoutXlayoutY 속성을 조정하지 마십시오. 이 문제를 해결하려면 당신은 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의 사용을 권장 이것에 의해 당신이 좀 더 읽기 쉽고 또한 코드를 만들기 때문에 좌표 하나의 당에 의해 개체의 수를 줄일 : 나는이 예제 [jewelsea 예]를 사용한다고 가정

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

관련 문제