java 绘制长方形_Java入门:绘制简单图形

在上一节,我们学习了如何使用swing和awt工具创建一个空的窗口,本节学习如何绘制简单图形。

基本绘图介绍

Java中绘制基本图形,可以使用Java类库中的Graphics类,此类位于java.awt包中。在我们自己的java程序文件中,要使用Graphics类就需要使用import java.awt.Graphics语句将Graphics类导入进来。

Graphics类提供基本的几何图形绘制方法,主要有:画线段、画矩形、画圆、画带颜色的图形、画椭圆、画圆弧、画多边形等。本项目仅用到画直线的功能,其它图形绘制请自行点击查阅Java API。

Graphics类的drawLine()方法:drawLine(int x1,int y1,int x2,int y2)

此方法的功能是:在此图形上下文的坐标系中,使用当前颜色在点 (x1,y1) 和 (x2,y2)之间画一条线。

这里需要理解几个概念:

1)图形上下文:通俗点讲,就是画图环境。每个窗口构件(如主窗口、按钮等),都有一个自己的图形上下文对象,我们就是使用这个对象来实现在构件上画图。这个对象就是Graphics对象。

2)如何获得图形上下文:我们要在哪个构件上绘图,就调用那个构件的getGraphics()方法即可获得该构件的图形上下文对象,然后使用这个对象绘图。

3)Java坐标系:

Java的坐标原点(0,0)位于屏幕的左上角,坐标度量以象素为单位,水平向右为X轴的正方向,竖直向下为Y轴的正方向,每个坐标点的值表示屏幕上的一个像素点的位置,所有坐标点的值都取整数,如下图所示。

4)当前颜色:指图形上下文当前的颜色。每个图形上下文都有自己当前的颜色。通过Graphics对象的getColor()方法可获取改颜色,setColor()方法可设置颜色。

实践训练:绘制游戏区域

第一步:给DrawSee类添加成员变量,用来描述游戏区域的特征。

对DrawSee类来说,此类主要完成的功能是与用户交互,即显示游戏区域,显示数字,响应用户鼠标点击,显示用户鼠标点击后的结果等。我们现在考虑绘制10行10列游戏区域的问题。先给DrawSee类添加如下四个成员变量:

DrawSee.java文件

importjava.awt.Color;importjava.awt.Container;importjava.awt.Font;importjava.awt.Graphics;importjava.awt.event.MouseAdapter;importjava.awt.event.MouseEvent;importjavax.swing.JFrame;public class DrawSee extendsJFrame {private static final int sx = 50;//游戏区域10*10方块的起始横坐标

private static final int sy = 50;//游戏区域10*10方块的起始纵坐标

private static final int w = 40;//每个小方格的边长

private static final int rw = 400;//游戏区域10*10方块的边长

...

}

之所以把这些成员作为DrawSee类的成员变量,而没有作为某个成员方法的局部变量,这是因为这几个变量所描述的是DrawSee这个窗口的特征,把他们作为类成员变量更符合逻辑。但是,这几个变量只在下面第二步描述的方法中用过,其它方法中并没有使用,所以即使你将这介个变量定义在paintComponent()方法里面,也不会出现错误,程序仍能得到正确结果。

第二步:添加绘制游戏区域的方法(即绘制10行10列的红色网格)

DrawSee.java文件

1 public voidpaintComponents(Graphics g) {2 try{3

4 //设置线条颜色为红色

5 g.setColor(Color.RED);6

7 //绘制外层矩形框

8 g.drawRect(sx, sy, rw, rw);9

10 /*绘制水平10个,垂直10个方格。11 * 即水平方向9条线,垂直方向9条线,12 * 外围四周4条线已经画过了,不需要再画。13 * 同时内部64个方格填写数字。14 */

15 for(int i = 1; i < 10; i ++) {16 //绘制第i条竖直线

17 g.drawLine(sx + (i * w), sy, sx + (i * w), sy +rw);18

19 //绘制第i条水平线

20 g.drawLine(sx, sy + (i * w), sx + rw, sy + (i *w));21

22

23 }24 } catch(Exception e) {25 e.printStackTrace();26 }27 }

为简单起见,我们在DrawSee类的构造方法中直接调用 paintComponents方法,让其绘制10行10列的游戏网格。(重载paint方法,在其中绘制才是合理的选择)这里直接调用paintComponents会看不到绘图结果,需要在调用paintComponents之前插入一段代码,让进程等待500毫秒。代码见第48至61行:

DrawSee.java文件

1 import java.awt.Color;2 import java.awt.Container;3 import java.awt.Font;4 import java.awt.Graphics;5 import java.awt.event.MouseAdapter;6 import java.awt.event.MouseEvent;7

8 import javax.swing.JFrame;9

10

11 /**12 *13 * 程序入口14 *15 */

16 public classTestDrawLine {17 public static voidmain(String[] args) {18 newDrawSee();19 }20 }21

22 classDrawSee extends JFrame {23

24 private static final int sx = 50;//小方格宽度

25 private static final int sy = 50;//小方格高度

26 private static final int w = 40;27 private static final int rw = 400;28

29

30 privateGraphics jg;31

32

33

34 private Color rectColor = new Color(0xf5f5f5);35

36 /**37 * DrawSee构造方法38 */

39 publicDrawSee() {40 Container p =getContentPane();41 setBounds(100, 100, 500, 500);42 setVisible(true);43 p.setBackground(rectColor);44 setLayout(null);45 setResizable(false);46 this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);47

48 try{49

50

51

52 Thread.sleep(500);53 } catch(Exception e) {54 e.printStackTrace();55 }56

57 //获取专门用于在窗口界面上绘图的对象

58 jg = this.getGraphics();59

60 //绘制游戏区域

61 paintComponents(jg);62

63

64 }65

66

67

68 public voidpaintComponents(Graphics g) {69 try{70

71 //设置线条颜色为红色

72 g.setColor(Color.RED);73

74 //绘制外层矩形框

75 g.drawRect(sx, sy, rw, rw);76

77 /*绘制水平10个,垂直10个方格。78 * 即水平方向9条线,垂直方向9条线,79 * 外围四周4条线已经画过了,不需要再画。80 * 同时内部64个方格填写数字。81 */

82 for(int i = 1; i < 10; i ++) {83 //绘制第i条竖直线

84 g.drawLine(sx + (i * w), sy, sx + (i * w), sy +rw);85

86 //绘制第i条水平线

87 g.drawLine(sx, sy + (i * w), sx + rw, sy + (i *w));88

89 //填写第i行从第1个方格到第8个方格里面的数字(方格序号从0开始)

90 for(int j = 0; j < 10; j ++) {91 //drawString(g, j, i);

92 }93 }94 } catch(Exception e) {95 e.printStackTrace();96 }97 }98

99

100 }

现在运行程序,可以看到已经绘制出10行10列的区域了。

注意,在窗口元素上绘制直线、写文字等操作,使用到的是一个叫做Graphics的对象。在构造函数的第58行语句中,this.getGraphics()语句是获取游戏窗口的绘图对象(一个Graphics对象),这里的this是指程序运行后用户看到的那个窗口,getGraphics()方法就是得到绘图对象。获取到这个对象后,被保存到成员变量jg中,这样,在其他成员方法中就可以直接使用这个jg对象来绘图了。

DrawSee类另外几个成员:

setGrid(int cx,int cy,Color color):设置被选中的cx行,cy列网格的背景

compare(int cx,int cy):比较cx行cy列网格和之前选中的网格是否可以消除

drawString(Graphics g, int x, int y):在x行y列网格上写数字

isEnd(int[][] map) :判断二维数组map是不是全0

上叙方法请读者自己分析代码,在分析时,主要抓住两个角度,一个是这个方法的逻辑过程是怎样的,第二个是方法体内用到了哪些语法知识。

下面给出DrawSee类的完整代码:

1 import java.awt.Color;2 import java.awt.Container;3 import java.awt.Font;4 import java.awt.Graphics;5 import java.awt.event.MouseAdapter;6 import java.awt.event.MouseEvent;7

8 import javax.swing.JFrame;9

10

11 /**12 *13 * 程序入口14 *15 */

16 public classTestDrawLine {17 public static voidmain(String[] args) {18 newDrawSee();19 }20 }21

22 classDrawSee extends JFrame {23 private static final long serialVersionUID = 2L;24 private static final int sx = 50;//小方格宽度

25 private static final int sy = 50;//小方格高度

26 private static final int w = 40;27 private static final int rw = 400;28 private int px = 0, py = 0;29

30 privateGraphics jg;31 private int cc = 0;//被选中的方格个数

32 private int[][] map;//存放游戏数据的二维数组

33 private boolean isEnd = false;34 private Color rectColor = new Color(0xf5f5f5);35

36 /**37 * DrawSee构造方法38 */

39 publicDrawSee() {40 Container p =getContentPane();41 setBounds(100, 100, 500, 500);42 setVisible(true);43 p.setBackground(rectColor);44 setLayout(null);45 setResizable(false);46 this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);47

48 try{49 //创建游戏数据地图

50 map =SeeAgain.createMap();51

52 Thread.sleep(500);53 } catch(Exception e) {54 e.printStackTrace();55 }56

57 //获取专门用于在窗口界面上绘图的对象

58 jg = this.getGraphics();59

60 //绘制游戏区域

61 paintComponents(jg);62

63

64 //添加鼠监听事件,当鼠标点击时触发

65 this.addMouseListener(newMouseAdapter() {66

67 //定义鼠标点击事件响应过程

68 @Override69 public voidmouseClicked(MouseEvent e) {70 //如果游戏结束,返回,不执行后面的代码

71 if(isEnd) {72 return;73 }74

75 //获取鼠标点击的那一点的x,y坐标

76 int x = e.getX(), y =e.getY();77

78 /**79 * 计算当前点击的方格是第几个80 * cx:当前点击的方格处于水平方向第几个81 * cy: 当前点击的方格处于竖直方向第几个82 */

83 int cx = (x - sx) / w, cy = (y - sy) /w;84

85 /**86 * 如果点击的方格处于游戏区域之外,87 * 直接返回,不执行后面的代码88 */

89 if(cx < 1 || cy < 1 || cx > 8 || cy > 8) {90 return;91 }92

93 //被选中的方格个数增加一个

94 cc ++;95

96 compare(cx,cy);97

98 }99 });100

101 }102

103 /**104 * 判断二维数组map中的所有元素是否均为0,105 * 只要有一个不为0,返回false,表示游戏还没结束;否则返回true表示游戏结束106 * @param map 二维数组,元素为int类型107 * @return108 */

109 public boolean isEnd(int[][] map) {110 for(int[] ms : map) {111 for(intm : ms) {112 if(m != 0) {113 return false;114 }115 }116 }117 return true;118 }119

120

121 public voidpaintComponents(Graphics g) {122 try{123

124 //设置线条颜色为红色

125 g.setColor(Color.RED);126

127 //绘制外层矩形框

128 g.drawRect(sx, sy, rw, rw);129

130 /*绘制水平10个,垂直10个方格。131 * 即水平方向9条线,垂直方向9条线,132 * 外围四周4条线已经画过了,不需要再画。133 * 同时内部64个方格填写数字。134 */

135 for(int i = 1; i < 10; i ++) {136 //绘制第i条竖直线

137 g.drawLine(sx + (i * w), sy, sx + (i * w), sy +rw);138

139 //绘制第i条水平线

140 g.drawLine(sx, sy + (i * w), sx + rw, sy + (i *w));141

142 //填写第i行从第1个方格到第8个方格里面的数字(方格序号从0开始)

143 for(int j = 0; j < 10; j ++) {144 drawString(g, j, i);145 }146 }147 } catch(Exception e) {148 e.printStackTrace();149 }150 }151

152 private void drawString(Graphics g, int x, inty) {153 //为0就不显示

154 if(map[x][y] != 0) {155 g.setColor(Color.RED);//Graphics对象颜色在之前又被修改过,所以每次需要将颜色重新设置为红色

156 g.setFont(new Font("Arial", 0, 40));//设置Graphics对象字体大小

157 g.drawString(map[x][y] + "", sx + (y * w) + 5, sy + ((x + 1) * w) - 5);//绘制字符

158 }159 }160

161 /***162 * 讲制定小方格设置为指定背景颜色163 * @param cx 方格的水平方向序号164 * @param cy 方格的垂直方向序号165 * @param color166 */

167 private void setGrid(int cx,intcy,Color color){168 //将绘图对象设置为灰色,后面会将所点击的方格背景设置为此颜色

169 jg.setColor(color);170

171 /**172 * 将所点击的方格上绘制一个小一点的矩形,矩形背景颜色为color,173 * 绘制的这个Rect会导致该方格上原有的文字被覆盖174 */

175 jg.fillRect(sx + (cx * w) + 1, sy + (cy * w) + 1, w - 2, w - 2);176

177 //将覆盖的数字重新写出来,这样就又看到红色的文字了。

178 drawString(jg, cy, cx);179 }180

181 private void compare(int cx,intcy){182 /**183 * 如果cc是1,表示当前一共选中了一个方格,用px,py来记住这个方格的位置;184 * 否则,表示现在选中的这个方格要与之前选中的方案比较,决定是否要删除185 */

186 if(cc == 1) {187 px =cx;188 py =cy;189

190 //将所点击的方格背景设置为灰色

191 setGrid(cx,cy,Color.LIGHT_GRAY);192 }193 else{//此时,cc肯定是大于1的,表示要比较两个方格的值是否相同

194 SeeAgain.removed(map, py, px, cy, cx );//让SeeAgain类的remove方法去判断上一次所选195 //的(px,py)处的方格值与本次选择的(cx,cy)处的方格值是否可以消掉196

197 //处理第一个方格

198 setGrid(cx,cy,rectColor);199

200 //处理第二个方格

201 setGrid(px,py,rectColor);202

203 cc = 0;//将cc的值复位

204 }205

206 //判断是否结束游戏

207 isEnd =isEnd(map);208 if(isEnd) {209 jg.setColor(Color.RED);210 jg.setFont(new Font("Arial", 0, 62));211 jg.drawString("Game Over!", 100, 220);212 }213 }214 }

上述代码第65行至第99行,是添加窗口的鼠标点击事件,鼠标每次点击一下小方格,就要判断所点击的放个是否要被消掉。

至此,本项目任务绘图部分的知识点就介绍到这里。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/488609.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

web面试常见问题补充

jquery Ajax $ajax({ Url:”test.html”,-----发送请求的地址 Async:true;------异步操作 Cache:true,-----可以从缓冲中加载 Type:”GET”,------请求方法 Datatype:”json”,-------服务器返回数据类型 Sucess:function(data){ ----------调用成功语句 If(data”OK”){ Conso…

如何与病毒搏斗?这部BBC“史诗级大片”告诉你答案

来源&#xff1a;惠在湖北 我们知道&#xff0c;在目前没有特效药和疫苗的情况下&#xff0c;被治愈的新型冠状病毒肺炎患者&#xff0c;离不开医学的帮助&#xff0c;而治愈的关键&#xff0c;依靠的是人体自身的免疫力。病毒是如何入侵的&#xff1f;免疫力从何而来&#xff…

单系统 台电x80pro_台电X80 Pro (E6E9)-双系统安装文件平板固件

这是台电X80 Pro (E6E9)-双系统安装文件平板固件&#xff0c;台电X80 Pro (E6E9)出来已经有一段时间了 相信大家都体验到了新机的强大了吧可使用时难免会发生一些意外 比如账户锁密码忘记 手机中毒 使用卡顿 不开机或者开机定屏 无故黑屏等 那怎么解决呢 今天就带大家一起来了解…

Ranklib源码剖析--LambdaMart

Ranklib是一套优秀的Learning to Rank领域的开源实现&#xff0c;其中有实现了MART&#xff0c;RankNet&#xff0c;RankBoost&#xff0c;LambdaMart&#xff0c;Random Forest等模型。其中由微软发布的LambdaMART是IR业内常用的Learning to Rank模型&#xff0c;本文主要介绍…

gentoo linux 分区_小白安装Gentoo Linux操作系统——磁盘分区

磁盘分区规划在日常安装Gentoo Linux操作系统前需要对系统使用的磁盘分区进行规划&#xff0c;规划原则需考虑磁盘容量、系统规模与用途。现阶段个人PC的磁盘容量已近乎TB级别&#xff0c;磁盘容量已不再成为系统安装的约束&#xff0c;那么对系统规模与用途的考虑则是安装Gent…

markdown 行内公式_使用Markdown快速编辑公众号技巧之mdnice

请使用 Chrome 浏览器。请阅读下方文本熟悉工具使用方法&#xff0c;本文可直接拷贝到微信中预览。1 Markdown Nice 简介支持自定义样式的 Markdown 编辑器支持微信公众号、知乎和稀土掘金欢迎扫码回复「排版」加入用户群2 主题https://preview.mdnice.com/themes/欢迎提交主题…

AI人必看!89页全网最全清华知识图谱报告(附PDF)

来源&#xff1a;智东西知识图谱&#xff08;Knowledge Graph&#xff09;是人工智能的重要分支技术&#xff0c;它在2012年由谷歌提出&#xff0c;成为建立大规模知识的杀手锏应用&#xff0c;在搜索、自然语言处理、智能助手、电子商务等领域发挥着重要作用。知识图谱与大数据…

mui.init方法配置

mui框架将很多功能配置都集中在mui.init方法中&#xff0c;要使用某项功能&#xff0c;只需要在mui.init方法中完成对应参数配置即可&#xff0c;目前支持在mui.init方法中配置的功能包括&#xff1a; 创建子页面、 关闭页面、 手势事件配置、 预加载、 下拉刷新、上拉加载、 设…

python wx模块下choice列表框值怎么更新_wx python

一、静态文本控件wx.StaticText(parent, id, label, poswx.DefaultPosition, sizewx.DefaultSize, style0, name"staticText")wx.StaticText构造函数的参数parent&#xff1a;父窗口部件。id&#xff1a;标识符。使用-1可以自动创建一个唯一的标识。label&#xf…

AI战“疫”!人工智能在疫情中的重要作用

来源&#xff1a;腾讯新闻网新冠肺炎疫情牵动着全国人民的心&#xff01;在防控疫情部署落实工作中&#xff0c;上海着力将人工智能等现代信息技术深入应用于疫情态势研判、传播路径分析、精准防控、有效治疗及后续治理等各工作环节。通过提供更加精准有效的科学决策依据&#…

linux 判断指针是否可读_Linux进程间通信——消息队列

概念什么是消息队列&#xff1f;消息队列亦称报文队列&#xff0c;也叫做信箱。是Linux的一种通信机制&#xff0c;这种通信机制传递的数据具有某种结构&#xff0c;而不是简单的字节流。消息队列的本质其实是一个内核提供的链表&#xff0c;内核基于这个链表&#xff0c;实现了…

【人工智能】中科院2019全球人工智能发展白皮书!八大关键技术中国崛起中,国产AI芯片耀眼...

来源&#xff1a;产业智能官人工智能是一个很宽泛的概念&#xff0c;概括而言是对人的意识和思维过程的模拟&#xff0c;利用机器学习和数据分析方法赋予机器类人的能力。人工智能将提升社会劳动生产率&#xff0c;特别是在有效降低劳动成本、优化产品和服务、创造新市场和就业…

斜度符号标注_几何作图之斜度和锥度

虽然机件的形状各有不同&#xff0c;但它们的图样基本上都是由直线、圆弧和其它一些曲线所组成的几何形体。因此在绘图时&#xff0c;常常要运用一些几何作图方法。斜度和锥度1&#xff0e;斜度(GB/T 4458.4-2003)斜度是指一直线(或平面)对另一条直线(或平面)的倾斜程度&#x…

shiro 手动创建session_Shiro 和 spring boot 的集成

1 添加依赖使用 shiro-spring-boot-web-starter 在 spring boot 中集成 shiro 只需要再添加一个依赖<dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-spring-boot-web-starter</artifactId><version>1.4.1</version…

动态规划 所有题型的总结

1 动态规划 1.1 定义 动态规划的核心是状态和状态转移方程。 在记忆化搜索中&#xff0c;可以为正在处理的表项声明一个引用&#xff0c;简化对它的读写操作&#xff1b; 动态规划解决的是多阶段决策问题&#xff1b; 初始状态→│决策&#xff11;│→│决策&#xff12;│→……

mysql事务嵌套 php_使用以下代码,MySQL中的PHP“嵌套”事务是否...

好的,我正在寻找使用PHP在MySQL中进行“嵌套”事务的解决方案,并且正如您在MySQL文档中所知的那样,不可能在事务内进行事务(Mysql transactions within transactions).我试图使用http://php.net/manual/en/pdo.begintransaction.php中建议的Database类,但不幸的是,这对我来说是…

美智库:马赛克战是人工智能与自主系统支撑的决策中心战

来源&#xff1a;国防科技要闻编者按2020年2月11日&#xff0c;美战略与预算评估中心发布报告《马赛克战&#xff1a;利用人工智能和自主系统实施决策中心战》。针对大国战略竞争&#xff0c;报告建议美国防部摒弃当前以消耗战为中心的理念&#xff0c;采用决策中心战。报告分析…

echarts山东地图_用 Python 绘制个人足迹地图

前两年&#xff0c;足迹地图小程序风靡朋友圈&#xff0c;一时间大家都流行晒自己的旅行地图。但是&#xff0c;笔者最近体验了好几款足迹地图的小程序&#xff0c;发现这些小程序虽然号称是足迹地图&#xff0c;但最多只是展示到省级别&#xff0c;无法精确到市级别&#xff0…

VC/VS开发问题集锦

&#xff08;1&#xff09;如何在一个CString的字符串中,以","为分割点,提取子字符串 CString a"322,787,123";int na.Find(","); //查找第一个","的位置ba.left(n); //将","左边的值取出给bint lengtha.…

AI 芯片发展的前世今生

来源&#xff1a;《微纳电子与智能制造》期刊作者&#xff1a;任 源、潘 俊、刘京京、何燕冬、何 进现代电子产品和设备在诸如通信 、娱乐 、安全和医疗保健等许多方面改善了我们的生活质量 &#xff0c;这主要是因为现代微电子技术的发展极大地改变了人们的日常工作和互动方式…