简易画图工具
项目概览简易画图工具这个程序主要由两部分组成界面搭建 (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){}}

相关新闻

[光学原理与应用-552]:非线性晶体倍频:宇宙的底层真相,藏在光的湮灭与新生里

[光学原理与应用-552]:非线性晶体倍频:宇宙的底层真相,藏在光的湮灭与新生里

非线性晶体倍频:宇宙的底层真相,藏在光的湮灭与新生里人类肉眼所见的光学世界,是线性、平稳、守恒、无新生的常态世界。光线穿过玻璃、透镜、偏振片,只会改变传播方向、相位、偏振姿态,频率恒定、能量恒定、光子本体恒…

2026/11/14 11:00:53 阅读更多 →
Agent 代码止步于本地调试?生产环境下的工程化缺陷与应对策略

Agent 代码止步于本地调试?生产环境下的工程化缺陷与应对策略

Agent 代码止步于本地调试?生产环境下的工程化缺陷与应对策略 引言 近年来,基于大语言模型的 AI Agent 在代码生成领域展现了惊人的能力——快速搭建骨架、补齐常见逻辑、遵循语法规范,局部效率提升显著。然而,许多团队在实践中发…

2026/11/12 4:04:31 阅读更多 →
移动版藏内容,AI爬虫直接跳过

移动版藏内容,AI爬虫直接跳过

很多人以为网站做了响应式设计就万事大吉,但GEO时代移动适配的标准已经变了。AI爬虫默认用手机UA抓取,超过60%的AI搜索查询发生在移动端。如果你的核心内容在移动版被CSS折叠隐藏、表格横向滚动、Schema靠JS动态注入,AI看到的可能只是一个&qu…

2026/10/31 6:14:15 阅读更多 →

最新新闻

Electron桌面应用开发实战:从环境搭建到打包发布全流程

Electron桌面应用开发实战:从环境搭建到打包发布全流程

做前端这些年,我大部分时间都在跟浏览器标签页打交道,直到第一次把桌面应用跑起来,才发现原来自己一直被限制在地址栏和刷新按钮围起来的框框里。Electron这个词,最开始是在某段时间频繁出现在同事的讨论里,一个用HTML…

2026/11/14 5:13:29 阅读更多 →
滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

简介:亚太天能T109滑盖智能锁产品说明书是一份PDF格式的官方技术文档,主要面向智能锁安装人员、终端用户及售后维护者,帮助快速掌握产品安装、配置与常见故障处理。全包仅1个PDF文件,大小4.37MB,内容结构清晰&#xff…

2026/11/14 5:13:29 阅读更多 →
PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

上个月我在调试一台高速AGV的驱动系统,整车要求空载跑到8m/s,电机转速已经拉到额定点,驱动器的输出电压也顶到了母线电压极限附近。再往上踩速度指令,转速纹丝不动,三相电流反而开始震荡。那会儿我的第一反应就是&…

2026/11/14 5:13:29 阅读更多 →
C++核心知识点:从内存管理到STL的实战指南

C++核心知识点:从内存管理到STL的实战指南

C 这门语言我前前后后折腾了十几年,用它写过嵌入式驱动、做过游戏服务端,也搭过基础组件库。每次看到新人一头扎进"C 核心知识点"这个搜索词,我其实挺感慨的——这门语言的难点从来不是语法多,而是知识点之间的耦合太深…

2026/11/13 22:08:41 阅读更多 →
T109滑盖智能锁怎么装?安装调试与故障排查全攻略

T109滑盖智能锁怎么装?安装调试与故障排查全攻略

简介:亚太天能T109滑盖智能锁产品说明书以PDF格式发布,适合智能锁用户、安装人员与售后维修人员阅读。内容围绕T109系列指纹密码刷卡锁展开,先介绍前面板、后面板、锁体、机械钥匙、电池盒盖等部件名称与功能,再给出完整安装步骤&…

2026/11/14 2:41:37 阅读更多 →
LLM知识降熵:从信息垄断到理解权下放

LLM知识降熵:从信息垄断到理解权下放

你有没有过这种经历:翻开源码注释、论文摘要或者一份专业报告,每个字都认识,连在一起却像天书。想找人聊聊,身边要么没人懂,要么懂的懒得跟你解释。后来我试着把同一段内容丢给一个大语言模型,几秒钟之后&a…

2026/11/14 5:13:29 阅读更多 →

日新闻

周新闻

月新闻