**15.17 (几何问題:寻找边界矩形)
- 请编写一个程序,让用户可以在一个二维面板上动态地增加和移除点,如图15-29a所示。当点加入和移除的时候,一个最小的边界矩形更新显示。假设每个点的半径是 10 像素
解题思路:
- 这道题可以从编程练习题15.15修改
- 新建一个面板Pane(),方法外部新建一个私有Circle类型的ArrayList,和一个私有类型的Rectangle()
- 编写一个用于绘制矩形的方法,接受面板参数Pane()
- 在绘制矩形的方法内找出这些点最大最小的xy值,如果边界矩形已存在,则从pane中移除,如果
ArrayList
中至少有一个Circle
,创建一个新的Rectangle
对象,使用计算出的边界值,并将其添加到Pane
中。 Rectangle
的填充颜色设为透明,这样它只显示边框,而不会覆盖Circle
在start方法中
为面板注册一个事件(鼠标点击:setOnMouseClicked)- 如果鼠标点的是左键:e.getButton() == MouseButton.PRIMARY,则新建一个圆,同时添加到布局和ArrayList中,更新边界矩形。
- 如果点的是右键,创建一个迭代器
iterator
用于遍历存储所有圆圈的ArrayList<Circle>
列表,使用contains()
方法检查鼠标位置是否在圆圈内, 如果是,那么同时在List和Pane中删除圆圈,更新边界矩形。
示例代码:编程练习题15_17BoundaryRectangle.java
package chapter_15;
import java.util.ArrayList;
import java.util.Iterator;
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.stage.Stage;
public class 编程练习题15_17BoundaryRectangle extends Application{
private ArrayList<Circle> list = new ArrayList<>();
private Rectangle boundaryRectangle;
@Override
public void start(Stage primaryStage) throws Exception {
Pane pane = new Pane();
pane.setOnMouseClicked(e ->{
double x = e.getX();
double y = e.getY();
if(e.getButton() == MouseButton.PRIMARY) {
Circle circle = new Circle(x,y,10);
circle.setFill(Color.WHITE);
circle.setStroke(Color.BLACK);
pane.getChildren().add(circle);
list.add(circle);
BoundaryRectangle(pane);
}
else if (e.getButton() == MouseButton.SECONDARY) {
Iterator<Circle> iterator = list.iterator();
while (iterator.hasNext()) {
Circle c = iterator.next();
if (c.contains(x, y)) {
pane.getChildren().remove(c);
iterator.remove(); // 使用迭代器的remove方法
BoundaryRectangle(pane);
}
}
}
});
Scene scene = new Scene(pane, 300, 300);
primaryStage.setTitle("编程练习题15_17BoundaryRectangle");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
Application.launch(args);
}
private void BoundaryRectangle(Pane pane) {
double minX = Double.MAX_VALUE;
double maxX = -Double.MAX_VALUE;
double minY = Double.MAX_VALUE;
double maxY = -Double.MAX_VALUE;
for(Circle c:list) {
double x = c.getCenterX();
double y = c.getCenterY();
double r = c.getRadius();
minX = Math.min(minX, x-r);
maxX = Math.max(maxX, x+r);
minY = Math.min(minY, y-r);
maxY = Math.max(maxY, y+r);
}
if(boundaryRectangle != null) {
pane.getChildren().remove(boundaryRectangle);
}
if(!list.isEmpty()) {
boundaryRectangle = new Rectangle(minX,minY, maxX-minX, maxY-minY);
boundaryRectangle.setFill(Color.TRANSPARENT);
boundaryRectangle.setStroke(Color.BLACK);
pane.getChildren().add(boundaryRectangle);
}
}
}
- 代码结果