java 图形化小工具Abstract Window Toolit :画笔Graphics,画布Canvas(),弹球小游戏
画笔Graphics
Java中提供了Graphics类,他是一个抽象的画笔,可以在Canvas组件(画布)上绘制丰富多彩的几何图和位图。
Graphics常用的画图方法如下:
- drawLine(): 绘制直线
- drawString(): 绘制字符串
- drawRect(): 绘制矩形
- drawRoundRect(): 绘制带圆角的矩形
- drawOval():绘制椭圆形
- drawPolygon():绘制多边形边框
- drawArc():绘制一段圆弧(可能是椭圆的圆弧)
- drawPolyline():绘制折线
- fillRect():填充一个矩形区域
- fillRoundRect():填充一个圆角矩形区域
- fillOval():填充椭圆形
- fillPolygon():填充多边形边框
- fillArc():填充一段圆弧(可能是椭圆的圆弧)
- drawImage():绘制位图
AWT专门提供了一个Canvas类作为绘图的画布,程序可以通过创建Canvas的子类,并重写它的paint()方法来实现绘图。
测试代码:
- Canvas()画布类 paint方法画图,方法中传入画笔形参
- Canvas()画布类 setSize(250,250);方法设置画布大小
- Canvas()画布类 repaint(); //清除后重新绘制
- Graphics().setColor方法设置画笔颜色,画笔执行画图动作(红色值,绿色值,蓝色值) 红绿蓝三色取值范围0-255 组合起来可以组成人类可见的任何颜色
import java.awt.*;
import java.awt.event.*;
import java.util.Random;
import java.util.concurrent.atomic.AtomicReference;/*** @ClassName DrawSimple* @projectName: object1* @author: Zhangmingda* @description: XXX* date: 2021/5/7.*/
public class DrawSimple {public static void main(String[] args) {//窗口Frame frame = new Frame("简单画图示例");//窗口关闭按钮动作WindowListener closeListener = new WindowAdapter() {@Overridepublic void windowClosing(WindowEvent e) {System.out.println("窗口关闭");System.exit(0);}};frame.addWindowListener(closeListener);//绘制图形形状变量AtomicReference<String> shape = new AtomicReference<>();//画布Canvas canvas = new Canvas(){Random random = new Random();@Overridepublic void paint(Graphics g) { //g为画笔System.out.println("画图中");if (shape.get() != null){switch (shape.get()){case "rect"://设置画笔颜色Color(红色值,绿色值,蓝色值) 红绿蓝三色取值范围0-255 组合起来可以组成人类可见的任何颜色g.setColor(new Color(255,0,0));//画矩形,x,y分别为起始位置,后面两个参数为宽,高 Random.nextInt(200) 为伪随机数g.drawRect(20,20,random.nextInt(200),random.nextInt(200));break;case "oval"://画椭圆g.setColor(new Color(10,100,30));g.drawOval(40,20,random.nextInt(200),random.nextInt(200));}}}};canvas.setSize(250,250);frame.add(canvas);//容器Panel panel = new Panel();//按钮Button drawRectBtn = new Button("画矩形");Button drawOvalBtn = new Button("画椭圆");//按钮绑定事件drawRectBtn.addActionListener(e ->{shape.set("rect");canvas.repaint(); //清除后重新绘制});drawOvalBtn.addActionListener(e ->{shape.set("oval");canvas.repaint(); //清除后重新绘制});panel.add(drawOvalBtn);panel.add(drawRectBtn);frame.add(panel,BorderLayout.SOUTH);//窗口自动调整大小frame.setLocation(400,300);frame.pack();frame.setVisible(true);}
}

开发弹球小游戏
开发思路:动画,就是间隔一定的时间(通常小于1秒)重新绘制新的图像,两次绘制的图像之间差异较小,肉眼看起来就成了所谓的动画。这个程序我们要借助Swing包的一个Timer类。
Timer(int delay, ActionListener listener): 每间隔delay秒,系统自动出发ActionListener监听器里的事件处理器(actionPerformed方法)
知识点:
- KeyListener 实现监听键盘按键 触发移动球拍
- 画图逻辑:球到了画布的X轴左右端,向相反方向移动位置,到了Y轴顶端位置0,或者到了球拍接触区域向相反方向移动位置
- Timer定时器,每隔毫秒级别重新画图
- 用到的变量全部定义为类变量

示例代码:
import com.sun.source.tree.NewClassTree;import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.Random;/*** @ClassName Pinball* @projectName: object1* @author: Zhangmingda* @description: XXX* date: 2021/5/7.*/
public class Pinball {//定义球拍初始位置用随机对象private Random random = new Random();/*** 设置画布大小:宽高*/private int canvaWidth = 300;private int canvaHeight = 400;/*** 球拍初始参数*///拍子大小位置private int rectX = random.nextInt(200); //拍子所在横坐标位置,要在画布范围之内,private int rectY = 355; //拍子所在Y轴坐标位置小于400,和底部留一定空隙private int rectWidth = 60; //宽度60private int rectHeight = 15; //厚度//拍子按下按键拍子移动的像素大小(步伐)int pace =10;/*** 小球的尺寸位置初始参数*/private int ballSize =15;private int ballX = random.nextInt(200);private int ballY = random.nextInt(100);/*** 小球运动速度值*/private int ballYSpeed = 5; //Y 轴移动速度private double xyRate = random.nextDouble() - 0.5; //X轴相对比Y轴运动速度的比率,返回一个-0.5 ~0.5之间的数,移动方向为向左或者向右private int ballXSpeed = (int) (ballYSpeed * xyRate * 2); // X 轴运动的速度/*** 定时器Timer*/private Timer timer;/*** 游戏是否结束*/private boolean gameOver = false;/*** 方法*/public void play(){/*** 定义窗口,设置位置和关闭动作*/Frame frame = new Frame("弹球小游戏");frame.setLocation(400,300);frame.addWindowListener(new WindowAdapter() {@Overridepublic void windowClosing(WindowEvent e) {System.out.println("关闭游戏");System.exit(0);}});/*** 定义画布*/Canvas canvas = new Canvas(){@Overridepublic void paint(Graphics g) {//如果没有结束if (!gameOver){//画球g.setColor(new Color(30,200,150));g.fillOval(ballX,ballY,ballSize, ballSize);//画下面的矩形拍子g.setColor(new Color(75, 79, 194));g.fillRect(rectX, rectY, rectWidth, rectHeight);}else { //gameOver了g.setColor(Color.RED);g.setFont(new Font("Times",Font.BOLD,30)); // 设置字体格式字体g.drawString("Game Over",70, 200);}}};//设置画布大小canvas.setPreferredSize(new Dimension(canvaWidth,canvaHeight));frame.add(canvas);/*** 游戏核心逻辑:动画效果*/timer = new Timer(50, new ActionListener() {@Overridepublic void actionPerformed(ActionEvent actionEvent) {/*** 如果到了X轴的两端,就向反方向画图*/if (ballX < 0 || ballX >= canvaWidth - ballSize)ballXSpeed = -ballXSpeed;/*** 如果球接触到了球拍的X轴和Y轴区域内,或者跑到顶端(ballY 坐标小于0)就把Y轴反向移动*/if (ballY < 0 || (ballY >= rectY - ballSize && ballY < rectY - ballSize/2) && ballX + ballSize /2 >= rectX && ballX + ballSize /2 <= rectX + rectWidth) {System.out.println("ballX:"+ ballX + "ballY:"+ ballY + "rectX:" + rectX + "rectY:" +rectY);ballYSpeed = -ballYSpeed; //反向速度}else if (ballY >= canvaHeight){ //如果球已经掉到画布之外或者 球拍下 就停止timer循环timer.stop();gameOver = true;}ballX += ballXSpeed;ballY += ballYSpeed;canvas.repaint();}});timer.start();/*** 窗口监听键盘*/KeyListener keyListener = new KeyAdapter() { //添加键盘监听器@Overridepublic void keyPressed(KeyEvent e) { //当键盘被按下时触发
// System.out.println("按下键盘");int KeyCode = e.getKeyCode(); //获取按下的键盘代号switch (KeyCode){case KeyEvent.VK_LEFT://左键按下if(rectX - pace > 0){rectX -= pace;}else {rectX = 0;}break;case KeyEvent.VK_RIGHT://右键按下if (rectX + pace < canvaWidth - rectWidth){rectX += pace;}else {rectX = canvaWidth -rectWidth;}break;}canvas.repaint();}};frame.addKeyListener(keyListener);/*** 窗口大小自动调节到最优,显示窗口*/frame.pack();frame.setVisible(true);}public static void main(String[] args) {new Pinball().play();}
}
相关文章:
java 图形化小工具Abstract Window Toolit :画笔Graphics,画布Canvas(),弹球小游戏
画笔Graphics Java中提供了Graphics类,他是一个抽象的画笔,可以在Canvas组件(画布)上绘制丰富多彩的几何图和位图。 Graphics常用的画图方法如下: drawLine(): 绘制直线drawString(): 绘制字符串drawRect(): 绘制矩形drawRoundRect(): 绘制…...
HCIA-RS实验-STP和RSTP(1)
这篇文章开始前,先简单说下这2个协议; 本文介绍了STP和RSTP的基本原理、优缺点以及应用场景。STP和RSTP都是生成树协议,主要作用于避免网络中的环路,保证数据包能够正常转发。在实际应用中,需要根据实际情况选择合适的…...
Leetcodes刷题之删除链表的倒数N个结点和删除链表的中间的结点
吾心信其可行,则移山填海之难,终有成功之日。 --孙中山 目录 🍉一.删除链表的倒数N个结点 🌻1.双指针 🍁2.求链表的长度 🌸二.删除链表的中间的结点 🍉一.删除链…...
Java-数据结构-并查集<二>
一.并查集的简单介绍 二. 并查集的主要构成和实现方式 三.HashMap模板和数组模板 由于在下文的模板基本一致,不再每次都罗列,大体的模板如下,若有错误可以在leetcode找到对应的题目解答,已经附上连接。 HashMap class UnionFi…...
JSP网上教学资源共享系统(源代码+论文)
通过网上教学资源共享系统的建设,完成了对于操作系统课程的远程化授课。可以使学生不受时间空间的限制,通过网络对于这门课程进行学习。建立起了基于B/C的网络化教学系统。本网站采用当前最流行的JSP网络编程技术,可以实现数据的高效、动态、…...
QT C++入门学习(1) QT Creator安装和使用
Qt官方下载 Qt 官网有一个专门的资源下载网站,所有的开发环境和相关工具都可以从这里下载,具体地址是:http://download.qt.io/ 进入链接后,是一个文件目录,依次进入这个路径:archive/qt/5.12/5.12.9/qt-o…...
UE动画状态机的事件触发顺序测试
正常A状态过渡到B状态的事件顺序: 整个流程为: 调用B状态的On Become Relevant事件调用B状态的On Update事件调用A状态的Left State Event事件调用B状态的Entered State Event事件调用B状态的Start Transition Event事件调用B状态的End Transition Even…...
数学建模的搜索技巧
你真的会使用“度娘”吗?是不是在查找所需要的东西的时候,搜出来的信息价值并不是很大,跟着北海老师学习,如何更高效的使用百度去查询自己想要的,有用的资料! 搜索技巧 完全匹配搜索 : 查询词的外边加上双…...
学成在线笔记+踩坑(10)——课程搜索、课程发布时同步索引库。
导航: 【黑马Java笔记踩坑汇总】JavaSEJavaWebSSMSpringBoot瑞吉外卖SpringCloud黑马旅游谷粒商城学成在线牛客面试题_java黑马笔记 目录 1 【检索模块】需求分析 1.1 全文检索介绍 1.2 业务流程 1.2.1、课程发布时索引库里新增一条记录 1.2.2、课程搜索 2 准…...
某应用虚拟化系统远程代码执行
漏洞简介 微步在线漏洞团队通过“X漏洞奖励计划”获取到瑞友天翼应用虚拟化系统远程代码执行漏洞情报(0day),攻击者可以通过该漏洞执行任意代码,导致系统被攻击与控制。瑞友天翼应用虚拟化系统是基于服务器计算架构的应用虚拟化平台,它将用户…...
solaris-Oracle11g于linux-mysql相连
Oracle11g(solaris64sparc)mysql(linux)实验 此实验目的,实现公司ebs R12 连mysql上的短信平台.预警和提示ebs中信息, 一,环境 主机名 ip 平台 数据库 dbname ebs234 192.168.1.234 …...
大厂齐出海:字节忙种草,网易爱社交
配图来自Canva可画 随着国内移动互联网红利逐渐触顶,互联网市场日趋饱和,国内各互联网企业之间的竞争便愈发激烈起来。在此背景下,广阔的海外市场就成为了腾讯、阿里、字节、京东、拼多多、百度、网易、快手、B站等互联网公司关注和争夺的重…...
几个实用的正则表达式
1到100之间的正整数正则 表达式:^[1-9]\d?$|^100$ 解释: ^表示匹配字符串开始位置 [1-9]表示数字1-9中的任意一个 \d表示任意一个数字 ?表示前面一个字符或子表达式出现0或1次 $表示匹配字符串结束位置 |表示或 最终的解释为:匹配满…...
python实战应用讲解-【numpy数组篇】常用函数(八)(附python示例代码)
目录 Python Numpy MaskedArray.cumprod()函数 Python Numpy MaskedArray.cumsum()函数 Python Numpy MaskedArray.default_fill_value()函数 Python Numpy MaskedArray.flatten()函数 Python Numpy MaskedArray.masked_equal()函数 Python Numpy MaskedArray.cumprod()函…...
Speech and Language Processing-之N-gram语言模型
正如一句老话所说,预测是困难的,尤其是预测未来。但是,如何预测一些看起来容易得多的事情,比如某人接下来要说的几句话后面可能跟着哪个单词。 希望你们大多数人都能总结出一个很可能的词是in,或者可能是over&#x…...
【AI】Python 安装时启用长路径支持
文章目录 场景:解释:关于文件长路径:计算方法: 场景: Python 安装时,会出现 Disable path length limit 的提示。 解释: 在 Windows 操作系统中,文件路径的长度是有限制的。在早期…...
深入理解Go语言中的接口编程【17】
文章目录 接口接口接口类型为什么要使用接口接口的定义实现接口的条件接口类型变量值接收者和指针接收者实现接口的区别值接收者实现接口指针接收者实现接口下面的代码是一个比较好的面试题 类型与接口的关系一个类型实现多个接口多个类型实现同一接口接口嵌套 空接口空接口的定…...
“数字中国·福启海丝”多屏互动光影艺术秀27日在福州举办
作为深化“数字海丝”的核心区、海上丝绸之路的枢纽城市,为喜迎第六届数字中国建设峰会盛大召开之际,福州市人民政府特此举办“数字中国福启海丝”多屏互动光影秀活动。本次光影秀活动是由福建省文化和旅游厅指导,福州市人民政府主办…...
Docker安装mysql8.0文档
第一步需要安装Docker基础环境,具体可以看看这篇 docker基础篇 第二步,拉取mysql8.0的镜像 docker pull mysql:8.0 第三步,镜像启动和文件挂载 复制下面命令执行,33006是对外访问暴露的端口,当然你也可以设置为3306…...
在函数中使用变量
shell脚本编程系列 向函数传递参数 函数可以使用标准的位置变量来表示在命令行中传给函数的任何参数。其中函数名保存在$0变量中,函数参数则依次保存在$1、$2等变量当中,也可以使用特殊变量$#来确定参数的个数 在脚本中调用函数时,必须将参…...
React 第五十五节 Router 中 useAsyncError的使用详解
前言 useAsyncError 是 React Router v6.4 引入的一个钩子,用于处理异步操作(如数据加载)中的错误。下面我将详细解释其用途并提供代码示例。 一、useAsyncError 用途 处理异步错误:捕获在 loader 或 action 中发生的异步错误替…...
DockerHub与私有镜像仓库在容器化中的应用与管理
哈喽,大家好,我是左手python! Docker Hub的应用与管理 Docker Hub的基本概念与使用方法 Docker Hub是Docker官方提供的一个公共镜像仓库,用户可以在其中找到各种操作系统、软件和应用的镜像。开发者可以通过Docker Hub轻松获取所…...
以下是对华为 HarmonyOS NETX 5属性动画(ArkTS)文档的结构化整理,通过层级标题、表格和代码块提升可读性:
一、属性动画概述NETX 作用:实现组件通用属性的渐变过渡效果,提升用户体验。支持属性:width、height、backgroundColor、opacity、scale、rotate、translate等。注意事项: 布局类属性(如宽高)变化时&#…...
基于ASP.NET+ SQL Server实现(Web)医院信息管理系统
医院信息管理系统 1. 课程设计内容 在 visual studio 2017 平台上,开发一个“医院信息管理系统”Web 程序。 2. 课程设计目的 综合运用 c#.net 知识,在 vs 2017 平台上,进行 ASP.NET 应用程序和简易网站的开发;初步熟悉开发一…...
在Ubuntu中设置开机自动运行(sudo)指令的指南
在Ubuntu系统中,有时需要在系统启动时自动执行某些命令,特别是需要 sudo权限的指令。为了实现这一功能,可以使用多种方法,包括编写Systemd服务、配置 rc.local文件或使用 cron任务计划。本文将详细介绍这些方法,并提供…...
微服务商城-商品微服务
数据表 CREATE TABLE product (id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 商品id,cateid smallint(6) UNSIGNED NOT NULL DEFAULT 0 COMMENT 类别Id,name varchar(100) NOT NULL DEFAULT COMMENT 商品名称,subtitle varchar(200) NOT NULL DEFAULT COMMENT 商…...
RNN避坑指南:从数学推导到LSTM/GRU工业级部署实战流程
本文较长,建议点赞收藏,以免遗失。更多AI大模型应用开发学习视频及资料,尽在聚客AI学院。 本文全面剖析RNN核心原理,深入讲解梯度消失/爆炸问题,并通过LSTM/GRU结构实现解决方案,提供时间序列预测和文本生成…...
【C++特殊工具与技术】优化内存分配(一):C++中的内存分配
目录 一、C 内存的基本概念 1.1 内存的物理与逻辑结构 1.2 C 程序的内存区域划分 二、栈内存分配 2.1 栈内存的特点 2.2 栈内存分配示例 三、堆内存分配 3.1 new和delete操作符 4.2 内存泄漏与悬空指针问题 4.3 new和delete的重载 四、智能指针…...
Web中间件--tomcat学习
Web中间件–tomcat Java虚拟机详解 什么是JAVA虚拟机 Java虚拟机是一个抽象的计算机,它可以执行Java字节码。Java虚拟机是Java平台的一部分,Java平台由Java语言、Java API和Java虚拟机组成。Java虚拟机的主要作用是将Java字节码转换为机器代码&#x…...
三分算法与DeepSeek辅助证明是单峰函数
前置 单峰函数有唯一的最大值,最大值左侧的数值严格单调递增,最大值右侧的数值严格单调递减。 单谷函数有唯一的最小值,最小值左侧的数值严格单调递减,最小值右侧的数值严格单调递增。 三分的本质 三分和二分一样都是通过不断缩…...
