**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;@Overridepublic 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);}}
}
- 代码结果