gpt4 book ai didi

java - 如何设置多边形的可拖动边界 - JavaFX

转载 作者:行者123 更新时间:2023-12-02 03:10:01 26 4
gpt4 key购买 nike

我有一个多边形,可以根据需要调整大小,并根据需要在场景中拖动/移动。但是,我的问题是如何阻止它被拖动到按钮或 TreeView 列表上?这是我的代码:

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

生成多边形的场景有一个 anchor Pane , TreeView 位于 HBox 中,按钮也是如此(如果对任何人有帮助的话)。

最佳答案

发生了什么

对 anchor 拖动点的检查是基于场景尺寸而不是多边形父容器的尺寸。

如何修复

将检查更改为基于父容器尺寸。

来自:

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

确保您的父级是可调整大小的父级(例如 Pane 而不是组),否则父级将不会自动扩展以填充可以放置多边形的可用区域。

其他问题

如果调整场景大小,使得可以渲染多边形的区域小于多边形的大小,则多边形仍然会溢出可用边界(因为它们现在已经缩小到小于多边形的大小) )。有几种方法可以处理这种情况。

  1. 您可以将多边形放置在 ScrollPane 中,以便在当前可视区域太小时用户可以滚动。这可能是首选的解决方案,但实现起来有点复杂(而且这并不是您真正问的问题)。目前我不会为此提供示例代码。
  2. 您可以将剪辑应用到父容器,以便它不会绘制在可见区域之外。例如,如果多边形的容器 Pane 名为 polyPane:

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

来自 StackOverflow 的内容需要 attribution .

关于java - 如何设置多边形的可拖动边界 - JavaFX,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41191361/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com