初步学习java---简单画图板(注:画板还没完善,后期逐步完善)

来源:互联网 发布:剑网三 脸型数据萝莉 编辑:程序博客网 时间:2024/05/22 03:38

1.创建一个窗体JFrame

1.1创建一个画图板的面板类DrawBoard1
1.2创建窗体方法,用来实现窗体化
/***************************窗体函数*******************************************/public void setFrameParams(){//设置窗体jfDrawFrame = new JFrame("小安画图板");jfDrawFrame.setSize(600, 400);//窗体大小 jfDrawFrame.setLocationRelativeTo(null);//窗体位置//设置窗体默认关闭操作jfDrawFrame.setDefaultCloseOperation(3);//设置流式布局jfDrawFrame.setLayout(new BorderLayout());}
1.3创建构造方法,调用其他面板类

2.创建左边面板PanelLeft

2.1创建PanelLeft类,继承JPanel类
2.2根据左边面板图片添加按钮jbutton
                                        
// 添加jbutton 添加图片String a[]={"star","dot_rect","eraser","fill","color_picker","magnifier","pencil","brush","airbrush","word","line","curve","rect","polygon","oval","round_rect"};               for(int i=0;i<16;i++){ImageIcon imageIcon = new ImageIcon("images/"+a[i]+".jpg");JButton btnIcon = new JButton(imageIcon);//设置按键的大小Dimension preferredSize = new Dimension(24,24);btnIcon.setPreferredSize(preferredSize);this.add(btnIcon);//把按键添加到面板// 2.给按钮添加监听btnIcon.addActionListener(actionListener);//// 3.给触发按钮设置一个命令btnIcon.setActionCommand(a[i]);//      }
2.3给按钮添加监听

3.创建中间面板PanelCenter

3.1给中间面板添加监听器
画笔Graphics2D
a.在按下监听获取他们的起始坐标
public void mousePressed(MouseEvent e) {System.out.println("按下了");//获取起始坐标xStart=e.getX();yStart=e.getY();}
b.在释放监听获取他们的终点坐标
直线、椭圆、矩形、圆角矩形、多边形(多边形第一条线是在释放的时候完成的,后面的要在点击事件中完成)都是在释放监听下完成的
public void mouseReleased(MouseEvent e) {System.out.println("释放了");//获取终点坐标xEnd=e.getX();yEnd=e.getY();//画if ("line".equals(p.currentCommon)) // 区分 直线 还是椭圆??? 通过命令区分{// 当前是画直线graphics.drawLine(xStart, yStart, xEnd, yEnd);} else if ("oval".equals(p.currentCommon)) {//当前画椭圆// 反着画 : xStart>xEnd width<0// x较小的 y较小的 :绝对值:xEnd - xStartgraphics.drawOval(Math.min(xStart,xEnd),Math.min(yStart,yEnd), Math.abs(xEnd - xStart),Math.abs(yEnd- yStart));}else if("rect".equals(p.currentCommon)){//当前画矩形graphics.drawRect(Math.min(xStart,xEnd),Math.min(yStart,yEnd), Math.abs(xEnd - xStart),Math.abs(yEnd- yStart));}else if("round_rect".equals(p.currentCommon)){//当前画圆角矩形graphics.drawRoundRect(Math.min(xStart,xEnd), Math.min(yStart,yEnd), Math.abs(xEnd - xStart), Math.abs(yEnd- yStart), 10, 10);}else if("polygon".equals(p.currentCommon)){//当前画多边形if(p.exeCount==0){//记录当前首条直线起始点recordxStart=xStart;recordyStart=yStart;//记录当前首条直线终点    recordxEnd=xEnd;recordyEnd=yEnd;    graphics.drawLine(xStart, yStart, xEnd, yEnd);    p.exeCount++;}}}
c.尤其注意多边形,在释放监听时,它需要记录起始坐标和终点坐标,利用exeCount来判断释放和点击;在点击中,每单击一次就获取当前点击左边并且都要替换记录   终点坐标,双击时首尾相连,把exeCount初始化
public void mouseClicked(MouseEvent e) {int xClick=e.getX();int yClick=e.getY();System.out.println("点击了");int clickCount = e.getClickCount();if("polygon".equals(p.currentCommon)){if(clickCount==1){//当前坐标与记录终点坐标相连graphics.drawLine(recordxEnd,recordyEnd,xClick, yClick);recordxEnd=xClick;recordyEnd=yClick;}else if(clickCount==2){//首位相连graphics.drawLine(recordxEnd,recordyEnd,xClick, yClick);graphics.drawLine(recordxStart,recordyStart,xClick, yClick);p.exeCount=0;}}}
3.2添加鼠标拖动监听器
铅笔、喷枪、橡皮擦、刷子都是在拖动监听下实现的
//添加鼠标拖动监听器MouseMotionListener mouseMotionListener=new MouseMotionListener(){@Overridepublic void mouseDragged(MouseEvent e) {System.out.println("拖动了");x1=e.getX();y1=e.getY();if("pencil".equals(p.currentCommon)){//铅笔graphics.drawLine(xStart, yStart, x1, y1);xStart=x1;yStart=y1;}else if("airbrush".equals(p.currentCommon)){//喷枪for (int i = 0; i < 120; i++) {// 生成的随机数random=new Random();int nextInt = random.nextInt(8) - 4;int nextInt2 = random.nextInt(8) - 4;System.out.println(nextInt);graphics.drawLine(x1 + nextInt, y1 + nextInt2, x1+ nextInt, y1 + nextInt2);// 画点}} else if("eraser".equals(p.currentCommon)) {//橡皮擦    BasicStroke basicStock2=new BasicStroke(30);graphics.setStroke(basicStock2);graphics.setColor(Color.white);graphics.drawLine(xStart, yStart,x1, y1);     xStart=x1;     yStart=y1;    basicStock2=new BasicStroke();graphics.setStroke(basicStock2);         }else if("brush".equals(p.currentCommon)) {    //刷子BasicStroke basicStock1=new BasicStroke(10);graphics.setStroke(basicStock1);graphics.drawLine(xStart, yStart, x1, y1);    xStart=x1;    yStart=y1;    basicStock1=new BasicStroke();graphics.setStroke(basicStock1);    }}@Overridepublic void mouseMoved(MouseEvent e) {}};

4.底部面板PanelBottom

4.1为面添加颜色JButton
Color[] colors = { Color.red, Color.black, Color.blue, Color.yellow ,Color.white};/** 面板上面添加默认颜色的Button **/// 1 默认颜色的数组for (int i = 0; i < colors.length; i++) {// 2创建ButtonJButton button = new JButton();button.setBackground(colors[i]);Dimension dd = new Dimension(25, 25);button.setPreferredSize(dd);button.addActionListener(listener);button.setActionCommand(i + "");// 3.添加this.add(button);}
4.2创建按钮的点击事件
ActionListener listener = new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {System.out.println("颜色选择了~~");String actionCommand = e.getActionCommand();int i = Integer.valueOf(actionCommand);// String -> int// :Integer整数System.out.println("cwt"+i);Color color = colors[i];graphics.setColor(color);p.currentColor = color;if("eraser".equals(p.currentCommon)){graphics.setColor(Color.white);}}};

源代码:

package lza_Draw2;import java.awt.BorderLayout;import java.awt.Graphics2D;import javax.swing.JFrame;public class DrawBoard1 {JFrame jfDrawFrame;//定义画图板窗体的全局变量public DrawBoard1() {setFrameParams();//左边面板PanelLeft pLeft =new PanelLeft(null);jfDrawFrame.add(pLeft, BorderLayout.WEST);//把面板添加到窗体里//中间面板PanelCenter pCenter =new PanelCenter(pLeft,null);jfDrawFrame.add(pCenter, BorderLayout.CENTER);//把面板添加到窗体里//底部面板PanelBottom pBottom =new PanelBottom(pLeft,null);jfDrawFrame.add(pBottom, BorderLayout.SOUTH);jfDrawFrame.setAlwaysOnTop(true);jfDrawFrame.setVisible(true);// 必须在获得画笔:Graphics2D graphics2 = (Graphics2D) pCenter.getGraphics();// 获得画笔// TODO 要给左边面板的g赋值pLeft.graphics = graphics2;pCenter.graphics = graphics2;pBottom.graphics = graphics2;}/***************************窗体函数*******************************************/public void setFrameParams(){//设置窗体jfDrawFrame = new JFrame("小安画图板");jfDrawFrame.setSize(600, 400);//窗体大小jfDrawFrame.setLocationRelativeTo(null);//窗体位置//设置窗体默认关闭操作jfDrawFrame.setDefaultCloseOperation(3);//设置流式布局jfDrawFrame.setLayout(new BorderLayout());}}
package lza_Draw2;import java.awt.Color;import java.awt.Dimension;import java.awt.Graphics2D;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import javax.swing.ImageIcon;import javax.swing.JButton;import javax.swing.JPanel;public class PanelLeft extends JPanel{private static final long serialVersionUID = 1L;public String currentCommon = "line";// 默认一开始就是直线public Graphics2D graphics = null;// 画笔public int exeCount;//用来判断画多边形时,拖动时的操作还是点击时的操作,当execount==0则执行拖动时的操作,不为0则跳出去public Color currentColor =Color.black;//记录初始颜色public PanelLeft(Graphics2D g){graphics=g;//设置左边面板容器Dimension dSizie = new Dimension(70, 100); //Dimension 类封装单个对象中组件的宽度和高度(精确到整数)this.setPreferredSize(dSizie);//设置此组件的首选大小。如果 preferredSize 为 null,则要求 UI 提供首选大小。this.setBackground(Color.lightGray);//设置面板的背景颜色// 添加jbutton 添加图片String a[]={"star","dot_rect","eraser","fill","color_picker","magnifier","pencil","brush","airbrush","word","line","curve","rect","polygon","oval","round_rect"};// 1.先要有监听器 :一个类implements ActionListener ;;// 接口不能new,有一个普通类,没有类名-》匿名类 =>匿名内部类ActionListener actionListener = new ActionListener() {// 重写了接口的抽象方法@Overridepublic void actionPerformed(ActionEvent e) {System.out.println("监听到了~~~");// 区分是哪个按钮?currentCommon = e.getActionCommand();// 获得当前触发按钮的命令graphics.setColor(currentColor);exeCount=0;}};for(int i=0;i<16;i++){ImageIcon imageIcon = new ImageIcon("images/"+a[i]+".jpg");JButton btnIcon = new JButton(imageIcon);//设置按键的大小Dimension preferredSize = new Dimension(24,24);btnIcon.setPreferredSize(preferredSize);this.add(btnIcon);//把按键添加到面板// 2.给按钮添加监听btnIcon.addActionListener(actionListener);//// 3.给触发按钮设置一个命令btnIcon.setActionCommand(a[i]);//}}}
package lza_Draw2;import java.awt.BasicStroke;import java.awt.Color;import java.awt.Graphics2D;import java.awt.event.MouseEvent;import java.awt.event.MouseListener;import java.awt.event.MouseMotionListener;import java.util.Random;import javax.swing.JPanel;public class PanelCenter extends JPanel{private static final long serialVersionUID = 1L;public PanelLeft pleft;public Graphics2D graphics;// 画笔//定义全局坐标变量public int xStart ;//X起始点public int yStart ;//Y的起始点public int xEnd ;//X的终点public int yEnd ;//Y的终点public int recordxStart;//记录起始点x的值public int recordyStart;//记录起始点y的值public int recordxEnd;//记录终点x的值public int recordyEnd;//记录终点y的值public int x1, y1;//拖动时的坐标public Random random;//定义随机数类的全局对象public PanelCenter(PanelLeft p,Graphics2D g){pleft=p;graphics=g;//给中间面板添加监听器MouseListener mouseListener = new MouseListener(){@Overridepublic void mouseClicked(MouseEvent e) {int xClick=e.getX();int yClick=e.getY();System.out.println("点击了");int clickCount = e.getClickCount();if("polygon".equals(p.currentCommon)){if(clickCount==1){//当前坐标与记录终点坐标相连graphics.drawLine(recordxEnd,recordyEnd,xClick, yClick);recordxEnd=xClick;recordyEnd=yClick;}else if(clickCount==2){//首位相连graphics.drawLine(recordxEnd,recordyEnd,xClick, yClick);graphics.drawLine(recordxStart,recordyStart,xClick, yClick);p.exeCount=0;}}}@Overridepublic void mouseEntered(MouseEvent e) {System.out.println("进入了");}@Overridepublic void mouseExited(MouseEvent e) {System.out.println("退出了");}@Overridepublic void mousePressed(MouseEvent e) {System.out.println("按下了");//获取起始坐标xStart=e.getX();yStart=e.getY();}@Overridepublic void mouseReleased(MouseEvent e) {System.out.println("释放了");//获取终点坐标xEnd=e.getX();yEnd=e.getY();//画if ("line".equals(p.currentCommon)) // 区分 直线 还是椭圆??? 通过命令区分{// 当前是画直线graphics.drawLine(xStart, yStart, xEnd, yEnd);} else if ("oval".equals(p.currentCommon)) {//当前画椭圆// 反着画 : xStart>xEnd width<0// x较小的 y较小的 :绝对值:xEnd - xStartgraphics.drawOval(Math.min(xStart,xEnd),Math.min(yStart,yEnd), Math.abs(xEnd - xStart),Math.abs(yEnd- yStart));}else if("rect".equals(p.currentCommon)){//当前画矩形graphics.drawRect(Math.min(xStart,xEnd),Math.min(yStart,yEnd), Math.abs(xEnd - xStart),Math.abs(yEnd- yStart));}else if("round_rect".equals(p.currentCommon)){//当前画圆角矩形graphics.drawRoundRect(Math.min(xStart,xEnd), Math.min(yStart,yEnd), Math.abs(xEnd - xStart), Math.abs(yEnd- yStart), 10, 10);}else if("polygon".equals(p.currentCommon)){//当前画多边形if(p.exeCount==0){//记录当前首条直线起始点recordxStart=xStart;recordyStart=yStart;//记录当前首条直线终点    recordxEnd=xEnd;recordyEnd=yEnd;    graphics.drawLine(xStart, yStart, xEnd, yEnd);    p.exeCount++;}}}};//添加鼠标拖动监听器MouseMotionListener mouseMotionListener=new MouseMotionListener(){@Overridepublic void mouseDragged(MouseEvent e) {System.out.println("拖动了");x1=e.getX();y1=e.getY();if("pencil".equals(p.currentCommon)){//铅笔graphics.drawLine(xStart, yStart, x1, y1);xStart=x1;yStart=y1;}else if("airbrush".equals(p.currentCommon)){//喷枪for (int i = 0; i < 120; i++) {// 生成的随机数random=new Random();int nextInt = random.nextInt(8) - 4;int nextInt2 = random.nextInt(8) - 4;System.out.println(nextInt);graphics.drawLine(x1 + nextInt, y1 + nextInt2, x1+ nextInt, y1 + nextInt2);// 画点}} else if("eraser".equals(p.currentCommon)) {//橡皮擦    BasicStroke basicStock2=new BasicStroke(30);graphics.setStroke(basicStock2);graphics.setColor(Color.white);graphics.drawLine(xStart, yStart,x1, y1);     xStart=x1;     yStart=y1;    basicStock2=new BasicStroke();graphics.setStroke(basicStock2);         }else if("brush".equals(p.currentCommon)) {    //刷子BasicStroke basicStock1=new BasicStroke(10);graphics.setStroke(basicStock1);graphics.drawLine(xStart, yStart, x1, y1);    xStart=x1;    yStart=y1;    basicStock1=new BasicStroke();graphics.setStroke(basicStock1);    }}@Overridepublic void mouseMoved(MouseEvent e) {}};this.setBackground(Color.white);// 2.给panel添加监听器this.addMouseListener(mouseListener);this.addMouseMotionListener(mouseMotionListener);}}
package lza_Draw2;import java.awt.Color;import java.awt.Dimension;import java.awt.Graphics2D;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import javax.swing.JButton;import javax.swing.JPanel;public class PanelBottom extends JPanel{private static final long serialVersionUID = 533562196214049835L;public PanelLeft panelLeft;public Graphics2D graphics;// 1 默认颜色的数组Color[] colors = { Color.red, Color.black, Color.blue, Color.yellow ,Color.white};public PanelBottom(PanelLeft p,Graphics2D g){panelLeft=p;graphics=g;Dimension d = new Dimension(100, 70);this.setPreferredSize(d);/** 创建按钮的点击事件 **/ActionListener listener = new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {System.out.println("颜色选择了~~");String actionCommand = e.getActionCommand();int i = Integer.valueOf(actionCommand);// String -> int// :Integer整数System.out.println("cwt"+i);Color color = colors[i];graphics.setColor(color);p.currentColor = color;if("eraser".equals(p.currentCommon)){graphics.setColor(Color.white);}}};/** 面板上面添加默认颜色的Button **/// 1 默认颜色的数组for (int i = 0; i < colors.length; i++) {// 2创建ButtonJButton button = new JButton();button.setBackground(colors[i]);Dimension dd = new Dimension(25, 25);button.setPreferredSize(dd);button.addActionListener(listener);button.setActionCommand(i + "");// 3.添加this.add(button);}}}

测试类:

package lza_Draw2;public class Test {public static void main(String[] args) {DrawBoard1 drawBoard1 =new DrawBoard1 ();}}
为了解决放大窗体时,所画的东西不被清除掉利用队列(用泛化数组)来记录所画的东西。
package lza_Draw2;import java.awt.Graphics2D;public class Queue<T> {private int size;private Object []queue=new Object[size];public int getSize(){return size;}//添加public void add(T element){Object []queue_new=new Object[size+1];for(int i=0;i<size;i++){queue_new[i]=queue[i];}queue_new[size]=element;queue=queue_new;size++;}//删除public void delete(int index){Object []queue_new=new Object[size-1];for(int i=0;i<index;i++){queue_new[i]=queue[i];}for(int i=index;i<size-1;i++){queue_new[i]=queue[i+1];}queue=queue_new;size--;}//修改public void update(int index,T element){queue[index] =element ;}//插入public void insert(int index,T element){Object []queue_new=new Object[size+1];for(int i=0;i<index;i++){queue_new[i]=queue[i];}queue_new[index]=element;for(int i=index;i<size;i++){queue_new[i+1]=queue[i];}queue=queue_new;size++;}//查询public T inquire(int a){return (T) queue[a];}}
创建一个重绘的一个抽象父类,构造方法记录它们的坐标和颜色、宽度,重绘图像的方法
package lza_Draw2;import java.awt.Color;import java.awt.Graphics2D;import java.awt.Stroke;public abstract class Shape {public int x1,y1,x2,y2;public Color color;public Stroke stroke;public Shape(int x1,int y1,int x2,int y2,Color color,Stroke stroke){this.x1=x1;this.y1=y1;this.x2=x2;this.y2=y2;this.color=color;this.stroke=stroke;}public abstract void drawShape(Graphics2D g);}
在中间画板处创建重绘方法
public void paint(Graphics g) {super.paint(g);System.out.println("~");for(int i=0;i<queue.getSize();i++){ queue.inquire(i).drawShape((Graphics2D)g);}}
创建直线、椭圆、矩形、圆角矩形的重绘子类,继承Shape
列举直线的重绘代码,其他的都是大同小异
package lza_Draw2;import java.awt.Color;import java.awt.Graphics2D;import java.awt.Stroke;public class LineShape extends Shape{public LineShape(int x1, int y1, int x2, int y2, Color color, Stroke stroke) {super(x1, y1, x2, y2, color, stroke);}@Overridepublic void drawShape(Graphics2D g) {g.setColor(color);g.setStroke(stroke);g.drawLine(x1, y1, x2, y2);}}
在中间面板中分别在他们的画中添加如下代码即可以
queue.add(new OvalShape(x1,y1,x2,y2, graphics.getColor(), new BasicStroke(1)));
比如直线:
if ("line".equals(p.currentCommon)) // 区分 直线 还是椭圆??? 通过命令区分{// 当前是画直线graphics.drawLine(xStart, yStart, xEnd, yEnd);//TODOLineShape line = new LineShape(xStart, yStart, xEnd, yEnd, graphics.getColor(), new BasicStroke(1));queue.add(line);}
其运行结果截图:







0 0