zoukankan      html  css  js  c++  java
  • JAVA 画图板实现(基本画图功能+界面UI)二、功能实现及重绘实现

    上篇博客中介绍了界面的实现方法,在这篇博客中将对每个按钮的功能的实现进行讲解并介绍重绘

    首先肯定要添加事件监听机制了,那么问题来了,事件源对象是谁?需要添加什么方法?事件接口是什么?

    1、我们需要点击按钮,获取按钮上的文字信息,颜色信息,粗细信息。那么,此时事件源对象就是按钮,监听方法就是addActionListener(ActionListener e),事件接口就是ActionListener

    2、要根据在窗体上按下和释放的位置画一个图形,此时事件源对象就是窗体,监听方法就是addMouseListener(MouseListener e),事件接口就是MouseListener

     1 public class DrawListener extends MouseAdapter implements ActionListener {
     2 
     3     private Color color = Color.black;// 声明颜色属性,存储用户选择的颜色
     4     private int width = 1;// 声明粗细属性,存储用户选择的粗细
     5     private String type = "Line";// 声明图形属性,存储用户选择的图形
     6     private int x1, y1, x2, y2, x3 = 0, y3 = 0, x4 = 0, y4 = 0, x5, y5;// 声明坐标值属性,存储鼠标按下和释放的坐标值
     7     private Graphics2D g;// 声明画笔类属性,组件是画出来的,现在要在组件上画图形,Graphics从组件上获取
     8     private DrawMain dm;// 声明画图程序窗体组件属性
     9     private JTextField text;// 获取文本框内容
    10     private double H = 100;// 等腰三角形的高度
    11     private int num = 0;
    12     private List<Shape> list;
    13     private ImageIcon i = new ImageIcon("C:\Users\long452a\Desktop\a1.jpg");
    14 
    15     /**
    16      * 构造方法
    17      * 
    18      * @param dm画图程序的窗体组件对象
    19      */
    20     public DrawListener(DrawMain dm, JTextField text, List<Shape> list) {
    21         this.dm = dm;
    22         this.text = text;
    23         this.list = list;
    24     }
    25 
    26     /**
    27      * 点击按钮时执行的事件处理方法
    28      * 
    29      * @param e对象中存储了事件源对象的信息和动作信息
    30      */
    31     public void actionPerformed(ActionEvent e) {
    32     }
    33 
    34     /**
    35      * Invoked when the mouse button has been clicked (pressed and released) on a
    36      * component.
    37      */
    38     public void mouseClicked(MouseEvent e) {
    39     }
    40 
    41     /**
    42      * Invoked when a mouse button has been pressed on a component.
    43      */
    44     public void mousePressed(MouseEvent e) {
    45     }
    46 
    47     /**
    48      * Invoked when a mouse button has been released on a component.
    49      */
    50     public void mouseReleased(MouseEvent e) {
    51     }
    52         
    53     public void mouseDragged(MouseEvent e) {
    54     }
    55 }

    这样我们的类就建好了,下面就该写里面的方法了

      1     /**
      2      * 点击按钮时执行的事件处理方法
      3      * 
      4      * @param e对象中存储了事件源对象的信息和动作信息
      5      */
      6     public void actionPerformed(ActionEvent e) {
      7         String text = e.getActionCommand();
      8         if (text.equals("")) {
      9             JButton button = (JButton) e.getSource();
     10             color = button.getBackground();
     11         } else if (text.equals("1") || text.equals("3") || text.equals("5")) {
     12             width = Integer.parseInt(text);
     13         } else {
     14             type = text;
     15         }
     16         // System.out.println(color + ">>" + width + ">>" + type);
     17     }
     18 
     19     /**
     20      * Invoked when the mouse button has been clicked (pressed and released) on a
     21      * component.
     22      */
     23     public void mouseClicked(MouseEvent e) {
     24         x4 = x2;
     25         y4 = y2;
     26     }
     27 
     28     /**
     29      * Invoked when a mouse button has been pressed on a component.
     30      */
     31     public void mousePressed(MouseEvent e) {
     32         x1 = e.getX() + 7;
     33         y1 = e.getY() + 183;
     34         if (y1 < 183)
     35             y1 = 183;
     36         g = (Graphics2D) dm.getGraphics();// 从窗体上获取画笔对象
     37         g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);// 设置画笔抗锯齿
     38         g.setColor(color);// 设置画笔颜色
     39         g.setStroke(new BasicStroke(width));// 设置画笔线条粗细
     40 
     41     }
     42 
     43     /**
     44      * Invoked when a mouse button has been released on a component.
     45      */
     46     public void mouseReleased(MouseEvent e) {
     47         x2 = e.getX() + 7;
     48         y2 = e.getY() + 183;
     49         if (y2 < 183)
     50             y2 = 183;
     51         if (type.equals("iso_Tri")) {
     52             if (x1 == x2) {
     53                 g.drawLine(x1, y1, x2, y2);
     54                 g.drawLine(x1, y1, x1 + (int) H, (y2 + y1) / 2);
     55                 g.drawLine(x2, y2, x1 + (int) H, (y2 + y1) / 2);
     56                 list.add(new Shape(x1, y1, x2, y2, width, color, type, i, dm, text));
     57                 list.add(new Shape(x1, y1, x1 + (int) H, (y2 + y1) / 2, width, color, type, i, dm, text));
     58                 list.add(new Shape(x2, y2, x1 + (int) H, (y2 + y1) / 2, width, color, type, i, dm, text));
     59             } else if (y1 == y2) {
     60                 g.drawLine(x1, y1, x2, y2);
     61                 g.drawLine(x1, y1, (x1 + x2) / 2, y1 + (int) H);
     62                 g.drawLine(x2, y2, (x1 + x2) / 2, y1 + (int) H);
     63                 list.add(new Shape(x1, y1, x2, y2, width, color, type, i, dm, text));
     64                 list.add(new Shape(x1, y1, x1 + (x1 + x2) / 2, y1 + (int) H, width, color, type, i, dm, text));
     65                 list.add(new Shape(x2, y2, x1 + (x1 + x2) / 2, y1 + (int) H, width, color, type, i, dm, text));
     66             } else {
     67                 double a = Math.atan((double) (x2 - x1) / (double) (y2 - y1));
     68                 double x3 = (double) (x1 + x2) / 2 + H * Math.cos(a);
     69                 double y3 = (double) (y1 + y2) / 2 - H * Math.sin(a);
     70                 g.drawLine(x1, y1, x2, y2);
     71                 g.drawLine(x1, y1, (int) x3, (int) y3);
     72                 g.drawLine(x2, y2, (int) x3, (int) y3);
     73                 list.add(new Shape(x1, y1, x2, y2, width, color, type, i, dm, text));
     74                 list.add(new Shape(x1, y1, x1 + (int) x3, (int) y3, width, color, type, i, dm, text));
     75                 list.add(new Shape(x2, y2, (int) x3, (int) y3, width, color, type, i, dm, text));
     76             }
     77         } else if (type.equals("Polygon")) {
     78             if (num == 0) {
     79                 g.drawLine(x1, y1, x2, y2);
     80                 list.add(new Shape(x1, y1, x2, y2, width, color, type, i, dm, text));
     81                 x5 = x2;
     82                 y5 = y2;
     83             }
     84             num++;
     85             if (num == 1) {
     86                 x3 = x1;
     87                 y3 = y1;
     88             }
     89             if (x2 == x4 && y2 == y4) {
     90                 g.drawLine(x1, y1, x3, y3);
     91                 list.add(new Shape(x1, y1, x3, y3, width, color, type, i, dm, text));
     92                 num = 0;
     93             } else {
     94                 g.drawLine(x2, y2, x5, y5);
     95                 list.add(new Shape(x2, y2, x5, y5, width, color, type, i, dm, text));
     96                 x5 = x2;
     97                 y5 = y2;
     98             }
     99         } else {
    100             Shape s = new Shape(x1, y1, x2, y2, width, color, type, i, dm, text);
    101             s.draw(g);
    102             list.add(s);
    103         }
    104     }
    105 
    106     public void mouseDragged(MouseEvent e) {
    107         if (type.equals("Pencil")) {
    108             x2 = e.getX() + 7;//这里的+7 +183 是调出来的,能够使画的图是沿着鼠标
    109             y2 = e.getY() + 183;
    110             if (y2 < 183)
    111                 y2 = 183;
    112             Shape s = new Shape(x1, y1, x2, y2, width, color, type, i, dm, text);
    113             s.draw(g);
    114             list.add(s);
    115             x1 = x2;
    116             y1 = y2;
    117         } else if (type.equals("Erase")) {
    118             x2 = e.getX() + 7;
    119             y2 = e.getY() + 183;
    120             if (y2 < 183)
    121                 y2 = 183;
    122             Shape s = new Shape(x1, y1, x2, y2, width, Color.WHITE, type, i, dm, text);
    123             s.draw(g);
    124             list.add(s);
    125             x1 = x2;
    126             y1 = y2;
    127         } else if (type.equals("喷枪")) // 难点
    128         {
    129             Random rand = new Random();// 实例化一个随机数类的对象
    130             int size = rand.nextInt(50);// 随机决定要画的点数
    131             x2 = e.getX() + 7;
    132             y2 = e.getY() + 183;
    133             for (int j = 0; j < size; j++) {
    134                 // 在0-7之间可以取50次
    135                 int x = rand.nextInt(10);
    136                 int y = rand.nextInt(10);
    137                 // 不断改变(x1,y1)的坐标值,实现在(x1,y1)的周围画点
    138                 Shape s = new Shape(x2 + x, y2 + y, x2 + x, y2 + y, width, color, type, i, dm, text);
    139                 s.draw(g);
    140                 list.add(s);
    141                 x1 = x2;
    142                 y1 = y2;
    143             }
    144         }
    145     }

      仔细看看代码,你也许注意到了,我在画图时创建了一个Shape对象,并且还把Shape对象存到了一个List中,为什么要这么做?你们可以去别人的博客上贴一个粗略实现的画图板代码,画几条直线然后再改变窗体的大小试试看,是不是画的直线不见了?那要怎么做才能使这些图形保存下来呢?这就需要用到重绘了。

      但是,我们需要知道,为什么图形会消失?其实计算机中的界面什么都是画出来的。自然组件也是画出来的,而改变组件大小的时候,原来的组件无法满足现在组件的显示要求,所以组件要重新画一次,然而此时组件上的图形并不会重新再画一次,为什么?组件已经默认有重绘的方法了paint(Graphics g),所以我们需要重写这个方法,但是我们怎么能让计算机知道之前画了什么呢?这是就需要把每次画的内容记录到队列或数组中,重绘时就可以根据这个队列或是数组进行了。而创建Shape对象自然是为了方便保存这些图形的数据了。

    下面是Shape的写法

     1 public class Shape {
     2 
     3     private int x1, y1, x2, y2, width;
     4     private Color color;
     5     private String type;
     6     private ImageIcon i;
     7     private DrawMain dm;
     8     private JTextField text;
     9 
    10     public Shape(int x1, int y1, int x2, int y2, int width, Color color, String type, ImageIcon i, DrawMain dm,
    11             JTextField text) {
    12         this.x1 = x1;
    13         this.y1 = y1;
    14         this.x2 = x2;
    15         this.y2 = y2;
    16         this.width = width;
    17         this.color = color;
    18         this.type = type;
    19         this.i = i;
    20         this.dm = dm;
    21         this.text = text;
    22     }
    23 
    24 
    25     public void draw(Graphics2D g) {
    26         g.setColor(color);
    27         g.setStroke(new BasicStroke(width));
    28         if (type.equals("Line") || type.equals("Pencil") || type.equals("iso_Tri") || type.equals("Polygon")
    29                 || type.equals("Erase") || type.equals("喷枪")) {
    30             g.drawLine(x1, y1, x2, y2);
    31         } else if (type.equals("Oval")) {
    32             g.fillOval(Math.min(x1, x2), Math.min(y1, y2), Math.abs(x2 - x1), Math.abs(y2 - y1));
    33         } else if (type.equals("Rect")) {
    34             g.drawRect(Math.min(x1, x2), Math.min(y1, y2), Math.abs(x2 - x1), Math.abs(y2 - y1));
    35         } else if (type.equals("RoundRect")) {
    36             g.drawRoundRect(Math.min(x1, x2), Math.min(y1, y2), Math.abs(x2 - x1), Math.abs(y2 - y1),
    37                     Math.abs(x2 - x1) / 3, Math.abs(y2 - y1) / 3);
    38         } else if (type.equals("fill3DRect")) {
    39             g.fill3DRect(Math.min(x1, x2), Math.min(y1, y2), Math.abs(x2 - x1), Math.abs(y2 - y1), true);
    40         } else if (type.equals("fillArc")) {
    41             double r = ((x2 - x1) * (x2 - x1) + y1 * y1) / (2 * y1);
    42             double m = Math.asin((double) (x2 - x1) / r);
    43             g.fillArc(Math.min(x1, x2), Math.min(y1, y2), Math.abs(x2 - x1), (int) r, 0, (int) (m * 180 / Math.PI));
    44         } else if (type.equals("Image")) {
    45             g.drawImage(i.getImage(), Math.min(x1, x2), Math.min(y1, y2), Math.abs(x2 - x1), Math.abs(y2 - y1), dm);
    46         } else if (type.equals("Text")) {
    47             g.drawString(text.getText(), x1, y1);
    48         }
    49     }
    50 
    51 }

    现在还有一个问题,paint该写在哪?写在之前写的DrawMain中

    private List<Shape> list = new ArrayList<Shape>();
    
        public void paint(Graphics gr) {
            super.paint(gr);
            Graphics2D g = (Graphics2D) gr;
            g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            for (int i = 0; i < list.size(); i++) {
                Shape shape = list.get(i);
                shape.draw(g);
            }
        }

    提醒一下:别忘了把事件监听添加到组件中!!!!

    这样一来,我们的画图板就能完美使用了。当然这个画图板跟系统中的比起来还是差了很多了,比如撤销、重做、保存等功能都还不具备,剩下的功能就需要后面慢慢研究再完善了。

  • 相关阅读:
    黄聪:手机移动端建站Jquery+CSS3+HTML5触屏滑动特效插件、实现触屏焦点图、图片轮展图
    黄聪:VS2010开发如何在c#中使用Ctrl、Alt、Tab等全局组合快捷键
    利用python实现汉字转拼音
    python 获得质数
    将你的python转成exe格式
    python 动画
    python 饼状图
    python 抓屏
    python 图像迷糊
    python-opencv-圆、椭圆与任意多边形的绘制
  • 原文地址:https://www.cnblogs.com/csu-lmw/p/9288262.html
Copyright © 2011-2022 走看看