在JavaFX中使用Path绑定两个Circle

时间:2018-04-12 13:52:47

标签: java javafx

我想使用Path(通过在元素中添加多个LineTo对象)使用自由格式线绑定两个圆圈。

我不知道如何在Path的情况下对属性使用绑定。此外,我想点击它来改变它的颜色。

这是一个应该如何看的例子。

我需要的例子

Example of what I need

修改:

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

1 个答案:

答案 0 :(得分:2)

只需将第一个yMoveTo的{​​{1}}和LineTo属性绑定到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 canvas的{​​{1}}事件处理程序中进行自定义检查。