Java AWT中修改已绘制Graphics对象颜色不生效及代码优化求助
问题原因分析
- 控件初始化逻辑错误:
Button的创建、添加以及监听器绑定逻辑放到了paint()方法中,paint()会被系统频繁触发调用,会导致重复创建大量按钮、重复绑定监听器,造成资源浪费 - 颜色修改逻辑无效:监听器中仅对
paint()方法传入的临时Graphics对象设置颜色,没有触发页面重绘,也没有保存当前选中的颜色,且循环遍历所有颜色列表的操作最终只会将颜色设置为列表最后一个值,没有实际切换效果 - 缓存了失效的Graphics对象:
paint()方法传入的Graphics是临时对象,每次页面重绘时系统都会生成新的实例,监听器中持有旧的Graphics对象操作不会生效
修复思路
- 新增成员变量存储当前绘制颜色、颜色列表索引、按钮实例,所有控件初始化逻辑放到构造方法中执行,仅执行一次
paint()方法中仅保留绘制逻辑,绘制前先将画笔颜色设置为当前存储的颜色- 按钮点击事件中修改当前颜色索引,更新当前绘制颜色后调用
repaint()方法触发页面重绘,实现颜色更新
修正后的完整代码
import java.awt.*; import java.awt.event.*; import java.util.Arrays; import java.util.List; public class TestGraphic extends Figure { // 存储当前绘制使用的颜色 private Color currentColor = Color.BLACK; // 颜色列表 private final List<Color> colorList = Arrays.asList(Color.black, Color.blue , Color.cyan, Color.red, Color.green, Color.magenta, Color.orange, Color.yellow); // 当前颜色对应的索引 private int colorIndex = 0; TestGraphic(){ setSize(600,600); closeFrame(); // 控件初始化仅在构造方法中执行一次 Button btn = new Button("Change color"); btn.setBounds(30,100,80,30); add(btn); // 绑定颜色切换监听器 btn.addActionListener(e -> { // 索引+1后取模,实现循环切换 colorIndex = (colorIndex + 1) % colorList.size(); currentColor = colorList.get(colorIndex); // 触发重绘 repaint(); }); // 关闭默认布局,方便控件用setBounds定位 setLayout(null); } public static void main(String[] args) { TestGraphic test = new TestGraphic(); test.setVisible(true); } @Override public void paint(Graphics gui) { // 先调用父类paint方法,保证控件正常渲染 super.paint(gui); drawComponent(gui); } public void drawComponent(Graphics gui) { // 绘制前先设置当前颜色 gui.setColor(currentColor); gui.drawOval(108,110,200,200); gui.drawOval(160,150,20,20); gui.drawOval(240,150,20,20); gui.drawRect(160,220,100,40); } @Override void draw(Graphics gui) { } @Override public boolean contains(int x, int y) { return false; } private void closeFrame(){ addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent windowEvent){ System.exit(0); } }); } }
额外优化建议
- 建议使用Swing而非AWT进行GUI开发,AWT是老旧的重型控件框架,Swing作为轻量框架功能更完善,兼容性更好
- 自定义绘制逻辑建议放到
paintComponent()方法而非paint()方法,更符合Swing/AWT的绘制分层规范 - 如果需要绘制的图形较多,可以单独封装图形类,存储每个图形的位置、大小、颜色属性,绘制时遍历列表渲染,方便后续扩展修改
内容的提问来源于stack exchange,提问作者Marwane
相关产品推荐
相关产品推荐

