java JavaFX - 画布上的可点击线

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/27999430/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 12:47:21  来源:igfitidea点击:

JavaFX - Clickable line on canvas

javajavafx

提问by Just some guy

I have this JavaFX application that lets you plot locations on a map and connect them.

我有这个 JavaFX 应用程序,可以让您在地图上绘制位置并连接它们。

enter image description here

在此处输入图片说明

I do this by drawing a map as a background image on a canvas and then drawing circles and lines on it. I have made the circles clickable by using the contains() method in the Circle class, but how can I make the lines clickable?

为此,我在画布上绘制地图作为背景图像,然后在其上绘制圆圈和线条。我使用 Circle 类中的 contains() 方法使圆圈可点击,但如何使线条可点击?

edit: Look at this example where I just draw a line and set an event handler:

编辑:看看这个例子,我只是画一条线并设置一个事件处理程序:

    Canvas canvas = new Canvas();
    GraphicsContext gc = canvas.getGraphicsContext2D();

    gc.setLineWidth(5);
    gc.strokeLine(100, 100, 200, 200);

    canvas.setOnMouseClicked(event -> {
        double x = event.getX(), y = event.getY();
    });

My question is simply this: how do I finish the event handler so that it detects if the click is inside the line I just drew?

我的问题很简单:我如何完成事件处理程序,以便它检测点击是否在我刚刚绘制的线内?

回答by Roland

You should create a canvas and add the nodes (Circle, Line, etc) to it. Then you add mouse listeners to the nodes.

您应该创建一个画布并向其添加节点(圆、线等)。然后将鼠标侦听器添加到节点。

Example:

例子:

import java.util.ArrayList;
import java.util.List;

import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Line;
import javafx.stage.Stage;

public class DragNodes extends Application {

    public static List<Circle> circles = new ArrayList<Circle>();

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage primaryStage) {

        Group root = new Group();

        Canvas canvas = new Canvas(300, 300);
        GraphicsContext gc = canvas.getGraphicsContext2D();
        drawShapes(gc);

        Circle circle1 = new Circle(50);
        circle1.setStroke(Color.GREEN);
        circle1.setFill(Color.GREEN.deriveColor(1, 1, 1, 0.7));
        circle1.relocate(100, 100);

        Circle circle2 = new Circle(50);
        circle2.setStroke(Color.BLUE);
        circle2.setFill(Color.BLUE.deriveColor(1, 1, 1, 0.7));
        circle2.relocate(200, 200);

        Line line = new Line(circle1.getLayoutX(), circle1.getLayoutY(), circle2.getLayoutX(), circle2.getLayoutY());
        line.setStrokeWidth(20);

        Pane overlay = new Pane();
        overlay.getChildren().addAll(circle1, circle2, line);

        MouseGestures mg = new MouseGestures();
        mg.makeDraggable(circle1);
        mg.makeDraggable(circle2);
        mg.makeDraggable(line);

        root.getChildren().addAll(canvas, overlay);

        primaryStage.setScene(new Scene(root, 800, 600));
        primaryStage.show();
    }

    private void drawShapes(GraphicsContext gc) {
        gc.setStroke(Color.RED);
        gc.strokeRoundRect(10, 10, 230, 230, 10, 10);
    }

    public static class MouseGestures {

        double orgSceneX, orgSceneY;
        double orgTranslateX, orgTranslateY;

        public void makeDraggable(Node node) {
            node.setOnMousePressed(circleOnMousePressedEventHandler);
            node.setOnMouseDragged(circleOnMouseDraggedEventHandler);
        }

        EventHandler<MouseEvent> circleOnMousePressedEventHandler = new EventHandler<MouseEvent>() {

            @Override
            public void handle(MouseEvent t) {

                orgSceneX = t.getSceneX();
                orgSceneY = t.getSceneY();

                if (t.getSource() instanceof Circle) {

                    Circle p = ((Circle) (t.getSource()));

                    orgTranslateX = p.getCenterX();
                    orgTranslateY = p.getCenterY();

                } else {

                    Node p = ((Node) (t.getSource()));

                    orgTranslateX = p.getTranslateX();
                    orgTranslateY = p.getTranslateY();

                }
            }
        };

        EventHandler<MouseEvent> circleOnMouseDraggedEventHandler = new EventHandler<MouseEvent>() {

            @Override
            public void handle(MouseEvent t) {

                double offsetX = t.getSceneX() - orgSceneX;
                double offsetY = t.getSceneY() - orgSceneY;

                double newTranslateX = orgTranslateX + offsetX;
                double newTranslateY = orgTranslateY + offsetY;

                if (t.getSource() instanceof Circle) {

                    Circle p = ((Circle) (t.getSource()));

                    p.setCenterX(newTranslateX);
                    p.setCenterY(newTranslateY);

                } else {

                    Node p = ((Node) (t.getSource()));

                    p.setTranslateX(newTranslateX);
                    p.setTranslateY(newTranslateY);

                }

            }
        };

    }

}