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坐标系:
![](/assets/blank.gif)
实践训练:绘制游戏区域
import java.awt.Color; import java.awt.Container; import java.awt.Font; import java.awt.Graphics; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent;import javax.swing.JFrame;public class DrawSee extends JFrame {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()方法里面,也不会出现错误,程序仍能得到正确结果。
1 public void paintComponents(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 class TestDrawLine { 17 public static void main(String[] args) { 18 new DrawSee(); 19 } 20 } 21 22 class DrawSee 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 private Graphics jg; 31 32 33 34 private Color rectColor = new Color(0xf5f5f5); 35 36 /** 37 * DrawSee构造方法 38 */ 39 public DrawSee() { 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 void paintComponents(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 class TestDrawLine { 17 public static void main(String[] args) { 18 new DrawSee(); 19 } 20 } 21 22 class DrawSee 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 private Graphics 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 public DrawSee() { 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(new MouseAdapter() { 66 67 // 定义鼠标点击事件响应过程 68 @Override 69 public void mouseClicked(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 * @return 108 */ 109 public boolean isEnd(int[][] map) { 110 for(int[] ms : map) { 111 for(int m : ms) { 112 if(m != 0) { 113 return false; 114 } 115 } 116 } 117 return true; 118 } 119 120 121 public void paintComponents(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, int y) { 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 color 166 */ 167 private void setGrid(int cx,int cy,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,int cy){ 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行,是添加窗口的鼠标点击事件,鼠标每次点击一下小方格,就要判断所点击的放个是否要被消掉。
至此,本项目任务绘图部分的知识点就介绍到这里。
转载于:https://www.cnblogs.com/bayes/p/5505640.html
Java入门:绘制简单图形相关推荐
- java 绘制长方形_Java入门:绘制简单图形
在上一节,我们学习了如何使用swing和awt工具创建一个空的窗口,本节学习如何绘制简单图形. 基本绘图介绍 Java中绘制基本图形,可以使用Java类库中的Graphics类,此类位于java.aw ...
- python的turtle怎么画曲线_利用 turtle库绘制简单图形
turtle库是python的基础绘图库,这个库被介绍为一个最常用的用来介绍编程知识的方法库,其主要是用于程序设计入门,是标准库之一,利用turtle可以制作很多复杂的绘图. turtle名称含义为& ...
- [Qt教程] 第11篇 2D绘图(一)绘制简单图形
[Qt教程] 第11篇 2D绘图(一)绘制简单图形 楼主 发表于 2013-4-23 12:52:35 | 查看: 1398| 回复: 5 绘制简单图形 版权声明 该文章原创于Qter开源社区,作者 ...
- Android openGl开发详解(一)——绘制简单图形
1. What? openGl是什么?openGl ES又是什么? 2. How? Android中的openGL 如何使用? 3. GlSurfaceView是什么? GLSurfaceView的作 ...
- Python使用turtle绘制简单图形-设置绝对坐标setpos(), 抬起画笔penup(),放下画笔pendown()
[小白从小学Python.C.Java] [Python-计算机等级考试二级] [Python-数据分析] Python使用turtle绘制简单图形 [太阳]选择题 以下Python代码中的penup ...
- python opencv 绘制简单图形
09-python opencv 绘制简单图形 09-python opencv 绘制简单图形 概述 实现过程 引用与创建空图 绘制直线 绘制矩形 绘制圆 绘制椭圆 添加文字 显示图像 源代码 运行结 ...
- Python之Turtle库绘制简单图形
Python之Turtle库绘制简单图形 来绘制正方形.三角形.五边形.五角形 import turtle #引入turtle库pen=turtle.Turtle() #创建turtle类型的画笔 # ...
- plotly绘制简单图形4--饼形图
plotly绘制简单图形<1>--散点图折线图 plotly绘制简单图形<2>--条形图 plotly绘制简单图形<3>--设置按钮 本次说一下饼形图: 目录 1. ...
- plotly绘制简单图形5--饼形图附加
plotly绘制简单图形<4>--饼形图里说了饼形图的基本设置, 这里补充一个怎样设置两个饼图的方法(数据是爬取京东手机和电脑价格数据分析结果) import plotly.plotly ...
最新文章
- 2021新兴经济体大学排名发布,129所中国高校上榜!
- 【UGV】小车一些图片 麦轮版小车
- Gstreamer中一些gst-launch常用命令
- MariaDB exists 学习
- VTK:相互作用之TrackballCamera
- mybatis实战教程(mybatis in action),mybatis入门到精通(转)
- 女孩子们,你的专业由你做主
- Node.js 指南(入门指南)
- ESXi配置vCenter服务器
- Guava学习笔记(五):简化异常处理的Throwables类
- Mysql 查询列名
- PAIP.在程序中设置壁纸墙纸
- 安装linux出现分区出错,找到了linux分区顺序错乱修复方法
- VMware系列序列号
- 支持I2S数字音频接口;音频功放芯片NTP8835C
- 共享编辑文档系统dzzoffice安装
- java基础—综合练习
- 物联网之散射通信应用
- cisco路由器忘记密码恢复
- str.count 统计
热门文章
- rgb hsv php,如何将RGB颜色更改为HSV?
- android内存问题查看工具,哪些Android工具和方法最适合查找内存/资源泄漏?
- 华硕fl5600l拆机电池_华硕fl8000拆机图解
- 获取任意微信公众号二维码方法
- 连连看逆向分析与外挂编写
- [前端] 网易云音乐外链播放器不能正常显示的问题之解决方案
- Java架构师学习小目标
- 文件下载或者预览(download)
- 尤克里里ukulele最全选购攻略,高性价比尤克里里初学者推荐,新手告别选择困难
- pythonopencv测距_如何在opencv中测量两点之间的距离(像素到厘米)