用Java實(shí)現(xiàn)簡單畫板功能
現(xiàn)在,我們來講一下怎么用Java來實(shí)現(xiàn)簡單畫板,要實(shí)現(xiàn)的功能有:選擇圖形(方形、圓形、多邊形...)、可以選擇顏色。
首先,打開windows下的畫圖軟件,我們知道我們需要一個窗體(JFrame);我們要畫畫,需要畫板;我們要選擇圖形、顏色,所以還應(yīng)用到按鈕組件,說到這里,我們所需要的原料基本完成了。接下來,我們要考慮布局:我們采用最簡單的布局,窗體的最上面放選擇圖形的按鈕,中間是畫板,最下面是選擇顏色的按鈕。就是這樣的:
我們把圖形按鈕、顏色按鈕安排在兩個面板上,畫板為一個單獨(dú)的面板,對于布局,我們使用的是BorderLayout()布局管理器,它會把背景組件分割成5個區(qū)域,分別為上下左右 中。圖形按鈕和顏色按鈕挺多的,難道我們要一個個的添加嗎?不是的,我們可以用數(shù)組來存儲圖圖形信息和顏色信息,然后用循環(huán)來添加,速度快,日后也容易添加相應(yīng)的按鈕,擴(kuò)展畫板的功能。代碼如下:
String [] Shape={"直線","曲線","圓","噴槍","橡皮擦","矩形","橢圓","圓角矩形","弧線","多邊形","圖形","三角形","立體圓","樹葉"}; ?? ? ? ?? ?for(int i=0;i<Shape.length;i++){ ? ? ?? ??? ?JButton button=new JButton(Shape[i]); ? ? ?? ??? ?button.addActionListener(dl); ? ?//添加事件監(jiān)聽機(jī)制 ? ? ?? ??? ?ShapePanel.add(button); ? ? ?? ?} ? ? ? ? ? Color [] color={Color.BLACK,Color.blue,Color.white,Color.gray,Color.red,Color.CYAN,Color.green,Color.darkGray,Color.pink}; ? ? ?? ?for(int i=0;i<color.length;i++){ ? ? ?? ??? ?JButton button=new JButton(); ? ? ?? ??? ?button.addActionListener(dl); ? //添加事件監(jiān)聽機(jī)制 ? ? ?? ??? ?button.setPreferredSize(new Dimension(30,30)); ? ? ?? ??? ?button.setBackground(color[i]); ? ? ?? ??? ?ColorPanel.add(button); ? ? ?? ?}
到這里,我們的UI就大功告成啦,可以喝杯茶休息 一下啦。
我們的畫板要怎么知道用戶點(diǎn)擊了那一個圖形按鈕和顏色按鈕呢?是的,我們會想到事件監(jiān)聽。但事件監(jiān)聽只是告訴我們用戶按下了按鈕呀?我們又怎么知道這是個顏色按鈕還是圖形按鈕呀?是什么圖形呀?是什么顏色呀?這是我們接下來要解決的問題。
在上面創(chuàng)建圖形按鈕和顏色按鈕的時候,不知道你有沒有發(fā)現(xiàn)兩種按鈕的不同呢?是的,圖形按鈕有標(biāo)題,顏色按鈕有背景顏色,我們可以根據(jù)這一點(diǎn)來判斷用戶按下的是圖形按鈕還是顏色按鈕。那要怎么來取得按鈕所傳遞過來的圖形和顏色信息呢?我們可以在監(jiān)聽類里面添加Shape和Color屬性來保存。代碼如下:
public void actionPerformed(ActionEvent e){ ?? ? ? ?if(e.getActionCommand().equals("")){ ? ? ?//如果沒有信息,那就是顏色按鈕 ?? ? ? ??? ?JButton button = (JButton) e.getSource(); ? ?? ??? ??? ?color = button.getBackground(); ?? ?? ??? ??? ?System.out.println("color = " + color); ?? ? ? ?}else{ ?? ? ? ??? ?JButton button = (JButton) e.getSource(); ? ?? ??? ??? ?shape = button.getActionCommand(); ?? ?? ??? ??? ?System.out.println("String = " + shape); ?? ? ? ?} ?? ?}
哇,到了這里,我們的工作已經(jīng)完成一大半啦。
接下來就是根據(jù)獲取到的顏色和圖形信息進(jìn)行畫畫啦。先說一下最簡單的設(shè)置顏色,我們只需在用戶按下鼠給畫筆設(shè)置顏色屬性就好。
那我們要怎么畫圖形呢?圖形的完成有在鼠標(biāo)點(diǎn)擊是就完成的,有拖動完成的,有按下拖動然后松開才完成的....要怎么實(shí)現(xiàn)呢?是的,判斷,根據(jù)Shape來判斷,并做出相應(yīng)的動作。
按下就完成的圖形有:方形、圓形、弧線....這些圖形的繪制也比較簡單,只需獲取點(diǎn)下的坐標(biāo)值就可以進(jìn)行畫圖了。如下:
public void mousePressed(MouseEvent e) { ?? ??? ? g=(Graphics2D) df.getGraphics(); ?? ??? ? g.setColor(color); ?? ??? ? x1=e.getX(); ?? ??? ? y1=e.getY(); ?? ??? ? if(shape.equals("圓")){ ?? ??? ??? ? g.drawOval(x1, y1, 30, 30); ?? ??? ? }else if(shape.equals("矩形")){ ?? ??? ??? ? g.drawRect(x1, y1, 30, 40); ?? ??? ? }else if(shape.equals("圓角矩形")){ ?? ??? ??? ? g.drawRoundRect(x1, y1, 30, 40, 5, 10); ?? ??? ? }else if(shape.equals("橢圓")){ ?? ??? ??? ? g.drawOval(x1, y1, 30, 20); ?? ??? ? }else if(shape.equals("弧線")){ ?? ??? ??? ? g.drawArc(x1, y1, 100, 60, 0, 180); ?? ??? ? } ?? ? }
按下并拖動才能完成的有:直線。我們只需記錄下按下是的坐標(biāo)與松開是的坐標(biāo),然后連接兩點(diǎn),就可以畫直線了。代碼如下:
public void mouseReleased(MouseEvent e) { ?? ??? ??? ?x2 = e.getX(); ?? ??? ??? ?y2 = e.getY(); ?? ??? ??? ?if (shape.equals("直線")) { ?? ??? ??? ??? ?g.drawLine(x1, y1, x2, y2); ?? ??? ??? ?}else if(shape.equals("多邊形")&&!flag){ ?? ??? ??? ??? ?g.drawLine(x1, y1, x2, y2); ?? ??? ??? ??? ?newx1=x1; ?? ??? ??? ??? ?newy1=y1; ?? ??? ??? ??? ?newx2=x2; ?? ??? ??? ??? ?newy2=y2; ?? ??? ??? ??? ?flag=true; ?? ??? ??? ?} ? ?? ? }
拖動完成的有:曲線、橡皮擦、噴槍。曲線,我們也是用畫線的方法來實(shí)現(xiàn),但我們每次只畫一個點(diǎn),即起始坐標(biāo)相同,卻每次畫點(diǎn)的坐標(biāo)為鼠標(biāo)拖動過程中每一位置的坐標(biāo)。橡皮擦呢?我們先把畫筆顏色設(shè)置成畫板背景色,用畫曲線的方法,即鼠標(biāo)所在的地方都畫成背景色,實(shí)現(xiàn)橡皮擦的功能,為了突出效果,我們使用Graphics2D,把畫筆調(diào)粗。這樣,效果更加明顯。噴槍,我們使用的是隨機(jī)數(shù),及拖動鼠標(biāo)過程中,同時隨機(jī)的畫出數(shù)十個點(diǎn),來模擬噴槍隨機(jī)的效果。代碼如下:
public void mouseDragged(MouseEvent e) { ?? ??? ??? ?x2 = e.getX(); ?? ??? ??? ?y2 = e.getY(); ?? ??? ??? ?if (shape.equals("曲線")) { //?? ??? ??? ??? ?g.setStroke(new BasicStroke(10));?? ??? ??? ? //?? ??? ??? ??? ?g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); ?? ??? ??? ??? ?g.drawLine(x1, y1, x2, y2); ?? ??? ??? ??? ?x1 = x2; ?? ??? ??? ??? ?y1 = y2; ?? ??? ??? ?}else if(shape.equals("橡皮擦")){ ?? ??? ??? ??? ?g.setStroke(new BasicStroke(80));?? ??? ??? ??? ??? ??? ??? ? ?? ??? ??? ??? ?g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); ?? ??? ??? ??? ?g.setColor(Color.WHITE); ?? ??? ??? ??? ?g.drawLine(x1, y1, x2, y2); ?? ??? ??? ??? ?x1 = x2; ?? ??? ??? ??? ?y1 = y2; ?? ??? ??? ?}else if(shape.equals("噴槍")){ ?? ??? ??? ?//?? ?g.setStroke(new BasicStroke(2));?? ? ?//不用加粗?? ??? ??? ??? ??? ??? ? ?? ??? ??? ?//?? ?g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); ?? ??? ??? ??? ?for(int k=0;k<20;k++){ ?? ??? ??? ??? ??? ?Random i=new Random(); ? ? ?? ?? ??? ??? ??? ??? ?int a=i.nextInt(8); ?? ??? ??? ??? ??? ?int b=i.nextInt(10); ?? ??? ??? ??? ??? ?g.drawLine(x2+a, y2+b, x2+a, y2+b); ?? ??? ??? ??? ?} ?? ??? ??? ?} ?? ??? ?}
接下來,重點(diǎn)講一下多邊形的繪制。在繪制多變形時,第一條邊與畫直線是一樣的,往后,鼠標(biāo)每點(diǎn)一次,就畫一條直線,當(dāng)鼠標(biāo)點(diǎn)兩下時,就畫兩條直線,形成封閉的多邊形。怎么實(shí)現(xiàn)呢?最重要的是要用四個變量來存儲上一個點(diǎn)的坐標(biāo)與最開始的坐標(biāo),每點(diǎn)一次,就在新的點(diǎn)與上一個點(diǎn)之間畫直線,點(diǎn)兩次就多畫一條直線,圍成封閉圖形。代碼如下:
public void mouseClicked(MouseEvent e) { ?? ??? ? if(shape.equals("多邊形")&&flag){ ?? ??? ??? ? x2=e.getX(); ? ? ? ?//獲取新的點(diǎn)的坐標(biāo) ?? ??? ??? ? y2=e.getY(); ?? ??? ??? ? if(e.getClickCount()==2){ ?? ??? ??? ??? ? g.drawLine(newx1, newy1, newx2, newy2); ?? ??? ??? ??? ? flag=false; ?? ??? ??? ? } ?? ??? ??? ? g.drawLine(newx2, newy2, x2, y2); ?? ??? ??? ?? ?? ??? ??? ? newx2=x2; ? //存下上個點(diǎn)的坐標(biāo) ?? ??? ??? ? newy2=y2; ?? ??? ? ? ?} }
到這里,我們終于大功告成啦,雖然還是很小兒科,但這是我們編程路上很重要的一步啦??匆幌鲁晒麍D吧:
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
zuul轉(zhuǎn)發(fā)后服務(wù)取不到請求路徑的解決
這篇文章主要介紹了zuul轉(zhuǎn)發(fā)后服務(wù)取不到請求路徑的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-07-07SpringBoot集成Redisson實(shí)現(xiàn)分布式鎖的方法示例
這篇文章主要介紹了SpringBoot集成Redisson實(shí)現(xiàn)分布式鎖的方法示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-10-10Spring中@order注解用法實(shí)戰(zhàn)教程
@Order注解主要用來控制配置類的加載順序,數(shù)字越小,越先加載,下面這篇文章主要給大家介紹了關(guān)于Spring中@order注解用法的相關(guān)資料,需要的朋友可以參考下2022-11-11淺談java中集合的由來,以及集合和數(shù)組的區(qū)別詳解
下面小編就為大家?guī)硪黄獪\談java中集合的由來,以及集合和數(shù)組的區(qū)別詳解。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2016-10-10MyBatis中的XML實(shí)現(xiàn)和動態(tài)SQL實(shí)現(xiàn)示例詳解
這篇文章主要介紹了MyBatis中的XML實(shí)現(xiàn)和動態(tài)SQL實(shí)現(xiàn),我們可以將XML中重復(fù)出現(xiàn)的內(nèi)容提取出來放到sql標(biāo)簽中,當(dāng)需要用到sql標(biāo)簽中的內(nèi)容時,用include標(biāo)簽將sql標(biāo)簽中的內(nèi)容引進(jìn)來即可,感興趣的朋友跟隨小編一起看看吧2024-02-02淺談mybatis中的#和$的區(qū)別 以及防止sql注入的方法
下面小編就為大家?guī)硪黄獪\談mybatis中的#和$的區(qū)別 以及防止sql注入的方法。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2016-10-10