我想使用Path(通过在元素中添加几个LineTo对象)将两个圆与自由形式的线绑定在一起。

Path的情况下,我不知道如何对属性使用绑定。此外,我想通过单击更改其颜色。

这是一个外观的示例。

我需要的例子

java - 在JavaFX中将两个圆与路径绑定(bind)-LMLPHP

编辑:

每个顶点都可以使用setOnMouseDragged移动,因此我需要保持连接到顶点的线的每种自由形式。

最佳答案

只需将第一个x和最后一个yMoveToLineTo属性绑定到路径开始/结束的centerXcenterY坐标。

private Path constructionPath = null;
private final Map<Color, Color> nextColor;

{
    // create map for modifying color
    nextColor = new HashMap<>();
    Color[] colors = new Color[] { Color.BLACK, Color.RED, Color.GREEN, Color.BLUE };
    for (int i = 0; i < colors.length - 1; i++) {
        nextColor.put(colors[i], colors[i+1]);
    }
    nextColor.put(colors[colors.length-1], colors[0]);
}

private void createCircle(MouseEvent evt, Pane canvas) {
    Circle circle = new Circle(evt.getX(), evt.getY(), 5, Color.WHITE);
    circle.setStroke(Color.BLACK);
    circle.setStrokeWidth(2.5);

    // circle dragging events
    class DragListener implements EventHandler<MouseEvent> {

        boolean dragging;
        double startX;
        double startY;

        @Override
        public void handle(MouseEvent event) {
            Point2D pt = circle.localToParent(event.getX(), event.getY());
            circle.setCenterX(pt.getX() + startX);
            circle.setCenterY(pt.getY() + startY);
            dragging = true;
        }
    }
    DragListener listener = new DragListener();
    circle.setOnMousePressed(event -> {
        if (event.getButton() == MouseButton.PRIMARY) {
            Point2D pt = circle.localToParent(event.getX(), event.getY());
            listener.startX = circle.getCenterX() - pt.getX();
            listener.startY = circle.getCenterY() - pt.getY();
        }
    });
    circle.setOnMouseReleased(event -> {
        if (event.getButton() == MouseButton.PRIMARY) {
            event.consume();
            if (listener.dragging) {
                listener.dragging = false;
            } else {
                if (constructionPath == null) {
                    // start new path
                    MoveTo move = new MoveTo();
                    move.xProperty().bind(circle.centerXProperty());
                    move.yProperty().bind(circle.centerYProperty());
                    constructionPath = new Path(move);
                    constructionPath.setStrokeWidth(2.5);
                    constructionPath.setOnMouseReleased(evt2 -> {
                        evt2.consume();
                        Path p = (Path) evt2.getSource();
                        p.setStroke(nextColor.get(p.getStroke()));
                    });
                    canvas.getChildren().add(0, constructionPath);
                } else {
                    // end path
                    LineTo line = new LineTo();
                    constructionPath.getElements().add(line);
                    line.xProperty().bind(circle.centerXProperty());
                    line.yProperty().bind(circle.centerYProperty());
                    constructionPath = null;
                }
            }
        }
    });
    circle.setOnMouseDragged(listener);

    canvas.getChildren().add(circle);
}




Pane canvas = new Pane();
canvas.setOnMouseReleased(evt -> {
    if (evt.getButton() == MouseButton.PRIMARY) {
        if (constructionPath == null) {
            // create Circle
            createCircle(evt, canvas);
        } else {
            // add line to path
            LineTo line = new LineTo(evt.getX(), evt.getY());
            constructionPath.getElements().add(line);
        }
    }
});

canvas.setPrefSize(500, 500);


注意:点击路径很容易错过。如果要增加用户可以单击的区域,则应在mouseReleased canvasPane事件处理程序中进行自定义检查。

07-25 21:35
查看更多