javafximageviewcoordinatesscenebuilderonmouseclick

JavaFX, mark coordinates on an image with mouse click


I am trying to make a measuring tool in JavaFX to use on an ImageView, where I click on two points in the image and then get the distance between them - I have figured this part out. However, I also want to be able to see/mark where on the image I have clicked, but I can't imagine how would be best to do so. I'll attach the code for the measuring tool, so that you get a better idea of what I'm dealing with. I think it must be inside the first if loop, where I can set the mark at (secondposx, secondposy) - but my question is, how can I make that mark? Do you have any good ideas? :-)

private void btnMeasureAction(ActionEvent event) {
    if (btnMeasure.isSelected()) {
        imgView.setCursor(Cursor.CROSSHAIR);
        imgView.setPickOnBounds(true);
        imgView.setOnMouseClicked(e -> {
            secondposx = e.getX();
            secondposy = e.getY();
// I think the MARK should be set here.
                //System.out.println(secondposx + ", " + secondposy);


            if ((firstposx == 0)) {
                firstposx = secondposx;
                firstposy = secondposy;
                //System.out.println(firstposx + ", " + firstposy);
            } else {
                double distance = Math.sqrt(Math.pow((secondposx - firstposx), 2) + Math.pow((secondposy - firstposy), 2));
                System.out.println("The distance is: " + distance);
                btnMeasure.setSelected(false);
                imgView.setOnMouseClicked(null);
                imgView.setCursor(Cursor.DEFAULT);
                firstposx = 0;
                firstposy = 0;
                secondposy = 0;
                secondposx = 0;
            }

Solution

  • One solution is to wrap your image view inside a Pane, and add appropriate shapes to the Pane. I.e. instead of

    scrollPane.setContent(imgView);
    

    do

    Pane imgContainer = new Pane(imgView);
    scrollPane.setContent(imgContainer);
    

    and then do

    Circle marker = new Circle(secondposx, secondposy, 2, Color.SALMON);
    imgContainer.getChildren().add(marker);
    

    If you want to add the markers directly to the existing AnchorPane (or to any other container which is an ancestor of the image view), and avoid creating an additional container, you can do so but you will need to change coordinates from the image view to that container. You can do this first getting the coordinates in the scene, and then changing from scene coordinates to the container coordinates:

    Point2D sceneCoords = new Point2D(e.getSceneX(), e.getSceneY());
    Point2D anchorPaneCoords = anchorPane.sceneToLocal(sceneCoords);
    Circle marker = new Circle(anchorPaneCoords.getX(), anchorPaneCoords.getY(), 2, Color.CORAL);
    anchorPane.getChildren().add(marker);