简易画图工具

发布时间:2026/8/26 17:53:32
简易画图工具 项目概览简易画图工具这个程序主要由两部分组成界面搭建 (draw0806.java)负责创建窗口、按钮和画板。逻辑控制 (DrawListener.java)负责监听鼠标点击、拖拽和按钮操作实现绘图功能。核心代码解析界面搭建draw0806.java这部分代码主要使用了 Swing 库来构建用户界面。窗口设置创建了一个 JFrame设置了大小800x800和标题。布局管理使用了 BorderLayout边界布局。北部 (NORTH)放置了一个绿色的 JPanel里面塞满了各种功能的 JButton直线、矩形、颜色选择等。中部 (CENTER)放置了一个白色的 JPanel这是“画纸”。事件绑定这是最关键的一步。代码创建了 DrawListener 对象并将它绑定到了窗口和所有按钮上。细节代码中有一行 jf.setDefaultCloseOperation(3);。这里的 3 其实对应的是 JFrame.EXIT_ON_CLOSE意思是关闭窗口时退出程序。逻辑控制DrawListener.java这个类实现了三个接口MouseListener鼠标监听、MouseMotionListener鼠标移动监听和 ActionListener按钮动作监听。变量传递通过 listener.gr g;把画板的画笔对象 Graphics 传给了监听器这样监听器才能画图。核心绘图逻辑直线在 mousePressed 记录起点mouseReleased 记录终点调用 gr.drawLine。矩形利用 Math.abs 和 Math.min 计算矩形的左上角坐标和宽高处理了从右向左拖动的情况。曲线/橡皮擦在 mouseDragged 中实现。橡皮擦的原理其实就是画很粗的白色线条BasicStroke(30)。多边形/三角形利用 flag 标志位和 mouseClicked 事件来记录多个顶点。功能按钮 触发事件 核心逻辑 (Graphics方法) 备注直线 按下松开 drawLine(x1, y1, x2, y2) 最基础的绘图矩形 按下松开 drawRect(x, y, width, height) 需要计算绝对值防止负数宽高曲线 拖拽 drawLine (连续绘制) 每次拖拽更新起点形成连续线条橡皮擦 拖拽 setColor(WHITE) setStroke(30) 本质是画白色的粗线任意多边形 多次点击 drawLine (连接顶点) 双击闭合图形颜色选择 点击按钮 setColor(Color.RED/BLUE…) 改变画笔颜色遇到的问题与思考 (Debug笔记)在研究这两段代码时我发现了一些值得注意的地方坐标系的“错误数字”代码里多次出现了 y y - 70。原因这是因为顶部的按钮面板占用了大约70像素的高度。鼠标监听获取的是相对于整个窗口JFrame的坐标而绘图是相对于中间面板drawPanel的所以必须减去顶部的高度偏移。总结“事件驱动编程” 的思想用户操作点击/拖拽 - 监听器捕获 - 调用Graphics API绘图。代码packagedrawUI;/** * author ZHANG * date 2026/8/7 11:44 * description */importjavax.swing.*;importjava.awt.*;importjava.awt.event.MouseListener;publicclassdraw0806{publicvoidinitUI(){JFramejfnewJFrame();jf.setSize(800,800);jf.setTitle(画图工具);jf.setLocationRelativeTo(null);jf.setDefaultCloseOperation(3);jf.setLayout(newBorderLayout());JPanelnorthPanelnewJPanel();northPanel.setBackground(Color.GREEN);northPanel.setPreferredSize(newDimension(0,40));jf.add(northPanel,BorderLayout.NORTH);JButtonjbunewJButton(直线);northPanel.add(jbu,BorderLayout.NORTH);JButtonjbu2newJButton(矩形);northPanel.add(jbu2,BorderLayout.NORTH);JButtonjbu3newJButton(任意三角形);northPanel.add(jbu3,BorderLayout.NORTH);JButtonjbu4newJButton(任意多边形);northPanel.add(jbu4,BorderLayout.NORTH);JButtonjbu5newJButton(曲线);northPanel.add(jbu5,BorderLayout.NORTH);JButtonjbu6newJButton(橡皮擦);northPanel.add(jbu6,BorderLayout.NORTH);JButtonrednewJButton(红色);northPanel.add(red,BorderLayout.NORTH);JButtonbluenewJButton(蓝色);northPanel.add(blue,BorderLayout.NORTH);JButtonblacknewJButton(黑色);northPanel.add(black,BorderLayout.NORTH);JPaneldrawPanelnewJPanel();drawPanel.setBackground(Color.WHITE);jf.add(drawPanel,BorderLayout.CENTER);jf.setVisible(true);GraphicsgdrawPanel.getGraphics();DrawListenerlistenernewDrawListener();jf.addMouseListener(listener);jf.addMouseMotionListener(listener);jbu.addActionListener(listener);jbu2.addActionListener(listener);jbu3.addActionListener(listener);jbu4.addActionListener(listener);jbu5.addActionListener(listener);jbu6.addActionListener(listener);red.addActionListener(listener);blue.addActionListener(listener);black.addActionListener(listener);jf.addMouseListener(listener);listener.grg;}publicstaticvoidmain(String[]args){draw0806 uinewdraw0806();ui.initUI();}}绘图方法packagedrawUI;importjava.awt.*;importjava.awt.event.*;/** * author ZHANG * date 2026/8/7 15:28 * description */publicclassDrawListenerimplementsMouseListener,ActionListener,MouseMotionListener{publicGraphicsgr;publicintx1,y1,x2,y2,x3,y3,x4,y4;publicStringname;publicintflag1;publicvoidmouseDragged(MouseEvente){x4e.getX();y4e.getY();y4y4-70;if(曲线.equals(name)){Graphics2Dg2(Graphics2D)gr;g2.setStroke(newBasicStroke(5));gr.drawLine(x1,y1,x4,y4);x1x4;y1y4;}if(橡皮擦.equals(name)){Graphics2Dg2(Graphics2D)gr;g2.setStroke(newBasicStroke(30));gr.setColor(Color.white);gr.drawLine(x1,y1,x4,y4);x1x4;y1y4;}}publicvoidmouseMoved(MouseEvente){}publicvoidactionPerformed(ActionEvente){namee.getActionCommand();System.out.println(点击按钮name name);}publicvoidmouseClicked(MouseEvente){x3e.getX();y3e.getY();y3y3-70;if(任意三角形.equals(name)){Graphics2Dg2(Graphics2D)gr;g2.setStroke(newBasicStroke(5));gr.drawLine(x1,y1,x3,y3);gr.drawLine(x2,y2,x3,y3);flag1;System.out.println(x3 x3 y3 y3);}//判断是否双击: e.getClickCount() 2if(任意多边形.equals(name)){Graphics2Dg2(Graphics2D)gr;g2.setStroke(newBasicStroke(5));gr.drawLine(x2,y2,x3,y3);x2x3;y2y3;System.out.println(x3 x3 y3 y3);if(e.getClickCount()2){gr.drawLine(x1,y1,x3,y3);flag1;}}}publicvoidmousePressed(MouseEvente){System.out.println(按下);if(flag1){x1e.getX();y1e.getY();y1y1-70;}System.out.println(x1 x1 y1 y1);}publicvoidmouseReleased(MouseEvente){System.out.println(松开);if(flag1){x2e.getX();y2e.getY();y2y2-70;}System.out.println(x2 x2 y2 y2);intwMath.abs(x2-x1);intmxMath.min(x2,x1);if(直线.equals(name)){Graphics2Dg2(Graphics2D)gr;g2.setStroke(newBasicStroke(5));gr.drawLine(x1,y1,x2,y2);}if(矩形.equals(name)){Graphics2Dg2(Graphics2D)gr;g2.setStroke(newBasicStroke(5));gr.drawRect(mx,y1,w,y2-y1);}if(任意三角形.equals(name)){Graphics2Dg2(Graphics2D)gr;g2.setStroke(newBasicStroke(5));gr.drawLine(x1,y1,x2,y2);flag;}if(任意多边形.equals(name)flag1){Graphics2Dg2(Graphics2D)gr;g2.setStroke(newBasicStroke(5));gr.drawLine(x1,y1,x2,y2);flag;}if(红色.equals(name)){Graphics2Dg2(Graphics2D)gr;g2.setStroke(newBasicStroke(5));gr.setColor(Color.RED);gr.drawLine(x1,y1,x2,y2);}if(黑色.equals(name)){Graphics2Dg2(Graphics2D)gr;g2.setStroke(newBasicStroke(5));gr.setColor(Color.black);gr.drawLine(x1,y1,x2,y2);}if(蓝色.equals(name)){Graphics2Dg2(Graphics2D)gr;g2.setStroke(newBasicStroke(5));gr.setColor(Color.BLUE);gr.drawLine(x1,y1,x2,y2);}}publicvoidmouseEntered(MouseEvente){}publicvoidmouseExited(MouseEvente){}}