尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
Java Swing实现简单画图工具
Java Swing实现一个简易画图工具直线矩形三角形多边形前言本篇将使用Swing制做一个简易画图工具能够画直线、矩形、三角形、多边形以及调节颜色、笔刷粗细等基础功能。环境JDK 17IntelliJ IDEA纯 Java 项目未使用 Maven一、整体设计程序分成两个类DrawUI负责搭界面窗口、按钮、文本框并把画笔和监听器接起来DrawListener同时实现鼠标和按钮两种监听负责记录坐标和按图形绘制。二、界面与绑定DrawUI2.1 界面组件窗口里放四类东西//图形按钮JButtonjbunewJButton(直线);jf.add(jbu);JButtonjbu2newJButton(矩形);jf.add(jbu2);JButtonjbu3newJButton(三角形);jf.add(jbu3);JButtonjbu4newJButton(多边形);jf.add(jbu4);//颜色按钮JButtonrednewJButton(红);jf.add(red);JButtongreennewJButton(绿);jf.add(green);JButtonbluenewJButton(蓝);jf.add(blue);JButtonblacknewJButton(黑);jf.add(black);//笔刷粗细输入框默认粗细为1JTextFieldwidthnewJTextField(1,5);jf.add(width);2.2 画笔直接从窗体拿并转成 Graphics2Djf.setVisible(true);//必须先设置为可见才能从这个窗体上获取画笔Graphics2Dg(Graphics2D)jf.getGraphics();//向下转型才能用setStroke为什么必须要转化为Graphics2D因为设置线宽的setStroke只在Graphics2D里才有。其中Graphics2D是Graphics的子类转过去后画线的drawLine等通过继承仍然可以使用。2.3 绑定监听器 传递画笔和文本框DrawListenerlistenernewDrawListener();jf.addMouseListener(listener);//为窗体添加鼠标监听器所有绘画操作均发生在窗体jbu.addActionListener(listener);//为各按钮添加动作监听器处理按键点击...//其余按钮同理listener.widthwidth;//把线宽输入框的输入内容引用传递给监听器listener.grg;//将画笔交给监听器这里就是事件源组件/ 监听器 / 绑定三要素组件产生动作监听器负责处理addXxxListener将两者接起来。三、事件处理DrawListener3.1 一个类实现两个接口publicclassDrawListenerimplementsMouseListener,ActionListener{//同时实现两个接口就无需再使用两个类增加程序复杂度了publicGraphics2Dgr;//画笔publicintx1,y1,x2,y2,x3,y3;//坐标publicintmode0;//0直线 1矩形 2三角形 3多边形publicintflag0;//标记位控制绘制阶段publicColorcolorColor.BLACK;//默认颜色黑色publicJTextFieldwidth;//线宽输入框一个类可以同时实现多个接口所以既接按钮点击、又接鼠标动作。3.2 按钮切换图形和颜色actionPerformedpublicvoidactionPerformed(ActionEvente){Stringnamee.getActionCommand();//获取按钮上的文字switch(name){case直线:mode0;break;//根据不同按钮做出不同响应影响后续坐标处理case矩形:mode1;break;case三角形:mode2;break;case多边形:mode3;break;case红:colorColor.RED;break;//颜色按钮设定画笔颜色case绿:colorColor.GREEN;break;case蓝:colorColor.BLUE;break;case黑:colorColor.BLACK;break;}flag0;//切换图形时把标记位清0避免残留}按钮名不同图形名 / 颜色名所以放同一个switch里区分。3.3 鼠标事件三个方法、固定顺序注意一次按下再松开会触发顺序固定mousePressed → mouseReleased → mouseClicked所以不能让三个方法都去写同一组坐标否则会覆盖掉前面记录的坐标。于是对各按键进行分工mousePressed记录起点mouseReleased记录终点坐标同时触发绘图函数mouseClicked处理多点图形后续的点。四、记录 分发的架构鼠标事件只负责记录坐标真正怎么画统一交给draw()它按mode分发publicvoiddraw(){gr.setColor(color);//绘图前设置当前颜色intwid1;//绘图前读取当前线宽try{widInteger.parseInt(width.getText().trim());//尝试读取线宽输入框输入并转化为int类型}catch(Exceptionex){//如果失败则将线宽设为默认值1wid1;}if(wid1)wid1;gr.setStroke(newBasicStroke(wid));//设置线宽if(mode0){...}//直线if(mode1){...}//矩形if(mode2){...}//三角形if(mode3){...}//多边形}好处加新图形只需要在draw()里多一个if不用动鼠标事件。4.1 直线、矩形两点图形按下记起点、松开记终点直接画// mousePressed: x1 e.getX(); y1 e.getY();// mouseReleased: x2 e.getX(); y2 e.getY(); draw();if(mode0){gr.drawLine(x1,y1,x2,y2);}if(mode1){//用 min 取左上角用abs保证宽高为正gr.drawRect(Math.min(x1,x2),Math.min(y1,y2),Math.abs(x2-x1),Math.abs(y2-y1));}4.2 三角形拖动底边 点一下补第三点用flag分两个阶段flag0等底边flag1等第三点。// mousePressed (flag0):记底边起点// mouseReleased(flag0):记底边终点,draw(),flag更新为1// mouseClicked (flag1):记第三点,draw(),flag重置为0if(mode2){if(flag0)gr.drawLine(x1,y1,x2,y2);//底边if(flag1){//两条侧边gr.drawLine(x1,y1,x3,y3);gr.drawLine(x2,y2,x3,y3);}}4.3 多边形拖动第一条边 依次点双击闭合用两组坐标迭代每来一个新点就和上一个点连一段始终记住第一个点最后闭合。x1,y1 第一个点固定x2,y2 上一个点不断更新x3,y3 当前新点//mouseReleased(flag0):画第一条边,然后点二继承点三x2x3;y2y3;flag1//mouseClicked(flag1):画最新一段,再x2x3;y2y3;//若e.getClickCount()2双击则闭合,与点一连接flag重置为0if(mode3){if(flag0||flag1)gr.drawLine(x2,y2,x3,y3);if(flag2)gr.drawLine(x1,y1,x2,y2);//双击闭合}关键每画完一段都要x2 x3; y2 y3;将这次画线的起点替换为终点坐标否则下一段会从错误的点出发。五、颜色与线宽颜色按钮设置colordraw()里每次先gr.setColor(color)。线宽文本框输入Integer.parseInt转成整数gr.setStroke(new BasicStroke(w))。parseInt遇到非数字会抛出异常try/catch做出响应返还默认值1。BasicStroke的线宽必须≥1因此加了if (wid 1) wid 1;验证。六、错误记录switch忘了break每个case后不加break就不会终止将会执行其后的所有指令结果不管点哪个按钮mode都变成最后一个值。Graphics没有setStrokesetStroke是Graphics2D的方法。字段声明成Graphics无法调用线宽方法必须声明成Graphics2D。在draw()里改flag导致两个分支都执行flag应该只在事件里改draw()只负责按当前flag画。把改flag写进draw()会出现画完 A 又立刻画 B。七、总结本篇使用Swing完成了一个能画多种图形、能选颜色和线宽的画图工具。介绍了事件处理流程以及绘图部分记录和绘制分离的架构后续添加新图形仅需更改绘制部分即可具有较好的延展性。
RELATED

相关推荐

从公共基础设施到资本增值工具:平台异化下内容生态的崩塌与独立站点出路

从公共基础设施到资本增值工具:平台异化下内容生态的崩塌与独立站点出路

摘要本文以互联网平台的内容治理与资本运作为研究对象,揭示平台如何在资本驱动下从本应中立、公共的基础设施异化为资本增值的工具。文章指出,这种异化通过规则随意性、算法黑箱与层层收割机制,系统性侵蚀内容生态的多样性与创作者权益&#…

📅 2026/10/9 7:57:35
AI 辅助嵌入式系统设计:接口定义与模块划分的正确打开方式

AI 辅助嵌入式系统设计:接口定义与模块划分的正确打开方式

AI 辅助嵌入式系统设计:接口定义与模块划分的正确打开方式 文章目录 AI 辅助嵌入式系统设计:接口定义与模块划分的正确打开方式 一、引言:AI 从"代码工人"升级为"设计参谋" 二、API 设计建议:接口定义的"草案机" 2.1 四步法 2.2 生成效果:一…

📅 2026/10/9 7:57:35
如何让代码与流程无可挑剔:轻量级自动化检查实践

如何让代码与流程无可挑剔:轻量级自动化检查实践

1. 一个词引发的思考:为什么“impeccable”值得单独拿出来聊第一次看到“impeccable”这个词被当成一个项目标题,我的反应是愣了一下。这词在英文里是“无可挑剔的、完美的”意思,日常对话里其实不算高频,但一旦被拎出来做项目名&…

📅 2026/10/9 7:52:34
MORE NEWS

更多资讯

📰

化工行业数字化转型:点线面框架与六大核心模块全解析

1. 化工行业数字化转型到底在转什么先说一个我最近经常被问到的问题:化工行业的数字化转型,和互联网、金融行业的数字化转型,到底是不是一回事?答案是有交集,但差异很大。互联网行业的转型,核心是流量、用户…

📰

MySQL索引失效全解析:从最左前缀到EXPLAIN定位慢查询

1. 从一个慢查询说起:索引失效到底在说什么 做后端开发的朋友一定遇到过这样的场景:一条 SQL 昨天还跑得好好的,今天数据量稍微涨了一点,响应时间从 50ms 直接飙到 3s。DBA 一查,告诉你"索引失效了"。更常见…

📰

2026自由职业者接单平台怎么选?六大渠道对比与避坑指南

作为一名经常在接单平台间来回切换的老自由职业者,我太懂“挑平台”这件事有多消耗精力了。明明活儿还没接到,先被一堆平台规则、提现门槛和中介抽成搞到头大。2026年这个节点,市面上的接单渠道确实又洗了一轮牌,有的平台越做越规…

📰

编码迁移工具ZCode自动修复事故复盘与安全上线实践

十天后,我们终于拿到了第三方核查的技术结论。ZCode 新功能从线上启用、触发故障再到内部复盘,整个过程就像过山车一样,现在总算有一个能说服所有人的落点。今天这篇文章把“风波”的成因、核查报告的解读方式,以及新功能后续怎么…

📰

轴承故障诊断实战:小波时频图与Swin Transformer端到端方案

简介:这份资源面向具备Python与深度学习基础的科研人员、研究生及工业设备诊断工程师,提供一套基于小波时频图(WTFP)结合移位窗口视觉Transformer(ST)的轴承故障诊断完整项目实例。它解决非平稳振动、工况变…

📰

基于Java的教务系统开发:从表结构设计到并发选课的完整实战

简介:基于 Java 开发的教务系统,是一套面向后端初学者的 SSM 整合练手项目,适合正在学习 Spring、SpringMVC、MyBatis 和 Shiro 安全框架的开发者。项目以教务查询为切入点,涉及管理员、教师、学生三类角色,覆盖登录认…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬