I wrote this program which enables the user to add and remove circles in a rectangle, It adds when the user left clicked and removed when he/she right clicked, although its adding works correctly but its removing doesn't work good, for example: when I add four circles and try to remove all of them, some of them doesn't remove and I don't know why,and I'm confused. help please.
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();
}
}
I think this looks like a bug: if you resize the window after a right-click fails, the repaint forced by the resize removes the circle. Some simple debugging shows that the circles are removed from the pane's child list when they should be (so it is a repaint issue).
As a workaround, replace the second rectangle with a pane. Here is the code with a direct replacement and no other changes: you can actually refactor this a lot to simplify it (registering the mouse listener with the second pane instead of the first for adding, and registering mouse listeners with each of the circle for removing, for example):
Here's the refactored version. Since
rectangle2
is now aPane
, you can add the circles directly to it, and not have to worry about adjusting their position. The right-click is handled on the circles themselves, so there's no need for code to check if the click was on a circle, and because of that, there's no need for the separate list of circles (though your real application may need that for other reasons).