java 绘制长方形_Java入门:绘制简单图形
在上一節(jié),我們學(xué)習(xí)了如何使用swing和awt工具創(chuàng)建一個(gè)空的窗口,本節(jié)學(xué)習(xí)如何繪制簡單圖形。
基本繪圖介紹
Java中繪制基本圖形,可以使用Java類庫中的Graphics類,此類位于java.awt包中。在我們自己的java程序文件中,要使用Graphics類就需要使用import java.awt.Graphics語句將Graphics類導(dǎo)入進(jìn)來。
Graphics類提供基本的幾何圖形繪制方法,主要有:畫線段、畫矩形、畫圓、畫帶顏色的圖形、畫橢圓、畫圓弧、畫多邊形等。本項(xiàng)目僅用到畫直線的功能,其它圖形繪制請(qǐng)自行點(diǎn)擊查閱Java API。
Graphics類的drawLine()方法:drawLine(int x1,int y1,int x2,int y2)
此方法的功能是:在此圖形上下文的坐標(biāo)系中,使用當(dāng)前顏色在點(diǎn)?(x1,y1)?和?(x2,y2)之間畫一條線。
這里需要理解幾個(gè)概念:
1)圖形上下文:通俗點(diǎn)講,就是畫圖環(huán)境。每個(gè)窗口構(gòu)件(如主窗口、按鈕等),都有一個(gè)自己的圖形上下文對(duì)象,我們就是使用這個(gè)對(duì)象來實(shí)現(xiàn)在構(gòu)件上畫圖。這個(gè)對(duì)象就是Graphics對(duì)象。
2)如何獲得圖形上下文:我們要在哪個(gè)構(gòu)件上繪圖,就調(diào)用那個(gè)構(gòu)件的getGraphics()方法即可獲得該構(gòu)件的圖形上下文對(duì)象,然后使用這個(gè)對(duì)象繪圖。
3)Java坐標(biāo)系:
Java的坐標(biāo)原點(diǎn)(0,0)位于屏幕的左上角,坐標(biāo)度量以象素為單位,水平向右為X軸的正方向,豎直向下為Y軸的正方向,每個(gè)坐標(biāo)點(diǎn)的值表示屏幕上的一個(gè)像素點(diǎn)的位置,所有坐標(biāo)點(diǎn)的值都取整數(shù),如下圖所示。
4)當(dāng)前顏色:指圖形上下文當(dāng)前的顏色。每個(gè)圖形上下文都有自己當(dāng)前的顏色。通過Graphics對(duì)象的getColor()方法可獲取改顏色,setColor()方法可設(shè)置顏色。
實(shí)踐訓(xùn)練:繪制游戲區(qū)域
第一步:給DrawSee類添加成員變量,用來描述游戲區(qū)域的特征。
對(duì)DrawSee類來說,此類主要完成的功能是與用戶交互,即顯示游戲區(qū)域,顯示數(shù)字,響應(yīng)用戶鼠標(biāo)點(diǎn)擊,顯示用戶鼠標(biāo)點(diǎn)擊后的結(jié)果等。我們現(xiàn)在考慮繪制10行10列游戲區(qū)域的問題。先給DrawSee類添加如下四個(gè)成員變量:
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;//游戲區(qū)域10*10方塊的起始橫坐標(biāo)
private static final int sy = 50;//游戲區(qū)域10*10方塊的起始縱坐標(biāo)
private static final int w = 40;//每個(gè)小方格的邊長
private static final int rw = 400;//游戲區(qū)域10*10方塊的邊長
...
}
之所以把這些成員作為DrawSee類的成員變量,而沒有作為某個(gè)成員方法的局部變量,這是因?yàn)檫@幾個(gè)變量所描述的是DrawSee這個(gè)窗口的特征,把他們作為類成員變量更符合邏輯。但是,這幾個(gè)變量只在下面第二步描述的方法中用過,其它方法中并沒有使用,所以即使你將這介個(gè)變量定義在paintComponent()方法里面,也不會(huì)出現(xiàn)錯(cuò)誤,程序仍能得到正確結(jié)果。
第二步:添加繪制游戲區(qū)域的方法(即繪制10行10列的紅色網(wǎng)格)
DrawSee.java文件
1 public voidpaintComponents(Graphics g) {2 try{3
4 //設(shè)置線條顏色為紅色
5 g.setColor(Color.RED);6
7 //繪制外層矩形框
8 g.drawRect(sx, sy, rw, rw);9
10 /*繪制水平10個(gè),垂直10個(gè)方格。11 * 即水平方向9條線,垂直方向9條線,12 * 外圍四周4條線已經(jīng)畫過了,不需要再畫。13 * 同時(shí)內(nèi)部64個(gè)方格填寫數(shù)字。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 }
為簡單起見,我們?cè)贒rawSee類的構(gòu)造方法中直接調(diào)用?paintComponents方法,讓其繪制10行10列的游戲網(wǎng)格。(重載paint方法,在其中繪制才是合理的選擇)這里直接調(diào)用paintComponents會(huì)看不到繪圖結(jié)果,需要在調(diào)用paintComponents之前插入一段代碼,讓進(jìn)程等待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構(gòu)造方法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 //獲取專門用于在窗口界面上繪圖的對(duì)象
58 jg = this.getGraphics();59
60 //繪制游戲區(qū)域
61 paintComponents(jg);62
63
64 }65
66
67
68 public voidpaintComponents(Graphics g) {69 try{70
71 //設(shè)置線條顏色為紅色
72 g.setColor(Color.RED);73
74 //繪制外層矩形框
75 g.drawRect(sx, sy, rw, rw);76
77 /*繪制水平10個(gè),垂直10個(gè)方格。78 * 即水平方向9條線,垂直方向9條線,79 * 外圍四周4條線已經(jīng)畫過了,不需要再畫。80 * 同時(shí)內(nèi)部64個(gè)方格填寫數(shù)字。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個(gè)方格到第8個(gè)方格里面的數(shù)字(方格序號(hào)從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 }
現(xiàn)在運(yùn)行程序,可以看到已經(jīng)繪制出10行10列的區(qū)域了。
注意,在窗口元素上繪制直線、寫文字等操作,使用到的是一個(gè)叫做Graphics的對(duì)象。在構(gòu)造函數(shù)的第58行語句中,this.getGraphics()語句是獲取游戲窗口的繪圖對(duì)象(一個(gè)Graphics對(duì)象),這里的this是指程序運(yùn)行后用戶看到的那個(gè)窗口,getGraphics()方法就是得到繪圖對(duì)象。獲取到這個(gè)對(duì)象后,被保存到成員變量jg中,這樣,在其他成員方法中就可以直接使用這個(gè)jg對(duì)象來繪圖了。
DrawSee類另外幾個(gè)成員:
setGrid(int cx,int cy,Color color):設(shè)置被選中的cx行,cy列網(wǎng)格的背景
compare(int cx,int cy):比較cx行cy列網(wǎng)格和之前選中的網(wǎng)格是否可以消除
drawString(Graphics g, int x, int y):在x行y列網(wǎng)格上寫數(shù)字
isEnd(int[][] map) :判斷二維數(shù)組map是不是全0
上敘方法請(qǐng)讀者自己分析代碼,在分析時(shí),主要抓住兩個(gè)角度,一個(gè)是這個(gè)方法的邏輯過程是怎樣的,第二個(gè)是方法體內(nèi)用到了哪些語法知識(shí)。
下面給出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;//被選中的方格個(gè)數(shù)
32 private int[][] map;//存放游戲數(shù)據(jù)的二維數(shù)組
33 private boolean isEnd = false;34 private Color rectColor = new Color(0xf5f5f5);35
36 /**37 * DrawSee構(gòu)造方法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 //創(chuàng)建游戲數(shù)據(jù)地圖
50 map =SeeAgain.createMap();51
52 Thread.sleep(500);53 } catch(Exception e) {54 e.printStackTrace();55 }56
57 //獲取專門用于在窗口界面上繪圖的對(duì)象
58 jg = this.getGraphics();59
60 //繪制游戲區(qū)域
61 paintComponents(jg);62
63
64 //添加鼠監(jiān)聽事件,當(dāng)鼠標(biāo)點(diǎn)擊時(shí)觸發(fā)
65 this.addMouseListener(newMouseAdapter() {66
67 //定義鼠標(biāo)點(diǎn)擊事件響應(yīng)過程
68 @Override69 public voidmouseClicked(MouseEvent e) {70 //如果游戲結(jié)束,返回,不執(zhí)行后面的代碼
71 if(isEnd) {72 return;73 }74
75 //獲取鼠標(biāo)點(diǎn)擊的那一點(diǎn)的x,y坐標(biāo)
76 int x = e.getX(), y =e.getY();77
78 /**79 * 計(jì)算當(dāng)前點(diǎn)擊的方格是第幾個(gè)80 * cx:當(dāng)前點(diǎn)擊的方格處于水平方向第幾個(gè)81 * cy: 當(dāng)前點(diǎn)擊的方格處于豎直方向第幾個(gè)82 */
83 int cx = (x - sx) / w, cy = (y - sy) /w;84
85 /**86 * 如果點(diǎn)擊的方格處于游戲區(qū)域之外,87 * 直接返回,不執(zhí)行后面的代碼88 */
89 if(cx < 1 || cy < 1 || cx > 8 || cy > 8) {90 return;91 }92
93 //被選中的方格個(gè)數(shù)增加一個(gè)
94 cc ++;95
96 compare(cx,cy);97
98 }99 });100
101 }102
103 /**104 * 判斷二維數(shù)組map中的所有元素是否均為0,105 * 只要有一個(gè)不為0,返回false,表示游戲還沒結(jié)束;否則返回true表示游戲結(jié)束106 * @param map 二維數(shù)組,元素為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 //設(shè)置線條顏色為紅色
125 g.setColor(Color.RED);126
127 //繪制外層矩形框
128 g.drawRect(sx, sy, rw, rw);129
130 /*繪制水平10個(gè),垂直10個(gè)方格。131 * 即水平方向9條線,垂直方向9條線,132 * 外圍四周4條線已經(jīng)畫過了,不需要再畫。133 * 同時(shí)內(nèi)部64個(gè)方格填寫數(shù)字。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個(gè)方格到第8個(gè)方格里面的數(shù)字(方格序號(hào)從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對(duì)象顏色在之前又被修改過,所以每次需要將顏色重新設(shè)置為紅色
156 g.setFont(new Font("Arial", 0, 40));//設(shè)置Graphics對(duì)象字體大小
157 g.drawString(map[x][y] + "", sx + (y * w) + 5, sy + ((x + 1) * w) - 5);//繪制字符
158 }159 }160
161 /***162 * 講制定小方格設(shè)置為指定背景顏色163 * @param cx 方格的水平方向序號(hào)164 * @param cy 方格的垂直方向序號(hào)165 * @param color166 */
167 private void setGrid(int cx,intcy,Color color){168 //將繪圖對(duì)象設(shè)置為灰色,后面會(huì)將所點(diǎn)擊的方格背景設(shè)置為此顏色
169 jg.setColor(color);170
171 /**172 * 將所點(diǎn)擊的方格上繪制一個(gè)小一點(diǎn)的矩形,矩形背景顏色為color,173 * 繪制的這個(gè)Rect會(huì)導(dǎo)致該方格上原有的文字被覆蓋174 */
175 jg.fillRect(sx + (cx * w) + 1, sy + (cy * w) + 1, w - 2, w - 2);176
177 //將覆蓋的數(shù)字重新寫出來,這樣就又看到紅色的文字了。
178 drawString(jg, cy, cx);179 }180
181 private void compare(int cx,intcy){182 /**183 * 如果cc是1,表示當(dāng)前一共選中了一個(gè)方格,用px,py來記住這個(gè)方格的位置;184 * 否則,表示現(xiàn)在選中的這個(gè)方格要與之前選中的方案比較,決定是否要?jiǎng)h除185 */
186 if(cc == 1) {187 px =cx;188 py =cy;189
190 //將所點(diǎn)擊的方格背景設(shè)置為灰色
191 setGrid(cx,cy,Color.LIGHT_GRAY);192 }193 else{//此時(shí),cc肯定是大于1的,表示要比較兩個(gè)方格的值是否相同
194 SeeAgain.removed(map, py, px, cy, cx );//讓SeeAgain類的remove方法去判斷上一次所選195 //的(px,py)處的方格值與本次選擇的(cx,cy)處的方格值是否可以消掉196
197 //處理第一個(gè)方格
198 setGrid(cx,cy,rectColor);199
200 //處理第二個(gè)方格
201 setGrid(px,py,rectColor);202
203 cc = 0;//將cc的值復(fù)位
204 }205
206 //判斷是否結(jié)束游戲
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行,是添加窗口的鼠標(biāo)點(diǎn)擊事件,鼠標(biāo)每次點(diǎn)擊一下小方格,就要判斷所點(diǎn)擊的放個(gè)是否要被消掉。
至此,本項(xiàng)目任務(wù)繪圖部分的知識(shí)點(diǎn)就介紹到這里。
總結(jié)
以上是生活随笔為你收集整理的java 绘制长方形_Java入门:绘制简单图形的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 虚拟化服务器类型,虚拟化服务器类型
- 下一篇: java indexof方法_【3-14