2016-12-16 47 views
-1

我有一個多邊形,可根據需要調整大小,並根據需要在場景周圍拖動/移動。但是,我的問題是我怎麼能阻止它被拖到按鈕或我的樹視圖列表?這裏是我的代碼:如何爲多邊形設置可拖動邊界 - JavaFX

public Polygon cfp(ActionEvent event) throws IOException { 

    Polygon fp = new Polygon(); 
    ObjectProperty<Point2D> mousePosition = new SimpleObjectProperty<>(); 
    //Set the anchor points for the template layout 
    fp.getPoints().setAll(
      350d, 50d, 
      700d, 50d, 
      1050d, 50d, 
      1050d, 350d, 
      1050d, 650d, 
      700d, 650d, 
      350d, 650d, 
      350d, 350d 

    ); 

    //Allow the Floor plan to be draggable around the screen 
    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())); 
     } 
    }); 
    //Set the colour and properties of the template layout 
    fp.setStroke(Color.DARKRED); 
    fp.setStrokeWidth(4); 
    fp.setStrokeLineCap(StrokeLineCap.ROUND); 
    fp.setFill(Color.MINTCREAM); 
    container.getChildren().add(fp); 
    container.getChildren().addAll(createAnchors(fp, fp.getPoints())); 
    return fp; 
} 

private ObservableList<Anchor> createAnchors(Polygon polygon, 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 ListWriteDoubleProperty(points, i); 
     DoubleProperty yProperty = new ListWriteDoubleProperty(points, i + 1); 

     //Bind the anchors to the polygon, so if its moved so are they 
     Anchor anchor = new Anchor(Color.BLACK, xProperty, yProperty); 
     anchor.layoutXProperty().bindBidirectional(polygon.layoutXProperty()); 
     anchor.layoutYProperty().bindBidirectional(polygon.layoutYProperty()); 

     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(anchor); 
    } 
    return anchors; 
} 

//Creating circles to mark the anchor points to help users know where to modify from 
class Anchor extends Circle { 
    private final DoubleProperty x, y; 

    Anchor(Color color, DoubleProperty x, DoubleProperty y) { 
     super(x.get(), y.get(), 5); 
     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 the circle node movable with mouse drag 
    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 the x and y co-ordinates. 
    private class Delta { 
     double x, y; 
    } 

} 

這裏是我的問題:

enter image description here

而多邊形生成有一個錨窗格中的場景,樹視圖是一個HBox中等等都是,如果這些按鈕幫助任何人。

+0

我還沒有編碼JavaFX,但不是多邊形只限於'窗格'?你能不能把主窗口分成兩個「窗格」?一個用於按鈕,水平地穿過底部,一個用於多邊形區域? – Eric

+0

我不知道爲什麼,但由於某種原因,我可以將它拖到窗戶周圍。這些按鈕位於HBox中,TreeView也是如此,所以我通常會假定該多邊形只能在其父窗格中拖動,但情況並非如此:/ – TheBeliever12

+0

您是否可以在X,Y多邊形的極值中進行硬編碼?因此限制它的父窗格? – Eric

回答

1

發生什麼事

您爲錨的阻力點檢查是基於現場的尺寸,而不是多邊形的父容器的尺寸。

如何解決它

更改您的檢查,以在父容器的尺寸爲基礎。

來源:

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); 
     } 
    } 
}); 

要:

setOnMouseDragged(new EventHandler<MouseEvent>() { 
    @Override 
    public void handle(MouseEvent mouseEvent) { 
     double newX = mouseEvent.getX() + dragDelta.x; 
     if (newX > 0 && newX < getParent().getLayoutBounds().getWidth()) { 
      setCenterX(newX); 
     } 
     double newY = mouseEvent.getY() + dragDelta.y; 
     if (newY > 0 && newY < getParent().getLayoutBounds().getHeight()) { 
      setCenterY(newY); 
     } 
    } 
}); 

確保你的父母是一個可調整大小的父母(如窗格,而不是一組),否則家長不會自動擴展,以填補可以放置多邊形的可用區域。

其他問題

如果調整的一幕讓在多邊形可以呈現的面積比多邊形的尺寸,則多邊形依然會溢出的可用範圍(因爲他們有現在收縮小於多邊形的大小)。有幾種方法可以處理這種情況。

  1. 你可以放置多邊形的一個ScrollPane,因此,如果當前可視區域變得太小,用戶可以左右滾動。這可能是首選解決方案,但實施起來會稍微複雜一點(而且這不是你問的問題)。目前我不會提供此示例代碼。
  2. 您可以將剪輯應用於父容器,以便它不會在可見區域外繪製。例如,如果在多邊形的容器窗格被命名爲polyPane:

    Rectangle clip = new Rectangle(); 
    clip.widthProperty().bind(polyPane.widthProperty()); 
    clip.heightProperty().bind(polyPane.heightProperty()); 
    polyPane.setClip(clip); 
    

內容來自StackOverflow的採購需要attribution

+0

非常感謝您,我遵循您所說的一切,並堅持使用矩形剪輯。非常感激 – TheBeliever12