You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java Swing调用repaint()重绘时将无关菜单栏绘制到绘图面板如何解决

问题原因

  • 你重写DrawPanel的paintComponent方法时,没有调用父类的super.paintComponent(g)方法:Swing的JPanel默认的paintComponent会完成填充背景色、清理上一次绘制残留内容的工作,缺少这行代码就会导致背景色不生效、上一次界面渲染的内容(包括左侧菜单栏的像素残留)不会被清除,直接和新绘制的图形叠加。
  • 额外问题1:当前代码中绘制图形时没有对坐标差做绝对值处理,如果鼠标从右下往左上拖拽绘制,宽高为负数会导致图形无法正常显示。
  • 额外问题2:当前fillArc的参数传值错误,fillArc的参数顺序为(x坐标, y坐标, 宽度, 高度, 起始角度, 弧的角度),你传入的参数不符合规范会导致弧形绘制异常。
  • 额外问题3:现有逻辑每次重绘只会显示最新绘制的一个图形,之前绘制的内容会被清除,如果需要保留历史绘制记录,需要额外存储历史图形数据。

修复方案

最简修复(仅解决背景不生效、菜单栏残留问题)

修改DrawPanel的paintComponent方法即可:

@Override
public void paintComponent (Graphics g) {
    // 必须加这行,调用父类绘制逻辑清背景、渲染背景色
    super.paintComponent(g);
    g.setColor(color);
    int drawX = Math.min(x1, x2);
    int drawY = Math.min(y1, y2);
    int drawW = Math.abs(x2 - x1);
    int drawH = Math.abs(y2 - y1);
    if (shape.equals("rectangle"))
        g.fillRect(drawX, drawY, drawW, drawH);
    else if (shape.equals("circle"))
        g.fillOval(drawX, drawY, drawW, drawH);
    else if (shape.equals("arc"))
        // 这里角度可根据你的需求调整,示例为绘制180度上半圆
        g.fillArc(drawX, drawY, drawW, drawH, 0, 180);
}

支持保留历史绘图的完整修复版

如果需要保留所有绘制过的图形,可使用修改后的完整DrawPanel代码:

import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.util.ArrayList;
import java.util.List;

public class DrawPanel extends JPanel implements MouseListener, MouseMotionListener {
    int x1, y1, x2, y2;
    Color color = Color.BLACK;
    String shape = "rectangle";
    // 存储历史绘制的所有图形
    List<ShapeItem> historyShapes = new ArrayList<>();

    // 内部类存储单个图形的完整属性
    static class ShapeItem {
        String type;
        Color color;
        int x, y, width, height;

        public ShapeItem(String type, Color color, int x, int y, int width, int height) {
            this.type = type;
            this.color = color;
            this.x = x;
            this.y = y;
            this.width = width;
            this.height = height;
        }
    }

    public DrawPanel() {
        addMouseListener(this);
        addMouseMotionListener(this);
    }

    @Override
    public void paintComponent (Graphics g) {
        super.paintComponent(g);
        // 绘制所有历史图形
        for (ShapeItem item : historyShapes) {
            g.setColor(item.color);
            switch (item.type) {
                case "rectangle":
                    g.fillRect(item.x, item.y, item.width, item.height);
                    break;
                case "circle":
                    g.fillOval(item.x, item.y, item.width, item.height);
                    break;
                case "arc":
                    g.fillArc(item.x, item.y, item.width, item.height, 0, 180);
                    break;
            }
        }
    }

    public void mousePressed(MouseEvent e) {
        x1 = e.getX();
        y1 = e.getY();
    }

    public void mouseReleased(MouseEvent e) {
        x2 = e.getX();
        y2 = e.getY();
        int drawX = Math.min(x1, x2);
        int drawY = Math.min(y1, y2);
        int drawW = Math.abs(x2 - x1);
        int drawH = Math.abs(y2 - y1);
        // 把当前绘制完成的图形加入历史列表
        historyShapes.add(new ShapeItem(shape, color, drawX, drawY, drawW, drawH));
        repaint();
    }

    public void setColor(Color color) {
        this.color = color;
    }

    public void setShape(String shape) {
        this.shape = shape;
    }
    
    // 清空画板方法,可绑定到你的Erase按钮
    public void clearAll() {
        historyShapes.clear();
        repaint();
    }

    public void mouseClicked(MouseEvent e) {}
    public void mouseEntered(MouseEvent e) {}
    public void mouseExited(MouseEvent e) {}
    public void mouseDragged(MouseEvent e) {}
    public void mouseMoved(MouseEvent e) {}
}

内容的提问来源于stack exchange,提问作者Mr. Goose

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 13:54:10