2016-12-16 110 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