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

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 - xStart
					graphics.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(){

			@Override
			public 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);
			    }
			}

			@Override
			public 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创建Button
			JButton 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() {
			@Override
			public 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() {
					// 重写了接口的抽象方法
					@Override
				public 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(){
			@Override
			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;
				}
			}
		}

			@Override
			public void mouseEntered(MouseEvent e) {
				System.out.println("进入了");
			}

			@Override
			public void mouseExited(MouseEvent e) {
				System.out.println("退出了");
				
			}

			@Override
			public void mousePressed(MouseEvent e) {
				System.out.println("按下了");
				//获取起始坐标
				xStart=e.getX();
				yStart=e.getY();
				
			}

			@Override
			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 - xStart
					graphics.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(){

			@Override
			public 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);
			    }
			}

			@Override
			public 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() {
			@Override
			public 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创建Button
			JButton 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);
	}

	@Override
	public 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);
					//TODO
					LineShape line = new LineShape(xStart, yStart, xEnd, yEnd, graphics.getColor(), new BasicStroke(1));
					queue.add(line);
				}
其运行结果截图:







  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值