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

基于Swing的Java形状绘图程序MouseListener调用DrawView问题求助

Swing绘图程序无法绘图问题修复方案

存在的核心问题

  • DrawControl重复创建JFrame实例,且未将自定义绘图组件DrawView添加到窗口容器中,paintComponent方法永远不会被触发
  • 定义了MouseListener但未绑定到绘图区域,点击事件无法被捕获
  • DrawModel构造方法为空,传入的坐标、颜色、形状参数未赋值给类属性,读取的属性永远是默认值
  • MouseListener点击逻辑错误:仅临时创建DrawView实例未挂载到容器,也未传递任何绘图数据
  • 缺少全局绘图数据存储列表,无法保留所有已绘制图形

修复后的完整代码

1. Shape枚举(无需修改)

public enum Shape {
    DOT,
    RECT,
    OVAL
}

2. DrawModel类(补全构造方法赋值逻辑)

import java.awt.*;

public class DrawModel {
    private int x;
    private int y;
    private int width;
    private int height;
    private Shape shapeType;
    private Color color;

    public DrawModel(int x, int y, int width, int height, Shape shapeType, Color color){
        this.x = x;
        this.y = y;
        this.width = width;
        this.height = height;
        this.shapeType = shapeType;
        this.color = color;
    }

    public int getX() {
        return x;
    }

    public int getY() {
        return y;
    }

    public int getWidth() {
        return width;
    }

    public int getHeight() {
        return height;
    }

    public Shape getShapeType() {
        return shapeType;
    }

    public Color getColor() {
        return color;
    }
}

3. DrawView类(新增绘图数据列表和添加图形的方法,遍历绘制所有图形)

import java.awt.*;
import java.util.ArrayList;
import java.util.List;
import javax.swing.*;

public class DrawView extends JPanel {
    private List<DrawModel> drawModelList = new ArrayList<>();

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        for (DrawModel s : drawModelList) {
            drawShape(g, s);
        }
    }

    private void drawShape(Graphics g, DrawModel s) {
        if (s == null) {
            return;
        }
        g.setColor(s.getColor());
        switch (s.getShapeType()) {
            case DOT:
                g.fillOval(s.getX(), s.getY(), 10, 10);
                break;
            case OVAL:
                g.fillOval(s.getX(), s.getY(), s.getWidth(), s.getHeight());
                break;
            case RECT:
                g.fillRect(s.getX(), s.getY(), s.getWidth(), s.getHeight());
                break;
        }
    }

    public void addDrawModel(DrawModel model) {
        this.drawModelList.add(model);
        repaint();
    }
}

4. DrawControl类(修复窗口结构、绑定鼠标监听、补全点击逻辑)

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class DrawControl extends JFrame {
    private Color currColor = Color.BLACK;
    private Shape currShape = Shape.DOT;
    private int pressX, pressY;
    private DrawView drawView;

    public DrawControl() {
        setTitle("Drawing Program");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(800, 800);
        setLocationRelativeTo(null);

        drawView = new DrawView();
        drawView.setBackground(Color.white);
        drawView.setLayout(new BorderLayout());

        JPanel menu = new JPanel();
        menu.setLayout(new FlowLayout());

        JButton buttonBlack = new JButton("Black");
        JButton buttonRed = new JButton("Red");
        JButton buttonGreen = new JButton("Green");
        JButton buttonDot = new JButton("Dot");
        JButton buttonOval = new JButton("Oval");
        JButton buttonRect = new JButton("Rect");
        JButton buttonUndo = new JButton("Undo");
        JButton buttonSave = new JButton("Save");
        JButton buttonLoad = new JButton("Load");

        menu.add(buttonBlack);
        menu.add(buttonRed);
        menu.add(buttonGreen);
        menu.add(buttonDot);
        menu.add(buttonOval);
        menu.add(buttonRect);
        menu.add(buttonUndo);
        menu.add(buttonSave);
        menu.add(buttonLoad);

        buttonBlack.addActionListener(e -> setColor(Color.BLACK));
        buttonRed.addActionListener(e -> setColor(Color.RED));
        buttonGreen.addActionListener(e -> setColor(Color.GREEN));
        buttonDot.addActionListener(e -> setShape(Shape.DOT));
        buttonOval.addActionListener(e -> setShape(Shape.OVAL));
        buttonRect.addActionListener(e -> setShape(Shape.RECT));

        drawView.addMouseListener(new MouseAdapter() {
            @Override
            public void mousePressed(MouseEvent e) {
                pressX = e.getX();
                pressY = e.getY();
                if (currShape == Shape.DOT) {
                    drawView.addDrawModel(new DrawModel(pressX, pressY, 0, 0, currShape, currColor));
                }
            }

            @Override
            public void mouseReleased(MouseEvent e) {
                if (currShape == Shape.RECT || currShape == Shape.OVAL) {
                    int releaseX = e.getX();
                    int releaseY = e.getY();
                    int width = Math.abs(releaseX - pressX);
                    int height = Math.abs(releaseY - pressY);
                    int x = Math.min(pressX, releaseX);
                    int y = Math.min(pressY, releaseY);
                    drawView.addDrawModel(new DrawModel(x, y, width, height, currShape, currColor));
                }
            }
        });

        JLabel current = new JLabel("...");

        add(drawView);
        drawView.add(menu, BorderLayout.NORTH);
        drawView.add(current, BorderLayout.SOUTH);
        setVisible(true);
    }

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

    public void setShape(Shape shape) {
        this.currShape = shape;
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(DrawControl::new);
    }
}

功能说明

  • 点模式:点击绘图区直接生成对应颜色的点
  • 矩形/椭圆模式:按住鼠标拖拽调整大小,松开鼠标生成对应形状
  • 默认初始为黑色点模式,可点击顶部按钮切换颜色和形状

内容的提问来源于stack exchange,提问作者nana

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 17:45:02