编程入门:用Java画一个象棋棋盘
Java图形界面入门手把手教你画一个中国象棋棋盘附完整代码先放效果图一、准备工作新建窗体和所有Swing程序一样第一步是创建一个JFrame窗口。我们新建一个类GoBangUI在showUI()方法中设置窗体的基本属性packagexiang_qi;importjavax.swing.*;importjava.awt.*;publicclassGoBangUI{publicvoidshowUI(){JFramejfnewJFrame();jf.setTitle(象棋);// 设置标题jf.setSize(450,500);// 设置大小宽450高500jf.setLocation(500,200);// 设置窗口在屏幕上的位置jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);// 关闭按钮退出程序jf.setVisible(true);// 让窗口显示出来}publicstaticvoidmain(String[]args){GoBangUIuinewGoBangUI();ui.showUI();}}此时运行你会看到一个空白的灰色窗口接下来我们要在上面画棋盘。二、绘制棋盘的步骤我们需要在窗体的“画布”上做四件事画线、填充底色、写字、贴背景图片。1. 画线drawLinedrawLine(x1, y1, x2, y2)方法用于画一条从(x1, y1)到(x2, y2)的线段。我们先定义几个常量方便后续计算X 50棋盘最左边那条线的 X 坐标Y 75棋盘最上边那条线的 Y 坐标SIZE 40每个格子的大小像素ROW 10行数中国象棋是10行COL 9列数中国象棋是9列画横线10行每行一条横线for(inti0;iROW;i){g.drawLine(X,Yi*SIZE,X(COL-1)*SIZE,Yi*SIZE);}画竖线9列但中间有“楚河汉界”断开所以分为上下两段for(inti0;iCOL;i){if(i0||iCOL-1){// 最左边和最右边的竖线要画通到底g.drawLine(Xi*SIZE,Y,Xi*SIZE,Y(ROW-1)*SIZE);}else{// 中间的竖线只画上半部分到第4行和下半部分从第5行开始g.drawLine(Xi*SIZE,Y,Xi*SIZE,Y4*SIZE);g.drawLine(Xi*SIZE,Y5*SIZE,Xi*SIZE,Y(ROW-1)*SIZE);}}画斜线两个“九宫格”的斜线// 上方九宫格g.drawLine(X3*SIZE,Y,X5*SIZE,Y2*SIZE);g.drawLine(X5*SIZE,Y,X3*SIZE,Y2*SIZE);// 下方九宫格g.drawLine(X3*SIZE,Y9*SIZE,X5*SIZE,Y7*SIZE);g.drawLine(X5*SIZE,Y9*SIZE,X3*SIZE,Y7*SIZE);2. 填充底色fillRect为了让棋盘看起来更真实我们先用一个矩形铺上木色背景。fillRect(x, y, width, height)会画一个以(x, y)为左上角、指定宽高的实心矩形。ColorcolornewColor(202,141,20);// 木黄色RGBg.setColor(color);g.fillRect(X-SIZE/2,Y-SIZE/2,(COL-1)*SIZESIZE,(ROW-1)*SIZESIZE);g.setColor(Color.BLACK);// 画线前改回黑色小技巧在 IntelliJ IDEA 中new Color(r, g, b)的括号里可以直接点击颜色预览帮你肉眼选色非常方便。3. 写字drawString中国象棋棋盘中央需要写“楚河”和“汉界”并且“汉界”正立“楚河”倒置让对阵双方各看各的。drawString(text, x, y)的(x, y)是文字左下角的位置基线。若字体大小为负数文字就会上下颠倒。// 写“汉界”正立Stringtext汉 界;FontfontnewFont(篆体,Font.BOLD,30);g.setFont(font);g.drawString(text,90,265);// 写“楚河”倒置Stringtext2楚 河;Fontfont2newFont(篆体,Font.BOLD,-30);// 负字号实现翻转g.setFont(font2);g.drawString(text2,330,245);注意负字号翻转并非所有系统都稳定更标准的方法是使用Graphics2D旋转但作为入门教学此技巧简洁直观。4. 贴入背景图片drawImage我们还可以在窗体的顶部或背景加上一张图片例如棋盘的木质纹理或装饰图。ImageIconimgnewImageIcon(C:\\Users\\chenjiaqin\\Desktop\\download.png);g.drawImage(img.getImage(),0,40,800,800,null);drawImage的参数依次为图片对象、左上角 X、左上角 Y、宽度、高度、图像观察者通常写null即可。三、一个问题线条会消失按照上面的代码如果直接在showUI()方法里用getGraphics()获取画笔并画图当你拖动窗口边缘改变大小、最小化再还原、或者被其他窗口遮挡后再显示你画的线条、文字和图片都会消失只剩下灰色的背景。为什么会这样因为 Java Swing 的窗口在每次需要重绘时比如上述事件系统会自动调用paint(Graphics g)方法来刷新界面。如果你没有重写paint默认的paint只会清空画布并画一个灰色背景你之前用getGraphics画上去的内容就像用粉笔写在黑板上被彻底擦除了。怎么办解决方法就是重写paint方法。我们把所有绘图代码都放在paint方法里这样每次系统要求重绘时都会自动执行我们的画图逻辑图形就会“永久”保留。四、正确的做法继承 JFrame 并重写 paint新建一个类MyFrame继承JFrame并重写paint方法packagexiang_qi;importjavax.swing.*;importjava.awt.*;publicclassMyFrameextendsJFrame{// 背景图片ImageIconimgnewImageIcon(C:\\Users\\chenjiaqin\\Desktop\\download.png);// 重写 paint 方法publicvoidpaint(Graphicsg){// 必须保留调用父类的 paint完成清空、绘制边框等基础工作super.paint(g);System.out.println(窗体刷新);// 可以观察每次重绘的时机// 画背景图片g.drawImage(img.getImage(),0,40,800,800,null);// 定义棋盘参数intX50,Y75,SIZE40,ROW10,COL9;// 填充木色背景ColorcolornewColor(202,141,20);g.setColor(color);g.fillRect(X-SIZE/2,Y-SIZE/2,(COL-1)*SIZESIZE,(ROW-1)*SIZESIZE);g.setColor(Color.BLACK);// 画横线for(inti0;iROW;i){g.drawLine(X,Yi*SIZE,X(COL-1)*SIZE,Yi*SIZE);}// 画竖线断开楚河汉界for(inti0;iCOL;i){if(i0||iCOL-1){g.drawLine(Xi*SIZE,Y,Xi*SIZE,Y(ROW-1)*SIZE);}else{g.drawLine(Xi*SIZE,Y,Xi*SIZE,Y4*SIZE);g.drawLine(Xi*SIZE,Y5*SIZE,Xi*SIZE,Y(ROW-1)*SIZE);}}// 画九宫格斜线g.drawLine(X3*SIZE,Y,X5*SIZE,Y2*SIZE);g.drawLine(X5*SIZE,Y,X3*SIZE,Y2*SIZE);g.drawLine(X3*SIZE,Y9*SIZE,X5*SIZE,Y7*SIZE);g.drawLine(X5*SIZE,Y9*SIZE,X3*SIZE,Y7*SIZE);// 写“汉界”正Stringtext汉 界;FontfontnewFont(篆体,Font.BOLD,30);g.setFont(font);g.drawString(text,90,265);// 写“楚河”倒Stringtext2楚 河;Fontfont2newFont(篆体,Font.BOLD,-30);g.setFont(font2);g.drawString(text2,330,245);}}现在窗口的绘图逻辑被“固化”在paint中无论怎么刷新棋盘都会稳稳地显示出来。五、主程序启动类修改GoBangUI让它创建MyFrame实例并显示窗口。packagexiang_qi;importjavax.swing.*;importjava.awt.*;publicclassGoBangUI{publicvoidshowUI(){MyFramejfnewMyFrame();// 使用我们自己的 JFrame 子类jf.setTitle(象棋);jf.setSize(450,500);jf.setLocation(500,200);jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);jf.setVisible(true);// 注意这里的 for 循环和 getGraphics() 仅为演示说明实际可删去for(inti0;i100000;i){System.out.println(hello);}// Graphics g jf.getGraphics(); // 此方法画图会消失不推荐使用}publicstaticvoidmain(String[]args){GoBangUIuinewGoBangUI();ui.showUI();}}六、关于for循环你在某些教材或视频中可能会看到这样的代码for(inti0;i100000;i){System.out.println(hello);}Graphicsgjf.getGraphics();// 然后用 g 画图...这个循环有什么用它是用来强行拖延时间的。因为setVisible(true)后窗口的初始化包括绘制并不是立刻完成的主线程会继续向下执行。如果马上调用getGraphics()很可能获取到的画笔是null或者绘图环境未就绪导致画不出来。用这个循环打印 10 万次“hello”让主线程“卡”一会儿等窗口完全显示后再获取画笔就能成功。但是这种做法会产生一些问题。它让程序启动变慢控制台刷出大量无用信息。即使获取到画笔画出来的图还是会在刷新时消失因为没有重写paint。正确的做法就是第 4 节讲的那样永远把绘图代码放在paint方法里既不需要延时循环也不需要手动getGraphics。结束~

相关新闻

释放数GB空间!Windows驱动存储清理终极解决方案

释放数GB空间!Windows驱动存储清理终极解决方案

释放数GB空间!Windows驱动存储清理终极解决方案 【免费下载链接】DriverStoreExplorer Driver Store Explorer 项目地址: https://gitcode.com/gh_mirrors/dr/DriverStoreExplorer 你是否发现Windows系统盘空间总是莫名其妙地减少?即使清理了临时…

2026/9/24 17:00:21 阅读更多 →
车内视角拍摄路面标线褪色数据集4083张VOC+YOLO格式

车内视角拍摄路面标线褪色数据集4083张VOC+YOLO格式

车内视角拍摄路面标线褪色数据集4083张VOCYOLO格式数据集格式:Pascal VOC格式YOLO格式(不包含分割路径的txt文件,仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数):4083 标注数量(xml文件个数):…

2026/9/12 10:58:50 阅读更多 →
水下渔网破洞和拦截鱼草检测数据集2017张VOC+YOLO格式

水下渔网破洞和拦截鱼草检测数据集2017张VOC+YOLO格式

水下渔网破洞和拦截鱼草检测数据集2017张VOCYOLO格式数据集格式:Pascal VOC格式YOLO格式(不包含分割路径的txt文件,仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数):2017 标注数量(xml文件个数)&#xff1…

2026/9/21 2:18:56 阅读更多 →

最新新闻

templ ADR 0001 解析:如何在文本行内书写 `@Component()` 组件表达式

templ ADR 0001 解析:如何在文本行内书写 `@Component()` 组件表达式

开发工具代码生成后端 【免费下载链接】templ A language for writing HTML user interfaces in Go. 项目地址: https://gitcode.com/gh_mirrors/te/templ 点击查看 免费下载 符号在 templ 模板语言中用于调用组件表达式(templ element expression&…

2026/9/24 17:00:11 阅读更多 →
刷题笔记:

刷题笔记:

标准刷题结构:public class Main{ public static void main(String[] args){ } }输入:import java.util.Scanner; public class Main{ public class void main(String[] args){ Scanner sc new Scanner(String.in); } }格式化输出:printf(&…

2026/9/24 17:00:11 阅读更多 →
Jackett 跨平台部署 3 步跑通 BT Tracker 聚合

Jackett 跨平台部署 3 步跑通 BT Tracker 聚合

Jackett 跨平台部署 3 步跑通 BT Tracker 聚合 Jackett 把多个 BT Tracker 的搜索结果统一成 Torznab API,让 Sonarr、Radarr 等客户端免适配直接调用。想在 Windows、macOS、Linux 上部署?这篇教程按场景给最短安装路径,并覆盖启动验证、后…

2026/9/24 17:00:11 阅读更多 →
Quick 共享示例(Shared Examples)与 Behavior:用共享断言消除测试样板代码

Quick 共享示例(Shared Examples)与 Behavior:用共享断言消除测试样板代码

Quick 共享示例(Shared Examples)与 Behavior:用共享断言消除测试样板代码 【免费下载链接】Quick The Swift (and Objective-C) testing framework. 项目地址: https://gitcode.com/gh_mirrors/qu/Quick 在 Swift/Objective-C 测试中…

2026/9/24 17:00:11 阅读更多 →
Humanizer InDate.Nine 全面解析:用 DateOnly 表达 9 天/9 周/9 个月/9 年后的日期

Humanizer InDate.Nine 全面解析:用 DateOnly 表达 9 天/9 周/9 个月/9 年后的日期

开发工具 【免费下载链接】Humanizer Humanizer meets all your .NET needs for manipulating and displaying strings, enums, dates, times, timespans, numbers and quantities 项目地址: https://gitcode.com/gh_mirrors/hu/Humanizer 点击查看 免费下载 导读 …

2026/9/24 17:00:10 阅读更多 →
gsd-core 配置读取修复解析:`config-get --default true` 如何消除 Nyquist 校验开关的 stderr 噪音与空变量回退

gsd-core 配置读取修复解析:`config-get --default true` 如何消除 Nyquist 校验开关的 stderr 噪音与空变量回退

gsd-core 配置读取修复解析:config-get --default true 如何消除 Nyquist 校验开关的 stderr 噪音与空变量回退 【免费下载链接】gsd-core Git. Ship. Done - Core 项目地址: https://gitcode.com/gh_mirrors/ge/gsd-core 本文以 gsd-core 仓库中归档变更集 .…

2026/9/24 16:59:10 阅读更多 →

日新闻

基于YOLOv8的渔船作业监控系统:从环境搭建到边缘部署全流程

基于YOLOv8的渔船作业监控系统:从环境搭建到边缘部署全流程

简介:这是一套面向计算机、人工智能、自动化等专业学生与教师的毕业设计级项目资源,围绕YOLOv8实现渔船作业监控系统,可用于毕设、课程设计、大作业或项目立项演示。压缩包共97个文件,约24.21MB,以70个Python源码文件为…

2026/9/24 0:00:19 阅读更多 →
单细胞注释实战:基于Scanpy的标记基因与参考映射流程解析

单细胞注释实战:基于Scanpy的标记基因与参考映射流程解析

简介:一份基于单细胞RNA测序数据的细胞类型注释算法研究Python毕业设计源码,针对计算机相关专业正在做毕设或需要项目实战的学习者,可用于课程设计与期末大作业。项目代码完整、经导师指导评审通过,可直接运行,覆盖数据…

2026/9/24 0:00:19 阅读更多 →
C#源生成器实战:用增量生成器替代反射,告别AOT崩溃

C#源生成器实战:用增量生成器替代反射,告别AOT崩溃

第一次在项目里被反射卡住,是在一个老旧的WinForms模块里:几十个类依赖PropertyChanged通知,运行时反射读属性、发通知,每次启动慢半拍不说,一上.NET Native/AOT裁剪模式几乎全面崩盘。后来我把这段逻辑全部改成C#源生…

2026/9/24 0:00:19 阅读更多 →

周新闻

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

直接铺开项目本身吧。这几个月我一直在折腾一件事:用Flutter给OpenHarmony做一款游戏集合类的App,说白了就是把若干小游戏塞进一个壳里,用统一入口分发。这个方向本身不算新鲜,真正让我花了不少心思的,是首页那堆游戏卡…

2026/9/24 14:34:13 阅读更多 →
Word表格编号全攻略:从列表编号到题注交叉引用

Word表格编号全攻略:从列表编号到题注交叉引用

写Word文档,最让人头疼的往往是那些“看起来不起眼”的小问题。比如表格编号这事:今天在表后面多加了两个空白行,明天给客户交稿前发现整个章节的编号全部错位,光是挨个改序号就能耗掉大半个下午。我前阵子帮人整理一份上百页的技…

2026/9/24 9:10:42 阅读更多 →
从第一个站到第二个站:独立开发者的静态网站选型与落地实践

从第一个站到第二个站:独立开发者的静态网站选型与落地实践

1. 项目概述1.1 核心需求解析做独立开发者这几年,说实话,第一个网站上线的那天晚上我兴奋得没睡着。但等它跑了半年,流量惨淡、功能臃肿、代码自己都懒得看第二遍之后,我才慢慢琢磨明白一个道理:第一个网站是练手&…

2026/9/24 14:33:56 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/24 12:50:34 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/24 14:33:48 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/24 12:49:17 阅读更多 →