基于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
相关产品推荐
相关产品推荐

