Java編寫畫圖板程序細節-保存已畫圖形


沒有Java編寫畫圖板程序細節-保存已畫圖形

 

 

 

一、為何我們要保存畫圖板上已畫圖形呢?

  有很多人會問,為什么我們一定要保存畫圖板上已經畫好了的圖形呢?原因很簡單。當我們在畫圖板上畫完自己想畫的圖形后,如果進行以下幾個操作,就會發現幾個降低用戶體驗感的問題,而這些問題就是由於沒有保存已畫圖形造成的。

  首先第一種情況,如果你畫完圖形后,突然發現QQ或者微信來消息了,然后你一般會將畫圖板最小化然后去查收信息,當你再次回到畫圖板程序的時候你會驚奇的發現,你辛辛苦苦繪出的圖片不翼而飛(哭了)。

最小化之前                       

 

     

 

最小化然后再次進入界面后

 

 

  第二種情況,當你發現畫圖板的大小不合適,畫到一半想要調整畫圖板大小時,一旦你調整畫板的大小,你又會驚奇的發現,畫好的圖形又不見了!

調整畫圖板大小之前                        

      

 

調整大小之后

 

  第三種情況,有時候你覺得畫圖板正好覆蓋了一些你想看的內容,你接下來肯定會把畫板界面往電腦屏幕邊界拖從而來看你想看的被覆蓋的內容,但是如果你拖過度了(把畫板界拖到了屏幕外面了),那么恭喜你,圖,又沒了!!!

 

 沒有移動畫圖板界面之前

 

 移動畫圖板界面到屏幕外

 

移動畫圖板界面然后拖回原處后

 

 

 

  怎么樣?是不是感覺體驗感極差,如果這要是別人設計出來的畫圖板,你會有用下去的興趣嗎?還在等什么,咱們一起來找到問題的根源來解決這個坑爹的設計吧!

 

 

二、為何會出現已畫圖形消失的情況呢?

  要想明白出現這個問題的根源呢,首先要明白一個原理:每當我們把將畫圖板最小化再打開時、拖動畫圖板到邊緣再拉回來時或者是改變畫圖板大小時,都是畫圖板的Frame框架在不斷調用它的paint方法的時候。其實這個很好理解,想想我們寫的代碼中有給Frame添加組件的部分,而這些組件包括框架本身是如何可視化讓我們用戶看見的呢?就是通過paint方法將這些組件“畫”到了我們的電腦屏幕上才讓我們看到了這些組件。那么當我們將畫圖板最小化,將畫圖板拖到邊緣或者改變畫圖板大小的時候,都是畫圖板的可視化部分在改變的時候(最小化的時候畫圖板可視化部分全部消失,拖到邊緣的時候畫圖板可視部分部分消失,改變大小的時候畫圖板可視部分大小改變)。既然畫圖板可視部分要改變了,就必須通過重新“畫”一個新的面板上去才能實現狀態的改變,這就是paint方法調用的原因。而Paint方法是一個java早已經定義好的一個方法,設計者並不知道我們用paint方法是來畫什么圖形的,設計者在設計之初只定義了用paint方法把這些組件畫出來了,卻並沒有畫我們自己創造的這些圖形的這個部分。因此當程序自動調用paint方法時,就沒有實現我們之前畫的圖形的可視化過程,只實現了框架組件的可視化過程,這就是為什么會出現已畫圖形消失的原因。

 

 

三、如何解決paint方法無法繪制用戶已畫圖形呢?

  1、保存當前已經繪制了的圖形

    ①用什么來保存我們已經繪制了的圖形?

     試想我們繪制一個圖形需要一些什么屬性與方法呢?就拿直線來說,我們繪制一條直線首先需要知道這個直線的起始點與終止點,如果有設計需要的話還需要知道這條直線的顏色和粗細等等,當然還有一個最重要的屬性,名字(例如“直線”),因為當我們繪制一個圖形對象的時候我們要知道對象是哪個類型的圖形,這樣我們才能使用對應的方法來繪制這個類型的圖形。既然一個圖形通過它自己的屬性和相應的方法能夠繪制出相應的圖形,那么我們不妨創建一個Shape類來實現保存的功能,將所有的圖形有關信息保存到Shape對象中,再調用Shape對象中的繪制方法從而實現可視化圖像的保存功能。

    具體代碼如下:

 

 1 public class Shape {
 2     private int x1,y1,x2,y2,x3,y3;
 3     private String name;
 4     private Color color;
 5     
 6 
 7     public Shape(String name,Color color,int x1, int y1,int x2,int y2,int x3,int y3){
 8         this.x1 = x1;
 9         this.y1 = y1;
10         this.x2 = x2;
11         this.y2 = y2;
12         this.x3 = x3;
13         this.y3 = y3;
14         this.name = name;
15         this.color = color;
16     }
17     
18     
19     public void drawshape(Graphics g){
20         switch(name){
21         case "直線":
22             g.setColor(color);
23             g.drawLine(x1, y1, x2, y2);
24             break;
25         case "三角形":
26             g.setColor(color);
27             g.drawLine(x1, y1, x2, y2);
28             g.drawLine(x1, y1, x3, y3);
29             g.drawLine(x2, y2, x3, y3);
30             break;
31         case "矩形":
32             g.setColor(color);
33             g.drawRect(Math.min(x1, x2), Math.min(y1, y2), Math.abs(x1-x2), Math.abs(y1-y2));
34             break;
35         }
36         
37             
38         
39     }
40 
41 }

 

 

 

 

    ②具體如何將這些圖形保存到Shape對象中?

 

    由於我們的圖形不止一個,所以我們需要創建一個對象數組,例如Shape[]Shapearray = new Shape;來保存不同的圖形。然后在同時繼承了鼠標監視器、動作監視 器、鼠標動作監視器的監視器類中來不斷往這個對象數組里面添加元素。例如當我們畫 直線的時候,我們首先點擊“直線”按鈕與“顏色”兩個按鈕,這個時候我們監視器就 已經通過name屬性和color屬性保存了相應的名字和顏色,然后當我們通過鼠標點擊 移動釋放后得到x1,y1,x2,y2四個坐標,這個時候我們的監視器就已經通過判斷名字顏色 以及坐標位置實現了繪圖功能,那么我們需要添加的步驟呢就只是在繪制完圖形以后繼 續創建一個Shape類型的對象(通過構建函數初始化屬性),然后再把這個對象賦給對 象數組里面的一個元素就實現了一個直線對象的保存。其它類型的對象以此類推。

     具體代碼如下:

  1 public class Drawlistener implements ActionListener,MouseListener,MouseMotionListener{
  2     
  3     private int x1,y1,x2,y2,x3,y3,i=1,j=1,count=1,number = 0;
  4     private String name;
  5     private Color color = Color.BLACK,color2;
  6     private Graphics gr;
  7     private JFrame frame;
  8     private Shape[] shapearray = new Shape[1000000];
  9     public Shape[] getshapearray(){
 10         return  shapearray;
 11     }
 12     public void setgraphics(Graphics gr1){
 13         gr = gr1;
 14     }
 15     public void setcolor(Color color1){
 16         color2 = color1;
 17     }
 18 
 19     @Override
 20     public void actionPerformed(ActionEvent e) {
 21         // TODO Auto-generated method stub
 22         if("".equals(e.getActionCommand())){
 23             JButton botton = (JButton)e.getSource();
 24             color = botton.getBackground();
 25             gr.setColor(color);
 26         }
 27         else{
 28             name = e.getActionCommand();
 29         }
 30         System.out.println(name);
 31     }
 32 
 33     @Override
 34     public void mouseClicked(MouseEvent e) {
 35         // TODO Auto-generated method stub
 36         if("三角形".equals(name)){
 37             x3 = e.getX();
 38             y3 = e.getY();
 39             gr.drawLine(x1, y1, x3, y3);
 40             gr.drawLine(x2, y2, x3, y3);
 41             i--;
 42             Shape shape = new Shape(name,color,x1, y1, x2, y2, x3, y3);
 43             shapearray[number++] = shape;
 44         }
 45         if("多邊形".equals(name)){
 46             count =e.getClickCount();
 47             if(count==1){
 48                 x3 = e.getX();
 49                 y3 = e.getY();
 50                 gr.drawLine(x3, y3, x2, y2);
 51                 Shape shape = new Shape("直線",color,x3,y3,x2,y2,x3,y3);
 52                 shapearray[number++] = shape;
 53                 x2 = x3;
 54                 y2 = y3;
 55             }
 56             else{
 57                 gr.drawLine(x1, y1, x3, y3);
 58                 j--;
 59                 Shape shape = new Shape("直線",color,x1,y1,x3,y3,x3,y3);
 60                 shapearray[number++] = shape;
 61             }
 62         }
 63         
 64     }
 65 
 66     @Override
 67     public void mousePressed(MouseEvent e) {
 68         // TODO Auto-generated method stub
 69         if("直線".equals(name)||"矩形".equals(name)){
 70             x1 = e.getX();
 71             y1 = e.getY();
 72             //System.out.println("x1 "+x1+"y1 "+y1);
 73         }
 74         if("三角形".equals(name)){
 75             if(i == 1){
 76             x1 = e.getX();
 77             y1 = e.getY();
 78             } 
 79         }
 80         if("多邊形".equals(name)&& j==1){
 81             x1 = e.getX();
 82             y1 = e.getY();
 83         }
 84         if("可拖動直線".equals(name)||"連續曲線".equals(name)){
 85             x1 = e.getX();
 86             y1 = e.getY();
 87         }
 88     }
 89 
 90     @Override
 91     public void mouseReleased(MouseEvent e) {
 92         // TODO Auto-generated method stub
 93         if("三角形".equals(name)){
 94             if(i == 1){
 95                 x2 = e.getX();
 96                 y2 = e.getY();
 97                 gr.drawLine(x1, y1, x2, y2);
 98                 i++;
 99             }
100         }
101         if("直線".equals(name)||"可拖動直線".equals(name)){
102             x2 = e.getX();
103             y2 = e.getY();
104             gr.drawLine(x1, y1, x2, y2);
105             //System.out.println("x1 "+ x1+"y1 "+y1+"x2 "+x2+"y2 "+y2);
106             Shape shape = new Shape("直線",color,x1,y1,x2, y2, x3, y3);
107             shapearray[number++] = shape;
108             
109             
110         }
111         if("矩形".equals(name)){
112             x2 = e.getX();
113             y2 = e.getY();
114             gr.drawRect(Math.min(x1, x2), Math.min(y1, y2), Math.abs(x1-x2), Math.abs(y1-y2));
115             Shape shape = new Shape(name,color,x1,y1, x2, y2, x3, y3);
116             shapearray[number++] = shape;
117             
118         }
119         if("多邊形".equals(name)&&j==1){
120             x2 = e.getX();
121             y2 = e.getY();
122             gr.drawLine(x1, y1, x2, y2);
123             Shape shape = new Shape("直線",color,x1,y1,x2,y2,x3,y3);
124             shapearray[number++] = shape;
125             j++;
126             
127         }
128     }
129 
130     @Override
131     public void mouseEntered(MouseEvent e) {
132         // TODO Auto-generated method stub
133         
134     }
135 
136     @Override
137     public void mouseExited(MouseEvent e) {
138         // TODO Auto-generated method stub
139         
140     }
141 
142     @Override
143     public void mouseDragged(MouseEvent e) {
144         // TODO Auto-generated method stub
145         System.out.println("我在努力拖動!");
146         if("可拖動直線".equals(name)){
147             gr.setColor(color2);
148             gr.drawLine(x1, y1, x3, y3);
149             x3 = e.getX();
150             y3 = e.getY();
151             gr.setColor(color);
152             gr.drawLine(x1, y1, x3, y3);
153         }
154         if("連續曲線".equals(name)){
155             x3 = e.getX();
156             y3 = e.getY();
157             gr.drawLine(x1, y1, x3, y3);
158             Shape shape = new Shape("直線",color,x1,y1,x3,y3,x3,y3);
159             shapearray[number++] = shape;
160             x1 = x3;
161             y1 = y3;
162         }
163     }
164 
165     @Override
166     public void mouseMoved(MouseEvent e) {
167         // TODO Auto-generated method stub
168         
169     }
170 
171 }

 

    ③保存了對象之后如何輸出這些對象呢

     之前已經提到了我們原本寫的圖形之所以消失就是因為Java設計者在設計JFrame類的時候並沒有在paint方法寫我們之前畫的那些圖形的繪制,那么我們要做的就很簡單了,就是重寫JFramepaint方法。而方法的重寫是建立在繼承關系上的,所以這個時候我們需要新創建一個類去繼承JFrame類,這個類里面的內容和之前實現畫圖板的類基本一樣,要做的只是把創建的JFrame對象刪去,然后對所有對JFrame對象的屬性或者方法的訪問由“對象.”改為“this.”,因為你已經繼承了JFrame類了,就不需要在類中在創建一個類的對象了。

緊接着要做的就是重寫paint方法。具體操作呢:首先查看JFrame類的源代碼,找到paint方法復制過來,然后在方法體里面寫上 super.paint(g),因為我們重寫方法還是要實現父類方法已有的功能,然后再在這個基礎上寫我們新創建的功能。

最后,將監視器保存的對象數組通過get方法傳送到這個類里面來,通過for循環來將每一個對象繪制到面板上,這樣就實現了對象的輸出了。

    具體代碼如下:

 

 1 public class Drawpanel extends JFrame{
 2     Drawlistener drawlistener = new Drawlistener();
 3     private Shape[] shapearray;
 4     public void showpanel(){
 5         this.setSize(1000,1000);
 6         this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 7         this.setLocationRelativeTo(null);
 8         this.setLayout(new FlowLayout());
 9         String[] shape = {"直線","矩形","三角形","多邊形","連續曲線","可拖動直線"};
10         for(int i = 0; i < shape.length;i++){
11             JButton shapebotton = new JButton(shape[i]);
12             Dimension shapedimension = new Dimension(100,50);
13             shapebotton.setPreferredSize(shapedimension);
14             shapebotton.addActionListener(drawlistener);
15             this.add(shapebotton);
16         }
17         Color[] color = {Color.RED,Color.BLUE,Color.GREEN};
18         String[]colorname = {"紅色","藍色","綠色"};
19         for(int j = 0; j < color.length;j++){
20             JButton colorbotton = new JButton();
21             Dimension colordimension = new Dimension(100,50);
22             colorbotton.setPreferredSize(colordimension);
23             colorbotton.setBackground(color[j]);
24             colorbotton.addActionListener(drawlistener);
25             colorbotton.setToolTipText(colorname[j]);
26             this.add(colorbotton);
27         }
28         this.addMouseListener(drawlistener);
29         this.addMouseMotionListener(drawlistener);
30             this.setVisible(true);
31             Graphics gr = this.getGraphics();
32             drawlistener.setgraphics(gr);
33             drawlistener.setcolor(this.getBackground());
34         
35         }
36     public void paint(Graphics g){
37         super.paint(g);
38         shapearray = drawlistener.getshapearray();
39         for(int i = 0; i <    shapearray.length;i++)
40         {
41             if(shapearray[i] != null){
42                 shapearray[i].drawshape(g);
43             }
44             else{
45                 break;
46             }
47             
48         }
49     }
50                 
51         
52     
53     public static void main(String[] args){
54         Drawpanel drawpanel = new Drawpanel();
55         drawpanel.showpanel();
56     }
57 
58     
59 
60 }

 

 

這樣就解決了以上所說的問題了,上面的三段代碼已經能夠編寫一個較為簡單的畫圖板,希望能幫助到你們!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM