有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java通过鼠标点击添加/删除

我写了一个程序,用户可以在一个矩形中添加和删除圆圈,当用户左键单击时添加,当用户右键单击时删除,虽然它的添加工作正常,但删除效果不好,例如:当我添加四个圆圈并尝试删除所有圆圈时,其中一些没有移除,我不知道为什么,我很困惑。请帮忙

public class BoundingRectangle extends Application {
@Override
public void start(Stage primaryStage) {
    Pane pane = new Pane();
    ArrayList<Circle> list = new ArrayList<>();

    Rectangle rectangle1 = new Rectangle(10, 10, 175, 80);
    rectangle1.setStroke(Color.BLACK);
    rectangle1.setFill(Color.WHITE);
    Rectangle rectangle2 = new Rectangle(250, 75, 300, 200);
    rectangle2.setStroke(Color.BLACK);
    rectangle2.setFill(Color.WHITE);

    Text text = new Text(20, 33, "INSTRUCTION\n" +
            "Add: Left Click\nRemove: Right Click");

    pane.setOnMouseClicked(e -> {
        if (e.getButton() == MouseButton.PRIMARY) {
            Circle circle = new Circle(e.getX(), e.getY(), 10);
            list.add(circle);
            circle.setStroke(Color.BLACK);
            circle.setFill(Color.WHITE);

           if (circle.getCenterX() - rectangle2.getX() < 10) {
                circle.setCenterX(rectangle2.getX() + 10);
            } 
           else if (circle.getCenterY() - rectangle2.getY() < 10) {
                circle.setCenterY(rectangle2.getY() + 10);
            } 
           else if (rectangle2.getX() + rectangle2.getWidth() -
                    circle.getCenterX() < 10) {
                circle.setCenterX(rectangle2.getX() +  rectangle2.getWidth()  - 10);
            } 
           else if (rectangle2.getY() + rectangle2.getHeight() -
                    circle.getCenterY() < 10) {
                circle.setCenterY(rectangle2.getY() + rectangle2.getHeight() - 10);
            }
                pane.getChildren().add(circle);
        }

        else if (e.getButton() == MouseButton.SECONDARY) {
                for (int i = 0; i < list.size(); i++) {
                    if (list.get(i).contains(e.getX(), e.getY())) {
                        pane.getChildren().remove(list.get(i));
                        list.remove(i);
                        break;
                    }
                }
            }

        });
        pane.getChildren().addAll(rectangle1, rectangle2, text);

        Scene scene = new Scene(pane, 600, 300);
        primaryStage.setScene(scene);
        primaryStage.setTitle("BoundingRectangle");
        primaryStage.show();
    }
}

共 (1) 个答案

  1. # 1 楼答案

    我认为这看起来像是一个错误:如果在右键单击失败后调整窗口大小,则“调整大小”命令强制的重新绘制会删除圆圈。一些简单的调试显示,圆圈在应该的时候会从窗格的子列表中删除(因此这是一个重新绘制问题)

    作为一种解决方法,将第二个矩形替换为窗格。下面是直接替换的代码,没有其他更改:实际上,您可以对其进行大量重构以简化它(例如,将鼠标侦听器注册到第二个窗格而不是第一个窗格以进行添加,并将鼠标侦听器注册到每个圆以进行删除):

    import java.util.ArrayList;
    
    import javafx.application.Application;
    import javafx.scene.Scene;
    import javafx.scene.input.MouseButton;
    import javafx.scene.layout.Pane;
    import javafx.scene.paint.Color;
    import javafx.scene.shape.Circle;
    import javafx.scene.shape.Rectangle;
    import javafx.scene.text.Text;
    import javafx.stage.Stage;
    
    public class BoundingRectangle extends Application {
        @Override
        public void start(Stage primaryStage) {
            Pane pane = new Pane();
            ArrayList<Circle> list = new ArrayList<>();
    
            Rectangle rectangle1 = new Rectangle(10, 10, 175, 80);
            rectangle1.setStroke(Color.BLACK);
            rectangle1.setFill(Color.WHITE);
            Pane rectangle2 = new Pane();
            rectangle2.relocate(250, 75);
            rectangle2.setPrefSize(300,  200);
            rectangle2.setStyle("-fx-border-color: black;");
    
            Text text = new Text(20, 33, "INSTRUCTION\n"
                    + "Add: Left Click\nRemove: Right Click");
    
            pane.setOnMouseClicked(e -> {
                if (e.getButton() == MouseButton.PRIMARY) {
                    Circle circle = new Circle(e.getX(), e.getY(), 10);
                    list.add(circle);
                    circle.setStroke(Color.BLACK);
                    circle.setFill(Color.WHITE);
    
                    if (circle.getCenterX() - rectangle2.getBoundsInParent().getMinX() < 10) {
                        circle.setCenterX(rectangle2.getBoundsInParent().getMinX() + 10);
                    } else if (circle.getCenterY() - rectangle2.getBoundsInParent().getMinY() < 10) {
                        circle.setCenterY(rectangle2.getBoundsInParent().getMinY() + 10);
                    } else if (rectangle2.getBoundsInParent().getMaxX()
                            - circle.getCenterX() < 10) {
                        circle.setCenterX(rectangle2.getBoundsInParent().getMaxX() - 10);
                    } else if (rectangle2.getBoundsInParent().getMaxY()
                            - circle.getCenterY() < 10) {
                        circle.setCenterY(rectangle2.getBoundsInParent().getMaxY() - 10);
                    }
                    pane.getChildren().add(circle);
                }
    
                else if (e.getButton() == MouseButton.SECONDARY) {
                    for (int i = 0; i < list.size(); i++) {
                        if (list.get(i).contains(e.getX(), e.getY())) {
                            pane.getChildren().remove(list.get(i));
                            list.remove(i);
                            break;
                        }
                    }
                }
    
            });
            pane.getChildren().addAll(rectangle1, rectangle2, text);
    
            Scene scene = new Scene(pane, 600, 300);
            primaryStage.setScene(scene);
            primaryStage.setTitle("BoundingRectangle");
            primaryStage.show();
        }
    
        public static void main(String[] args) {
            launch(args);
        }
    }
    

    这是重构后的版本。由于rectangle2现在是Pane,您可以直接将圆添加到它,而不必担心调整它们的位置。右键单击是在圆圈本身上处理的,因此不需要代码来检查单击是否在圆圈上,因此,不需要单独的圆圈列表(尽管您的实际应用程序可能出于其他原因需要)

    import javafx.application.Application;
    import javafx.scene.Scene;
    import javafx.scene.input.MouseButton;
    import javafx.scene.layout.Pane;
    import javafx.scene.paint.Color;
    import javafx.scene.shape.Circle;
    import javafx.scene.shape.Rectangle;
    import javafx.scene.text.Text;
    import javafx.stage.Stage;
    
    public class BoundingRectangle extends Application {
        @Override
        public void start(Stage primaryStage) {
            Pane pane = new Pane();
    
            Rectangle rectangle1 = new Rectangle(10, 10, 175, 80);
            rectangle1.setStroke(Color.BLACK);
            rectangle1.setFill(Color.WHITE);
    
            Pane rectangle2 = new Pane();
            rectangle2.relocate(250, 75);
            rectangle2.setPrefSize(300,  200);
            rectangle2.setStyle("-fx-border-color: black;");
    
            Text text = new Text(20, 33, "INSTRUCTION\n"
                    + "Add: Left Click\nRemove: Right Click");
    
            rectangle2.setOnMouseClicked(e -> {
                if (e.getButton() == MouseButton.PRIMARY) {
                    Circle circle = new Circle(e.getX(), e.getY(), 10);
    
                    circle.setOnMouseClicked(evt -> {
                        if (evt.getButton() == MouseButton.SECONDARY) {
                            rectangle2.getChildren().remove(circle);
                        }
                    });
    
                    circle.setStroke(Color.BLACK);
                    circle.setFill(Color.WHITE);
    
                    rectangle2.getChildren().add(circle);
                }
    
    
            });
            pane.getChildren().addAll(rectangle1, rectangle2, text);
    
            Scene scene = new Scene(pane, 600, 300);
            primaryStage.setScene(scene);
            primaryStage.setTitle("BoundingRectangle");
            primaryStage.show();
        }
    
        public static void main(String[] args) {
            launch(args);
        }
    }