lesson 3 画板的重绘
在做画板的时候,最小化窗口后聊QQ发现之前在画板上画的图形全不见了。在这节课讲到这是因为在重新最大化了的时候调用了画板上的paint方法,使画板上原来的组件重绘上去了,但是画出了的图形却没有保存在内存里,不能画出来。
所以要把图形也重绘出来的办法就是把图形也存进内存里,重写paint方法把图形也重绘出来。
首先是创建画板的窗体,各种初始化各种添加设置组件,然后实例化了个自己写的动态数组,用来存放图形的
public class MyDraw {//实例化一个动态数组对象MyArray arr = new MyArray();//主方法,实例化窗口对象,调用显示方法public static void main(String[] args) {MyDraw md = new MyDraw();md.show();}//显示画板窗口的方法public void show() {//实例化窗口对象,并初始化窗口JFrame jf = new JFrame("我的画板");jf.setSize(600,500);jf.setDefaultCloseOperation(3);jf.setLayout(new BorderLayout());//实例化北边画板对象,并初始化画板JPanel jp_north = new JPanel();jp_north.setPreferredSize(new Dimension(584,65));jp_north.setBackground(Color.gray);//实例化三个形状按钮,并初始化按钮标注JButton bu_line = new JButton("直线");JButton bu_rect = new JButton("矩形");JButton bu_oval = new JButton("椭圆");JButton bu_pen = new JButton("画笔");bu_line.setActionCommand("直线");bu_rect.setActionCommand("矩形");bu_oval.setActionCommand("椭圆");bu_pen.setActionCommand("画笔");//将三个形状按钮添加到北边画板上jp_north.add(bu_line);jp_north.add(bu_rect);jp_north.add(bu_oval);jp_north.add(bu_pen);//设置形状按钮的按钮监听器,并加在这三个形状按钮上TypeActionListener typel = new TypeActionListener();bu_line.addActionListener(typel);bu_rect.addActionListener(typel);bu_oval.addActionListener(typel);bu_pen.addActionListener(typel);//实例化三个颜色按钮,并初始化标注JButton bu_red = new JButton("红色");JButton bu_green = new JButton("绿色");JButton bu_colorchooser = new JButton("调色板");bu_red.setActionCommand("红色");bu_green.setActionCommand("绿色");bu_colorchooser.setActionCommand("调色板");//将三个形状按钮添加到北边画板上jp_north.add(bu_red);jp_north.add(bu_green);jp_north.add(bu_colorchooser);//设置颜色按钮的监听器,并加在这三个按钮上ColorActionListener colorl = new ColorActionListener(); bu_red.addActionListener(colorl);bu_green.addActionListener(colorl);bu_colorchooser.addActionListener(colorl);//设置南边的画板,并初始化画板MyJPanel jp_south = new MyJPanel(arr);jp_south.setPreferredSize(new Dimension(584,435));jp_south.setBackground(Color.WHITE);//将两个画板添加到窗体上jf.add(jp_north,BorderLayout.NORTH);jf.add(jp_south,BorderLayout.SOUTH);jf.setVisible(true);Graphics g = jp_south.getGraphics();//实例化鼠标监听器对象,并把鼠标监听器加在南边画板上MyMouseListener ml = new MyMouseListener(g, typel, colorl,arr,jp_south);jp_south.addMouseListener(ml);jp_south.addMouseMotionListener(ml);}}public class Shape {private int x1,x2,y1,y2;private Color color = Color.BLACK;private String type = "直线";//shape具有的可以画图的方法public void draw(Graphics g){g.setColor(color);if(type.equals("直线")||type.equals("画笔")){g.drawLine(x1, y1, x2, y2);}else if(type.equals("矩形")){g.drawRect(Math.min(x1, x2),Math.min(y1, y2),Math.abs(x2-x1), Math.abs(y2-y1));}else if(type.equals("椭圆")){g.drawOval(Math.min(x1, x2),Math.min(y1, y2),Math.abs(x2-x1), Math.abs(y2-y1));}}public int getX1() {return x1;}public void setX1(int x1) {this.x1 = x1;}public int getX2() {return x2;}public void setX2(int x2) {this.x2 = x2;}public int getY1() {return y1;}public void setY1(int y1) {this.y1 = y1;}public int getY2() {return y2;}public void setY2(int y2) {this.y2 = y2;}public Color getColor() {return color;}public void setColor(Color color) {this.color = color;}public String getType() {return type;}public void setType(String type) {this.type = type;}}public class TypeActionListener implements ActionListener {private String type = "直线";public void actionPerformed(ActionEvent e) {//按下形状按钮时获得选择的形状type = e.getActionCommand();}public String getType(){return type;}}public class ColorActionListener implements ActionListener {private Color color = Color.BLACK;public void actionPerformed(ActionEvent e) {//按下颜色按钮后获得选择的颜色if(e.getActionCommand().equals("红色")){color = Color.red;}else if(e.getActionCommand().equals("绿色")){color = Color.green;}else if(e.getActionCommand().equals("调色板")){color = JColorChooser.showDialog(null, "请选择颜色", Color.black);}}public Color getColor(){return color;}}public class MyMouseListener extends MouseAdapter {private int x1,y1,x2,y2,x3,y3;private Graphics g;private TypeActionListener typel;private ColorActionListener colorl;private MyArray arr;private MyJPanel Panel;//重写构造器public MyMouseListener(Graphics g,TypeActionListener typel,ColorActionListener colorl,MyArray arr,MyJPanel Panel) {this.g = g;this.colorl = colorl;this.typel = typel;this.arr = arr;this.Panel = Panel;} public void mousePressed(MouseEvent e) { //记录下第一个点 x1 = x3 = e.getX(); y1 = y3 = e.getY(); } public void mouseReleased(MouseEvent e) { if(typel.getType()!="画笔"){ //创建一个Shape对象 Shape shape = new Shape(); //把从形状和颜色按钮获得的选择保存进shape shape.setColor(colorl.getColor()); shape.setType(typel.getType()); //把点存进shape shape.setX1(x1); shape.setY1(y1); shape.setX2(x2); shape.setY2(y2); //把shape存进动态数组 arr.add(shape); } } public void mouseDragged(MouseEvent e){ //用白色重画之前的图形 if(typel.getType().equals("直线")){ g.setColor(Color.WHITE); g.drawLine(x1, y1, x3, y3); }else if(typel.getType().equals("矩形")){ g.setColor(Color.WHITE); g.drawRect(Math.min(x1, x3),Math.min(y1, y3),Math.abs(x3-x1), Math.abs(y3-y1)); }else if(typel.getType().equals("椭圆")){ g.setColor(Color.WHITE); g.drawOval(Math.min(x1, x3),Math.min(y1, y3),Math.abs(x3-x1), Math.abs(y3-y1)); } //调用Panel的重绘方法,以防白色擦去之前的图形 Panel.paint(g); //获取第二个点 x2 = e.getX(); y2 = e.getY(); //画出移动后新的图形 g.setColor(colorl.getColor()); if(typel.getType().equals("直线")){ g.drawLine(x1, y1, x2, y2); }else if(typel.getType().equals("矩形")){ g.drawRect(Math.min(x1, x2),Math.min(y1, y2),Math.abs(x2-x1), Math.abs(y2-y1)); }else if(typel.getType().equals("椭圆")){ g.drawOval(Math.min(x1, x2),Math.min(y1, y2),Math.abs(x2-x1), Math.abs(y2-y1)); }else if(typel.getType().equals("画笔")){ System.out.println(x1+" "+y1+" "+x2+" "+y2+" "+x3+" "+y3); g.drawLine(x3, y3, x2, y2); //创建一个Shape对象 Shape shape = new Shape(); //把从形状和颜色按钮获得的选择保存进shape shape.setColor(colorl.getColor()); shape.setType(typel.getType()); //把点存进shape shape.setX1(x3); shape.setY1(y3); shape.setX2(x2); shape.setY2(y2); arr.add(shape); } //将新的点保存进旧的点 x3 = x2; y3 = y2; }}public class MyJPanel extends JPanel {private MyArray arr;public MyJPanel(MyArray arr) {this.arr = arr;}public void paint(Graphics g) {super.paint(g);//将动态数组里的所有元素调用画图的方法重绘所有保存的图形for(int i=0;i<arr.size();i++){arr.get(i).draw(g);}}}public class MyArray {//初始化数组Shape [] arr = {};/** * 往数组里面添加元素的方法 * 通过新建一个原数组大小+1大小的数组实现添加 */public void add(Shape s) {//System.out.println(s.getX1()+" "+s.getY1()+" "+s.getX2()+" "+s.getY2());Shape temp [] = new Shape [arr.length+1];for(int i=0;i<arr.length;i++)temp[i] = arr[i];temp[arr.length] = s;arr = temp;/*for(int i=0;i<arr.length;i++){System.out.println(arr[i].getX1()+" "+arr[i].getY1()+" "+arr[i].getX2()+" "+arr[i].getY2());}*/}/** * 从数组里面取出元素的方法 */public Shape get(int index){return arr[index];}/** * 获取数组的大小的方法 */public int size(){return arr.length;}/** * 删除数组指定元素 * 按照指定的数组下标删除,并返回被删除的元素 */public Shape delete(int index){Shape del = arr[index];Shape [] temp = new Shape[arr.length-1];for(int i=0;i<temp.length;i++){if(i<index)temp[i] = arr[i];else temp[i] = arr[i+1];}arr = temp;return del;}/** * 清空数组,使得数组初始化为一个空数组 */public void init(){arr = new Shape [] {};}/** * 删除数组指定元素 * 按照指定的元素数据删除,并返回被删除的元素 *//*public String delete(String s){String del = null;int j=0,num=0;for(int i=0;i<arr.length;i++){if(arr[i].equals(s))num++;}//System.out.println(num);String [] temp = new String[arr.length-num];for(int i=0;i<temp.length;i++){if(arr[j].equals(s)){//System.out.println(" "+i+" "+j);del = arr[j];j++;temp[i] = arr[j];j++;}else{//System.out.println("*"+i+" "+j);temp[i] = arr[j];j++;}//System.out.println(temp[i]);}arr = temp;return del;}*//** * 将一个指定元素插入指定下标的数组位置中 */public void jump(Shape s,int index){Shape temp [] = new Shape [arr.length+1];for(int i=0;i<temp.length;i++){if(i<index)temp[i] = arr[i];else if(i==index)temp[i] = s;elsetemp[i] = arr[i-1];System.out.println(temp[i]);}arr = temp;}