绘制圆形:代码类拆分问题求助
我来帮你把这段代码拆分成更清晰的类结构,解决你拆分时遇到的问题~
首先,咱们得明确面向对象的封装原则:圆的属性(颜色、直径、位置)和它的行为(比如绘制)应该都放在Circle类里,而不是让Controller来持有这些零散的变量。这样每个类的职责更单一,代码也更好维护。
第一步:创建独立的Circle类
这个类专门负责存储圆的所有状态,并且自己知道怎么绘制自己:
import java.awt.Color; import java.awt.Graphics; public class Circle { // 圆的核心属性:位置、直径、颜色 private int x; private int y; private int diameter; private Color color; // 构造方法,一次性初始化所有属性 public Circle(int x, int y, int diameter, Color color) { this.x = x; this.y = y; this.diameter = diameter; this.color = color; } // 让圆自己实现绘制逻辑,不用外部操心 public void draw(Graphics g) { g.setColor(color); // 注意:Java的fillOval是按左上角坐标绘制的,所以要减去半径让圆心对准鼠标点击点 g.fillOval(x - diameter/2, y - diameter/2, diameter, diameter); } }
第二步:重构Controller类
Controller只需要做两件事:监听鼠标点击事件,创建Circle实例并管理所有圆的集合。另外注意不要每次生成随机数都新建Random对象,复用一个实例更高效:
import java.awt.Color; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.util.HashSet; import java.util.Random; public class Controller implements MouseListener { private HashSet<Circle> circleSet = new HashSet<>(); private Random random = new Random(); // 复用Random,避免频繁创建实例 @Override public void mousePressed(MouseEvent e) { // 生成随机RGB颜色 int r = random.nextInt(256); int g = random.nextInt(256); int b = random.nextInt(256); Color circleColor = new Color(r, g, b); // 生成10到100之间的随机直径(补全了你没写完的逻辑) int diameter = 10 + random.nextInt(91); // 创建新的圆实例,传入鼠标点击的坐标、直径和颜色 Circle newCircle = new Circle(e.getX(), e.getY(), diameter, circleColor); circleSet.add(newCircle); // 这里记得通知界面重绘!如果Controller是界面组件的内部类,直接调用repaint()就行 // 要是是独立类,得持有界面组件的引用再调用repaint() } // MouseListener的其他方法必须实现,空实现即可 @Override public void mouseClicked(MouseEvent e) {} @Override public void mouseReleased(MouseEvent e) {} @Override public void mouseEntered(MouseEvent e) {} @Override public void mouseExited(MouseEvent e) {} // 给界面提供获取圆集合的方法,方便绘制所有圆 public HashSet<Circle> getCircleSet() { return circleSet; } }
第三步:补充界面绘制类(比如DrawingPanel)
最后需要一个负责绘制的面板类,把所有圆都画出来:
import java.awt.Graphics; import javax.swing.JPanel; public class DrawingPanel extends JPanel { private Controller controller; public DrawingPanel(Controller controller) { this.controller = controller; this.addMouseListener(controller); // 给面板绑定鼠标监听器 } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); // 遍历所有圆,调用它们自己的draw方法 for (Circle circle : controller.getCircleSet()) { circle.draw(g); } } }
关键改进点说明
- 职责分离:
Circle管自己的状态和绘制,Controller管事件和集合管理,DrawingPanel管界面渲染,每个类只做一件事。 - 封装性:圆的所有细节都被封装在
Circle类里,外部代码不需要知道圆怎么画,只需要调用draw()就行。 - 效率优化:复用
Random对象,避免每次鼠标点击都新建实例。
内容的提问来源于stack exchange,提问作者TryingToGetBetter
相关产品推荐
相关产品推荐

