Java简易绘图板

来源:互联网 发布:淘宝商业的竞争环境 编辑:程序博客网 时间:2024/05/02 04:15

最近终于学到了Swing,做了个简易画板。先完成自由绘制的功能,然后添加一堆按钮并加上相应的功能。


想加一个撤消上一步操作的功能,但是想不到应该怎么实现。

换背景色是用重新填充整块画布的方式来完成,这样会把画布上的所有内容清空,该如何在不影响已有内容的情况下,更换背景色呢?不知道有没有类似PhotoShop里的图层的组件。

总结出以下两点收获:

1.Image默认背景色是黑色,Graphics默认背景色是白色。

2.JToolBar和JPopupMenu都可以使用add(Action a)的方法添加一个按钮,但是JPanel就不行,只能把Action当作事件监听器添加。


另外推荐大家使用Sublime Text,体积小巧,功能强大。我选了自带的Solarized(Dark)主题,另外装了个Monaco字体和MacType字体渲染程序,界面非常漂亮。

刚用没多久,有两个功能非常实用。

一是分屏浏览+克隆,如下图,写界面的时候看变量名非常方便。



二是定位。cmd调试代码时会提示哪一行出现什么错误,这时回到Sublime Text,按下Ctrl+G,输入行数直达。



以下是我搜集的Sublime Text 3下载地址和使用技巧,其中破解版集成了中文补丁了很多插件。

Sublime Text3下载


最后附上程序代码


import java.awt.image.BufferedImage;import java.awt.*;import javax.swing.*;import java.awt.event.*;public class Test{    //窗口    private JFrame f = new JFrame("绘图板");    //区域大小    private final int WIDTH = 600;    private final int HEIGHT = 600;    //上一次鼠标坐标    private int preX;    private int preY;    //按下鼠标时的坐标    private int startX;    private int startY;    //画布    MyCanvas drawArea = new MyCanvas();    //画图用的image    BufferedImage image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);    //重写Graphics中的画矩形方法    Graphics g = image.getGraphics();    //前景色默认红,背景色默认白    private Color foreColor = new Color(255, 0, 0);    private Color backColor = new Color(255, 255, 255);    //画笔,标记执行何种绘画模式    //画笔的值均为四字符的小写字母    private String brush = "free";    //上方工具栏    private JPanel p = new JPanel();    private JButton lineButton = new JButton("直线");    private JButton rectButton = new JButton("矩形");    private JButton circButton = new JButton("圆形");    private JButton freeButton = new JButton("自由绘制");    private JButton foreButton = new JButton("前景色");    private JButton backButton = new JButton("背景色");    private JButton clearButton = new JButton("清空画布");    //右键菜单,功能与工具栏上的按钮一模一样    private JPopupMenu popMenu = new JPopupMenu("画图选项");    //添加清空按钮    //AbstractAction是Action接口的实现类,故不须重写所有方法    //按钮和右键菜单都使用这个Action    //JPanel不能使用JPanel.add(Action)来创建Button    //按钮全要做到右键菜单上,所以每个按钮单独一个Action    Action clearDrawArea = new AbstractAction("清空画布"){        public void actionPerformed(ActionEvent e){            //调用画布初始化方法,即完成清空画布            imageInit();        }    };    //按下按钮的事件监听器    Action drawLine = new AbstractAction("直线"){        public void actionPerformed(ActionEvent e){            brush = "line";        }    };    Action drawRect = new AbstractAction("矩形"){        public void actionPerformed(ActionEvent e){            brush = "rect";        }    };    Action drawCirc = new AbstractAction("圆形"){        public void actionPerformed(ActionEvent e){            brush = "circ";        }    };    Action drawFree = new AbstractAction("自由绘制"){        public void actionPerformed(ActionEvent e){            brush = "free";        }    };    Action chooseForeColor = new AbstractAction("前景色"){        public void actionPerformed(ActionEvent e){            foreColor = chooseColor();        }    };    Action chooseBackColor = new AbstractAction("背景色"){        public void actionPerformed(ActionEvent e){            backColor = chooseColor();            imageInit();        }    };    //初始化    private void init(){        drawArea.setPreferredSize(new Dimension(WIDTH, HEIGHT));        f.add(drawArea);        //组合按钮        lineButton.addActionListener(drawLine);        rectButton.addActionListener(drawRect);        circButton.addActionListener(drawCirc);        freeButton.addActionListener(drawFree);        foreButton.addActionListener(chooseForeColor);        backButton.addActionListener(chooseBackColor);        clearButton.addActionListener(clearDrawArea);        p.add(lineButton);        p.add(rectButton);        p.add(circButton);        p.add(freeButton);        p.add(foreButton);        p.add(backButton);        p.add(clearButton);        f.add(p, BorderLayout.NORTH);        //组合右键菜单        popMenu.add(drawLine);        popMenu.add(drawRect);        popMenu.add(drawCirc);        popMenu.add(drawFree);        popMenu.addSeparator();        popMenu.add(chooseForeColor);        popMenu.add(chooseBackColor);        popMenu.addSeparator();        popMenu.add(clearDrawArea);        drawArea.setComponentPopupMenu(popMenu);        //image初始化        imageInit();        //按下鼠标时记录坐标        drawArea.addMouseListener(new MouseAdapter(){            public void mousePressed(MouseEvent e){                startX = e.getX();                startY = e.getY();            }        });        //拖曳鼠标时绘画        drawArea.addMouseMotionListener(new MouseMotionAdapter(){            public void mouseDragged(MouseEvent e){                  switch (brush){                    case "free":                        if((preX > 0) && (preY > 0)){                                                g.setColor(foreColor);                            g.drawLine(preX, preY, e.getX(), e.getY());                        }                        drawArea.repaint();                        setPreXY(e);                        break;                    case "line":                              //如果鼠标移动,则撤消原来的直线                        //以背景色画该直线模拟取消                              if(((e.getX() != preX)&&(preX != -1)) || ((e.getY() != preY)&&(preY != -1))){                            g.setColor(backColor);                            g.drawLine(startX, startY, preX, preY);                        }                                    g.setColor(foreColor);                        g.drawLine(startX, startY, e.getX(), e.getY());                        setPreXY(e);                        drawArea.repaint();                        break;                    case "rect":                        if(((e.getX() != preX)&&(preX != -1)) || ((e.getY() != preY)&&(preY != -1))){                            g.setColor(backColor);                            myDrawRect(startX, startY, preX, preY);                        }                        g.setColor(foreColor);                        myDrawRect(startX, startY, e.getX(), e.getY());                        setPreXY(e);                        drawArea.repaint();                        break;                    case "circ":                        if(((e.getX() != preX)&&(preX != -1)) || ((e.getY() != preY)&&(preY != -1))){                            g.setColor(backColor);                            myDrawOval(startX, startY, preX, preY);                        }                        g.setColor(foreColor);                        myDrawOval(startX, startY, e.getX(), e.getY());                        setPreXY(e);                        drawArea.repaint();                        break;                                                                }                                              }        });        //松开鼠标时preX、preY复位        drawArea.addMouseListener(new MouseAdapter(){            public void mouseReleased(MouseEvent e){                preX = -1;                preY = -1;            }        });                f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);        f.pack();        f.setVisible(true);    }    //选择颜色对话框    private Color chooseColor(){        //显示有模式的颜色选取器,在隐藏对话框之前一直阻塞        return JColorChooser.showDialog(drawArea, "请选择画笔颜色",foreColor);            }    //画布初始化    private void imageInit(){        //image初始是黑色,填充白色背景        g.setColor(backColor);        g.fillRect(0,0,WIDTH, HEIGHT);        drawArea.repaint();    }    //preX,preY复位    private void setPreXY(MouseEvent e){        preX = e.getX();        preY = e.getY();    }    //自定义画矩形,起始点有可能在右下角,则须先排序再画    private void myDrawRect(int a, int b, int c, int d){        //根据(a,b),(c,d)两点画矩形,求出左上角顶点的坐标        //宽和高是固定的|a-c|和|b-d|        //罗列四种情况并计算得出如下算法        g.drawRect(a<c?a:c, b<d?b:d, Math.abs(a-c), Math.abs(b-d));    }    //自定义画圆,起始点有可能在右下角,则须先排序再画    private void myDrawOval(int a, int b, int c, int d){        //根据(a,b),(c,d)两点画矩形,求出左上角顶点的坐标        //宽和高是固定的|a-c|和|b-d|        //罗列四种情况并计算得出如下算法        g.drawOval(a<c?a:c, b<d?b:d, Math.abs(a-c), Math.abs(b-d));    }            //自定义画布,继承自JPanel,重写Paint方法    private class MyCanvas extends JPanel{        public void paint(Graphics g){            g.drawImage(image, 0,0,null);                    }    }    public static void main(String[] args){        new Test().init();    }}



0 0
原创粉丝点击