Java绘图问题:如何让新绘制圆形变色且保留历史圆形颜色
实现保留已有圆形颜色的功能
要实现按下R/B/G键后新绘制的圆形用对应颜色、旧圆形保留原有颜色的效果,核心是给每个圆形单独记录颜色,而不是依赖全局统一颜色。下面是修改后的完整代码及关键改动说明:
import javax.swing.JFrame; import javax.swing.JPanel; import java.awt.Color; import java.awt.Graphics; import java.awt.event.KeyListener; import java.awt.event.KeyEvent; import java.awt.event.MouseListener; import java.awt.event.MouseEvent; public class GraphicsEx extends JFrame { private Canvas theCanvas; public GraphicsEx() { super("The Window"); setVisible(true); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setSize(640, 480); theCanvas = new Canvas(); theCanvas.addKeyListener(new ColorSelector(theCanvas)); theCanvas.addMouseListener(new ClickToAddCircles(theCanvas)); theCanvas.setFocusable(true); add(theCanvas); } public static void main(String[] args) { new GraphicsEx(); } // 自定义类存储每个圆形的位置和对应颜色 static class Circle { int x; int y; Color color; public Circle(int x, int y, Color color) { this.x = x; this.y = y; this.color = color; } } class Canvas extends JPanel { private Circle[] circleHistory; private static final int MAX_EVENTS = 1000; private static final int RADIUS = 100; private int totalCircles; private Color currentColor; public Canvas() { setBackground(Color.BLACK); circleHistory = new Circle[MAX_EVENTS]; totalCircles = 0; currentColor = Color.GREEN; // 默认初始颜色为绿色 setFocusable(true); } @Override public void paintComponent(Graphics g) { super.paintComponent(g); // 遍历所有已保存的圆形,用各自的颜色绘制 for (int i = 0; i < totalCircles; i++) { Circle circle = circleHistory[i]; g.setColor(circle.color); g.fillOval(circle.x - RADIUS / 2, circle.y - RADIUS / 2, RADIUS, RADIUS); } } // 修改当前要绘制的新圆形的颜色,不影响已有圆形 public void changeColor(Color newColor) { currentColor = newColor; } // 添加新圆形时,绑定当前选中的颜色 public void addCircle(int x, int y) { if (totalCircles < MAX_EVENTS) { circleHistory[totalCircles++] = new Circle(x, y, currentColor); repaint(); } } } class ClickToAddCircles implements MouseListener { private Canvas theCanvas; public ClickToAddCircles(Canvas theCanvas) { this.theCanvas = theCanvas; } public void mouseClicked(MouseEvent e) {} public void mousePressed(MouseEvent e) { // 点击画布时添加新圆形,传入点击坐标 theCanvas.addCircle(e.getX(), e.getY()); } public void mouseReleased(MouseEvent e) {} public void mouseEntered(MouseEvent e) {} public void mouseExited(MouseEvent e) {} } class ColorSelector implements KeyListener { private Canvas theCanvas; public ColorSelector(Canvas theCanvas) { this.theCanvas = theCanvas; } public void keyPressed(KeyEvent e) {} public void keyReleased(KeyEvent e) {} public void keyTyped(KeyEvent e) { switch (e.getKeyChar()) { case 'r': theCanvas.changeColor(Color.RED); break; case 'g': theCanvas.changeColor(Color.GREEN); break; case 'b': theCanvas.changeColor(Color.BLUE); break; } } } }
核心改动点
- 新增
Circle类:专门绑定每个圆形的坐标和颜色,确保每个圆形都有独立的颜色属性,不会被后续颜色切换操作覆盖。 - 替换存储结构:将Canvas中存储MouseEvent的数组,改为存储Circle对象的数组,实现颜色与位置的一一对应。
- 调整绘制逻辑:paintComponent方法遍历每个Circle对象,使用其自身的颜色绘制,而非全局统一颜色,彻底解决旧圆形变色的问题。
- 保留颜色切换逻辑:
changeColor方法仅修改新圆形的绘制颜色,不会影响已保存的圆形数据。
内容的提问来源于stack exchange,提问作者newtothis123
相关产品推荐
相关产品推荐

