粤嵌学习打卡第5天(GUI制作绘画板项目)

今天我们使用GUI来做一个绘画板小项目
本次项目使用mvc设计,整体框架如下所设计
在这里插入图片描述

一、view层

1.1 创建主界面类 MainView.java

/**
 * 绘画板显示界面
 * @author LinChi
 *
 */

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Graphics;

import javax.swing.BorderFactory;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JToggleButton;
import javax.swing.JToolBar;

import controller.ColorBtnLis;
import controller.OpenBtnLis;
import controller.PainterBoardLis;
import controller.ShapeBtnLis;
import model.ShapeEnum;
import util.ImageUtil;

public class MainView extends JFrame{
	//工具条
	private JToolBar jtb;
	//工具栏按钮
	//形状按钮
	private JToggleButton shapeBtns[];
	//颜色按钮
	private JToggleButton colorBtns[];
	//定义颜色
	private static final Color[] COLORS = {Color.BLACK,Color.RED,Color.GREEN,Color.BLUE,Color.WHITE,Color.GRAY};
	//操作按钮
	private JButton saveBtn;
	private JButton openBtn;
	//填充按钮
	private JToggleButton fillBtn;
	//画布
	private PainterBoard painter;
	//状态栏
	private JPanel typeBar;
	//标签
	private ShapeLabel shapeLab;
	private ColorLabel colorLab;
	//当前形状
	private ShapeEnum nowShape = ShapeEnum.values()[0];
	//当前颜色
	private Color nowColor = COLORS[0];
	//橡皮擦半径
	private int eraserRadio = 5;
	public MainView() {
		super("绘画板");
		this.setSize(500,400);
		this.setLocationRelativeTo(null);
		//添加工具栏组件
		addJToolBar();
		//添加状态栏
		addTypeBar();
		//添加画布
		addPainter();
		//添加事件
		addLinstener();
		this.setVisible(true);
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	}
	/**
	 * 添加画布
	 */
	private void addPainter() {
		this.painter = new PainterBoard();
		//添加到窗口的中部
		this.add(this.painter);
	}
	/**
	 * 添加监听器
	 */
	private void addLinstener() {
		//形状监听器
		//创建监听器对象
		ShapeBtnLis shapeBtnLis = new ShapeBtnLis(this);
		for(JToggleButton shapeLis:this.shapeBtns) {
			shapeLis.addItemListener(shapeBtnLis);
		}
		//颜色监听器
		ColorBtnLis colorBtnLis = new ColorBtnLis(this);
		for(JToggleButton colorLis:this.colorBtns) {
			colorLis.addItemListener(colorBtnLis);
		}
		//画布监听器
		PainterBoardLis pbs = new PainterBoardLis(this);
		//添加鼠标触摸事件
		this.painter.addMouseListener(pbs);
		//添加鼠标拖拽事件
		this.painter.addMouseMotionListener(pbs);
		//添加保存打开操作监听
		OpenBtnLis openLis = new OpenBtnLis(this);
		this.saveBtn.addActionListener(openLis);
		this.openBtn.addActionListener(openLis);
		this.fillBtn.addActionListener(openLis);
	}
	/**
	 * 状态栏组件
	 */
	private void addTypeBar() {
		//构造状态栏  使用流式布局管理器
		typeBar = new JPanel(new FlowLayout(FlowLayout.LEFT,10,5));
		//设置边界
		typeBar.setBorder(BorderFactory.createEtchedBorder());
		//添加标签
		JLabel shapeInFoLab = new JLabel("当前形状:");
		typeBar.add(shapeInFoLab);
		//构造形状
		this.shapeLab = new ShapeLabel(ShapeEnum.SPACE,nowShape);
		typeBar.add(shapeLab);
		
		JLabel colorInFoLab = new JLabel("当前颜色:");
		typeBar.add(colorInFoLab);
		this.colorLab = new ColorLabel(ShapeEnum.SPACE,nowColor);
		typeBar.add(this.colorLab);
		//添加到南部
		this.add(typeBar,BorderLayout.SOUTH);
	}
	/**
	 * 工具栏组件
	 */
	private void addJToolBar() {
		//构造工具栏按钮
		jtb = new JToolBar();
		//设置按钮数组值
		ShapeEnum[] btnShapeArryays = ShapeEnum.values();
		//定义按钮组
		ButtonGroup shapeBtnsGrop = new ButtonGroup();
		//构造形状按钮
		shapeBtns = new JToggleButton[btnShapeArryays.length];
		//循环构造按钮
		for(int i = 0;i<shapeBtns.length;i++) {
			shapeBtns[i] = new PainterToggleButton(btnShapeArryays[i]);
			//将按钮添加到组
			shapeBtnsGrop.add(shapeBtns[i]);
			//将按钮添加到工具栏
			jtb.add(shapeBtns[i]);
		}
		//设定线为默认图形
		shapeBtns[0].setSelected(true);
		//添加工具栏分割
		jtb.addSeparator();
		//定义颜色按钮组
		ButtonGroup colorsBtnGrop = new ButtonGroup();
		//构造颜色按钮
		colorBtns = new JToggleButton[COLORS.length];
		//循环创建按钮
		for(int i = 0;i<colorBtns.length;i++) {
			//构造按钮,使用矩形填充
			colorBtns[i] = new PainterToggleButton(ShapeEnum.ELLIPSE,COLORS[i]);
			//将按钮添加到按钮组
			colorsBtnGrop.add(colorBtns[i]);
			//将按钮添加到工具栏
			jtb.add(colorBtns[i]);
		}
		//设定黑色为默认颜色
		colorBtns[0].setSelected(true);
		//添加工具栏的分割
		jtb.addSeparator();
		
		//添加填充状态按钮
		fillBtn = new JToggleButton("绘制") {
			@Override
			public void paint(Graphics g) {
				// TODO Auto-generated method stub
				super.paint(g);
			}
		};
		jtb.add(fillBtn);
		
		//添加工具栏的分割
		jtb.addSeparator();
		
		//添加保存按钮
		saveBtn = new JButton(ShapeEnum.SPACE) {
			@Override
			public void paint(Graphics g) {
				//调用Jbutton的paint方法,绘制按钮默认的外观
				super.paint(g);
				//绘制图形
				g.drawImage(ImageUtil.getImageByLocalFilePath("images/save.png"), 5, 5, 20, 20,null);
			}
		};
		//将保存按钮添加到工具栏
		jtb.add(saveBtn);
		
		//添加打开按钮
		openBtn = new JButton(ShapeEnum.SPACE) {
			@Override
			public void paint(Graphics g) {
			//调用Jbutton的paint方法,绘制按钮默认的外观
			super.paint(g);
			//绘制图形
			g.drawImage(ImageUtil.getImageByLocalFilePath("images/open.png"), 5, 5, 25, 25,null);
		}
		};
		//将保存按钮添加到工具栏
		jtb.add(openBtn);
		
		//将工具栏添加到面板的北部
		this.add(jtb,BorderLayout.NORTH);
	}
	public JToolBar getJtb() {
		return jtb;
	}
	public void setJtb(JToolBar jtb) {
		this.jtb = jtb;
	}
	public JToggleButton[] getShapeBtns() {
		return shapeBtns;
	}
	public void setShapeBtns(JToggleButton[] shapeBtns) {
		this.shapeBtns = shapeBtns;
	}
	public JToggleButton[] getColorBtns() {
		return colorBtns;
	}
	public void setColorBtns(JToggleButton[] colorBtns) {
		this.colorBtns = colorBtns;
	}
	public JButton getSaveBtn() {
		return saveBtn;
	}
	public void setSaveBtn(JButton saveBtn) {
		this.saveBtn = saveBtn;
	}
	public JButton getOpenBtn() {
		return openBtn;
	}
	public void setOpenBtn(JButton openBtn) {
		this.openBtn = openBtn;
	}
	
	public PainterBoard getPainter() {
		return painter;
	}
	public void setPainter(PainterBoard painter) {
		this.painter = painter;
	}
	public JPanel getTypeBar() {
		return typeBar;
	}
	public void setTypeBar(JPanel typeBar) {
		this.typeBar = typeBar;
	}
	
	public ShapeLabel getShapeLab() {
		return shapeLab;
	}
	public void setShapeLab(ShapeLabel shapeLab) {
		this.shapeLab = shapeLab;
	}
	public ColorLabel getColorLab() {
		return colorLab;
	}
	public void setColorLab(ColorLabel colorLab) {
		this.colorLab = colorLab;
	}
	public ShapeEnum getNowShape() {
		return nowShape;
	}
	public void setNowShape(ShapeEnum nowShape) {
		this.nowShape = nowShape;
	}
	public Color getNowColor() {
		return nowColor;
	}
	public void setNowColor(Color nowColor) {
		this.nowColor = nowColor;
	}
	public int getEraserRadio() {
		return eraserRadio;
	}
	public void setEraserRadio(int eraserRadio) {
		this.eraserRadio = eraserRadio;
	}
	public JToggleButton getFillBtn() {
		return fillBtn;
	}
	public void setFillBtn(JToggleButton fillBtn) {
		this.fillBtn = fillBtn;
	}
	
}

1.2 创建按钮类 PainterToggleButton.java


import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Shape;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Line2D;
import java.awt.geom.Rectangle2D;

import javax.swing.JToggleButton;

import model.ShapeEnum;
import util.ImageUtil;
/**
 * 形状按钮类
 * @author LinChi
 *
 */
public class PainterToggleButton extends JToggleButton{
	//将形状图形枚举类传递进来
	private ShapeEnum shapeEnum;
	//将颜色传递进来
	private Color color;
	public PainterToggleButton(ShapeEnum shapeEnum) {
		super(ShapeEnum.SPACE);
		this.setPreferredSize(new Dimension(ShapeEnum.WIDTH,ShapeEnum.HEIGHT));
		this.shapeEnum = shapeEnum;
	}
	public PainterToggleButton(ShapeEnum shapeEnum,Color color) {
		this(shapeEnum);
		this.color = color;
	}
	
	public ShapeEnum getShapeEnum() {
		return shapeEnum;
	}
	public void setShapeEnum(ShapeEnum shapeEnum) {
		this.shapeEnum = shapeEnum;
	}
	public Color getColor() {
		return color;
	}
	public void setColor(Color color) {
		this.color = color;
	}
	@Override
	public void paint(Graphics g) {
		//调用父类的paint,绘制JToggleButton该有的外观
		super.paint(g);
		//定义2D画笔
		Graphics2D g2 = (Graphics2D)g;
		//定义形状
		Shape shape = null;
		//判断形状 
		if(shapeEnum == ShapeEnum.LINE) {
			shape = new Line2D.Double(ShapeEnum.LINE.getX1(),ShapeEnum.LINE.getY1(),ShapeEnum.LINE.getX2(),ShapeEnum.LINE.getY2());
		}else if(shapeEnum == ShapeEnum.ELLIPSE) {
			shape = new Ellipse2D.Double(ShapeEnum.ELLIPSE.getX1(),ShapeEnum.ELLIPSE.getY1(),ShapeEnum.ELLIPSE.getX2(),ShapeEnum.ELLIPSE.getY2());
		}else if(shapeEnum == ShapeEnum.RECTANGLE) {
			shape = new Rectangle2D.Double(ShapeEnum.RECTANGLE.getX1(),ShapeEnum.RECTANGLE.getY1(),ShapeEnum.RECTANGLE.getX2(),ShapeEnum.RECTANGLE.getY2());
		}else if(shapeEnum == ShapeEnum.ERASER) {
			shape = null;
		}
		//判断是否为空
		if(shape != null) {
			if(this.color != null) {
				g2.setColor(this.color);
				g2.fill(shape);
			}
			//默认黑色描边
			g2.setColor(Color.BLACK);
			//绘画
			g2.draw(shape);
		}else if(shapeEnum == ShapeEnum.ERASER) {
			//橡皮擦图片
			Image eraserImg = ImageUtil.getImageByLocalFilePath("images/eraser.png");
			//绘制橡皮擦图片
			g2.drawImage(eraserImg, 5, 5, 20, 20, null);
			
		}
	}
}

1.3 创建形状标签类 ShapeLabel.java


import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Line2D;
import java.awt.geom.Rectangle2D;

import javax.swing.JLabel;

import model.ShapeEnum;

public class ShapeLabel extends JLabel{
	private ShapeEnum nowShape;

	public ShapeLabel(String lab,ShapeEnum nowShape) {
		super(lab);
		this.nowShape = nowShape;
	}

	public ShapeEnum getNowShape() {
		return nowShape;
	}

	public void setNowShape(ShapeEnum nowShape) {
		this.nowShape = nowShape;
	}
	/**
	 * 标签栏绘制形状
	 */
	public void paint(Graphics g) {
		super.paint(g);
		//构造2D画笔
		Graphics2D g2 = (Graphics2D)g;
		//定义形状
		Shape shape = null;
		if(nowShape == ShapeEnum.LINE) {
			shape = new Line2D.Double(ShapeEnum.LINE.getX1(),ShapeEnum.LINE.getY1(),ShapeEnum.LINE.getX2(),ShapeEnum.LINE.getY2());
		}else if(nowShape == ShapeEnum.ELLIPSE) {
			shape = new Ellipse2D.Double(0,0,16,16);
		}else if(nowShape == ShapeEnum.RECTANGLE) {
			shape = new Rectangle2D.Double(0,0,16,16);
		}
		if(shape != null) {
			g2.draw(shape);
		}
	}
	
}

1.4创建颜色标签类 ColorLabel.java


import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.geom.Rectangle2D;

import javax.swing.JLabel;

import model.ShapeEnum;

public class ColorLabel extends JLabel{
	private Color nowColor;

	public ColorLabel(String lab,Color nowColor) {
		super(lab);
		this.nowColor = nowColor;
	}

	public Color getNowColor() {
		return nowColor;
	}

	public void setNowColor(Color nowColor) {
		this.nowColor = nowColor;
	}
	public void paint(Graphics g) {
		super.paint(g);
		if(nowColor == null) {
			return;
		}
		//构造2D画笔
		Graphics2D g2 = (Graphics2D)g;
		//定义形状
		Shape shape = null;
		shape = new Rectangle2D.Double(ShapeEnum.ELLIPSE.getX1(),ShapeEnum.ELLIPSE.getY1(),ShapeEnum.ELLIPSE.getX2(),ShapeEnum.ELLIPSE.getY2());
		g2.setColor(nowColor);
		g2.fill(shape);
	}
	
}

1.5创建画板类 PainterBoard.java


import java.awt.Graphics;
import java.awt.Graphics2D;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JPanel;

import model.PainterShape;

/**
 * 画板类
 * @author LinChi
 *
 */
public class PainterBoard extends JPanel{
	//传递当前对象
	private PainterShape nowShape;
	private MainView window;
	//记录绘制好的形状
	private List<PainterShape> shapeList = new ArrayList<PainterShape>();
	@Override
	public void paint(Graphics g) {
		super.paint(g);
		//使用背景色清理全画布
		g.clearRect(0, 0, this.getWidth(), this.getHeight());
		//得到2D画笔
		Graphics2D g2 = (Graphics2D)g;
		//绘制以前保存在列表中的图像
		for (PainterShape s : shapeList) {
			PaintPainterShape(g,s);
		}
		if(nowShape != null) {
			PaintPainterShape(g,nowShape);
		}
	}
	/**
	 * 绘制形状
	 * @return
	 */
	private void PaintPainterShape(Graphics g,PainterShape shape) {
		//得到2D画笔
		Graphics2D g2 = (Graphics2D)g;
		//判断空对象
		if(shape == null) {
			return;
		}
		//判断是否是橡皮擦
		if(shape.isEraserFlag()) {
			//将背景色设为当前颜色
			g2.setColor(g2.getBackground());
			g2.fill(shape.getShape());
		}else{
			//不是橡皮擦,绘制图形
			//设置当前颜色
			g2.setColor(shape.getColor());
			//绘画
			g2.draw(shape.getShape());
//			g2.fill(shape.getShape());
		}
	}
	
	public PainterShape getNowShape() {
		return nowShape;
	}
	public void setNowShape(PainterShape nowShape) {
		this.nowShape = nowShape;
	}
	public List<PainterShape> getShapeList() {
		return shapeList;
	}
	public void setShapeList(List<PainterShape> shapeList) {
		this.shapeList = shapeList;
	}
	
}

二、controller层

2.1创建颜色按钮监听器 ColorBtnLis.java

/**
 * 颜色按钮监听器
 * @author LinChi
 *
 */

import java.awt.Color;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;

import view.MainView;
import view.PainterToggleButton;

public class ColorBtnLis implements ItemListener{
	private MainView window;
	
	
	public ColorBtnLis(MainView window) {
		super();
		this.window = window;
	}


	@Override
	public void itemStateChanged(ItemEvent e) {
		//得到引发事件源的对象
		PainterToggleButton colorBtn = (PainterToggleButton)e.getSource();
		//获得当前按钮上的颜色
		Color color = colorBtn.getColor();
		//设置当前选择的颜色为点击按钮的颜色
		window.setNowColor(color);
		//设置状态栏标签的颜色
		window.getColorLab().setNowColor(color);
		//重新绘制图形
		window.getColorLab().repaint();
	}
	
}

2.2创建保存打开监听器 OpenBtnLis.java


import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.util.List;

import javax.swing.JFileChooser;
import javax.swing.JOptionPane;

import common.FileUtil;
import model.PainterShape;
import view.MainView;
import view.PainterBoard;

/**
 * 保存打开监听器
 * @author LinChi
 *
 */
public class OpenBtnLis implements ActionListener{
	private MainView window;
	//定义文件选择器
	private JFileChooser jfc = new JFileChooser();

	public OpenBtnLis(MainView window) {
		super();
		this.window = window;
	}
	@Override
	public void actionPerformed(ActionEvent e) {		
		//判断是否保存按钮触发了事件
		if(e.getSource() == window.getSaveBtn()) {
			//使用文件选择器,弹出保存对话框
			jfc.showSaveDialog(window);
			//获取需要保存的文件
			File selFile = jfc.getSelectedFile();
			//过滤非法操作
			if(selFile == null) {
				return;
			}
			//判断文件是否存在
			if(selFile.exists()) {
				//提示是否覆盖,选择否,退出
				if(JOptionPane.showConfirmDialog(window, "文件已经存在,是否覆盖?","提示",
						JOptionPane.YES_NO_OPTION,JOptionPane.QUESTION_MESSAGE) == JOptionPane.NO_OPTION) {
					return;
				}
			}
			//保存到文件
			boolean flag = FileUtil.saveImg(window.getPainter().getShapeList(), selFile);
			if(!flag) {
				JOptionPane.showMessageDialog(window,"保存失败,系统碰到严重问题,请与程序员联系!","错误",JOptionPane.ERROR_MESSAGE);
			}
		}else if(e.getSource() == window.getOpenBtn()) {
			//提示当前绘画的内容没有保存,是否保存了再打开
			if(window.getPainter().getNowShape() != null || !window.getPainter().getShapeList().isEmpty()) {
				if(JOptionPane.showConfirmDialog(window, "当前已绘制的图片没有保存,是否放弃?","提示",JOptionPane.YES_NO_OPTION,JOptionPane.QUESTION_MESSAGE) == JOptionPane.NO_OPTION) {
					return;
				}
			}
			//弹出打开对话框
			jfc.showOpenDialog(window);
			//选择打开的文件
			File openFile = jfc.getSelectedFile();
			//判断是否没有打开的图片信息
			if(openFile == null) {
				return;
			}
			//判断文件是否存在
			if(!openFile.exists()) {
				JOptionPane.showMessageDialog(window,"文件不存在!","错误",JOptionPane.ERROR_MESSAGE);
				return;
			}
			//读取文件列表
			List<PainterShape> list = FileUtil.readImg(openFile);
			//判断文件是否为null
			if(list == null) {
				JOptionPane.showMessageDialog(window, "不是我们的图片文件","错误",JOptionPane.ERROR_MESSAGE);
				return;
			}
			//清空当前画布信息
			window.getPainter().setNowShape(null);
			window.getPainter().getShapeList().clear();
			//将读取的图片列表设置到画布列表中
			window.getPainter().setShapeList(list);
			//重新绘制
			window.getPainter().repaint();
		}else if(e.getSource() == window.getFillBtn()) {
			if(window.getFillBtn().isSelected()) {
				window.getFillBtn().setText("填充");
			}else {
				window.getFillBtn().setText("绘制");
			}
		}
	}
}

1.3创建画板监听器 PainterBoardLis.java


import java.awt.Shape;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Line2D;
import java.awt.geom.Rectangle2D;

import model.PainterShape;
import model.ShapeEnum;
import view.MainView;

/**
 * 画板监听器
 * @author LinChi
 *
 */
public class PainterBoardLis extends MouseAdapter{
	private MainView window;
	//记录鼠标按下的坐标
	private int mousePressX;
	private int mousePressY;
	
	public PainterBoardLis(MainView window) {
		super();
		this.window = window;
	}

	@Override
	public void mousePressed(MouseEvent e) {
		this.mousePressX = e.getX();
		this.mousePressY = e.getY();
	}

	@Override
	public void mouseDragged(MouseEvent e) {
		//获取鼠标拖拽落下的坐标位置
		int x = e.getX();
		int y = e.getY();
		//获取当前形状
		ShapeEnum shapeEnum = window.getNowShape();
		//定义当前形状
		Shape nowShope = null;
		//判断当先选择的形状
		if(shapeEnum == ShapeEnum.LINE) {
			nowShope = new Line2D.Double(this.mousePressX,this.mousePressY,x,y);
		}else if(shapeEnum == ShapeEnum.ELLIPSE) {
			//计算图形的左上点 (左上点是图形的开始位置)
			int pointX = Math.min(x,this.mousePressX);
			int pointY = Math.min(y, this.mousePressY);
			//计算图形的宽度和高度
			int width = Math.abs(x - this.mousePressX);
			int height = Math.abs(y - this.mousePressY);
			nowShope = new Ellipse2D.Double(pointX,pointY,width,height);
		}else if(shapeEnum == ShapeEnum.RECTANGLE) {
			//计算图形的左上点 (左上点是图形的开始位置)
			int pointX = Math.min(x,this.mousePressX);
			int pointY = Math.min(y, this.mousePressY);
			//计算图形的宽度和高度
			int width = Math.abs(x - this.mousePressX);
			int height = Math.abs(y - this.mousePressY);
			nowShope = new Rectangle2D.Double(pointX,pointY,width,height);
		}else if(shapeEnum == ShapeEnum.ERASER) {
			//设定橡皮擦为圆形
			nowShope = new Ellipse2D.Double(x-window.getEraserRadio(),y-window.getEraserRadio(),window.getEraserRadio() * 2,window.getEraserRadio() * 2);
		}
		if(nowShope == null) {
			return;
		}
		//构造橡皮擦的形状
		PainterShape ps = new PainterShape(nowShope, window.getNowColor());
		//判断是否为橡皮擦,如果是,修改标记
		if( shapeEnum == ShapeEnum.ERASER) {
			//构造橡皮擦
			ps.setEraserFlag(true);
			//记录橡皮擦的形状,实现连续的拖拽擦除
			window.getPainter().getShapeList().add(window.getPainter().getNowShape());
		}
		//将自定义的形状设置到画布的当前形状上
		window.getPainter().setNowShape(ps);
		//调用paint方法绘制刚才设置的形状
		window.getPainter().repaint();
	}

	@Override
	public void mouseReleased(MouseEvent e) {
		//判断是否是橡皮擦
		if(window.getNowShape() == ShapeEnum.ERASER) {
			Shape shape = new Ellipse2D.Double(e.getX()-window.getEraserRadio(),e.getY()-window.getEraserRadio(),window.getEraserRadio() * 2,window.getEraserRadio() * 2);
			PainterShape ps = new PainterShape(shape, window.getNowColor(),true);
			//设置当前形状
			window.getPainter().setNowShape(ps);
		}
		//将画布当前形状记录到当前列表中
		window.getPainter().getShapeList().add(window.getPainter().getNowShape());
		//重绘图形
		window.getPainter().repaint();
	}
	
}

1.4 创建形状监听器 ShapeBtnLis.java


import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;

import model.ShapeEnum;
import view.MainView;
import view.PainterToggleButton;

public class ShapeBtnLis implements ItemListener{
	private MainView window;
	
	public ShapeBtnLis(MainView window) {
		super();
		this.window = window;
	}

	@Override
	public void itemStateChanged(ItemEvent e) {
		//获取事件源对象
		PainterToggleButton shapeBtn = (PainterToggleButton)e.getSource();
		//获取当前的形状
		ShapeEnum shapeEnum = shapeBtn.getShapeEnum();
		//设置当前的形状
		window.setNowShape(shapeEnum);
		//设置状态栏形状
		window.getShapeLab().setNowShape(shapeEnum);
		//重新绘制图形
		window.getShapeLab().repaint();
	}
}

三、model层

3.1创建图形类 PainterShape.java


import java.awt.Color;
import java.awt.Shape;
import java.io.Serializable;

/**
 * 封装选中图形类
 * @author LinChi
 *
 */
public class PainterShape implements Serializable{
	private Shape shape;
	private Color color;
	//是否是橡皮擦
	public boolean eraserFlag;
	public PainterShape(Shape shape, Color color) {
		super();
		this.shape = shape;
		this.color = color;
	}
	public PainterShape(Shape shape, Color color,boolean eraserFlag) {
		this(shape,color);
		this.eraserFlag = eraserFlag;
	}
	public Shape getShape() {
		return shape;
	}
	public void setShape(Shape shape) {
		this.shape = shape;
	}
	public Color getColor() {
		return color;
	}
	public void setColor(Color color) {
		this.color = color;
	}
	public boolean isEraserFlag() {
		return eraserFlag;
	}
	public void setEraserFlag(boolean eraserFlag) {
		this.eraserFlag = eraserFlag;
	}
	
}

3.2 创建枚举类 ShapeEnum.java

/**
 * 形状按钮枚举类
 * @author LinChi
 *
 */
public enum ShapeEnum {
	LINE(5,5,25,25),ELLIPSE(5,5,20,20),RECTANGLE(5,5,20,20),ERASER(0,0,0,0);
	//坐标点
	private double x1,y1;
	//线的终止坐标位置 圆形和矩形的宽和高
	private double x2,y2;
	//定义按钮的宽度和高度
	public static int WIDTH = 30;
	public static int HEIGHT = 30;
	//按钮文本
	public static String SPACE = "      ";
	private ShapeEnum(double x1,double y1,double x2, double y2) {
		this.x1 = x1;
		this.y1 = y1;
		this.x2 = x2;
		this.y2 = y2;
	}
	public double getX1() {
		return x1;
	}
	public void setX1(double x1) {
		this.x1 = x1;
	}
	public double getY1() {
		return y1;
	}
	public void setY1(double y1) {
		this.y1 = y1;
	}
	public double getX2() {
		return x2;
	}
	public void setX2(double x2) {
		this.x2 = x2;
	}
	public double getY2() {
		return y2;
	}
	public void setY2(double y2) {
		this.y2 = y2;
	}
}

4、util工具类

4.1 创建获得图片类 ImageUtil.java


import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.awt.image.RenderedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;

import javax.imageio.ImageIO;

public class ImageUtil {
	
	/**
	 * 鏍规嵁璺緞鍔犺浇鍥剧墖
	 */
	public static Image getImageByLocalFilePath(String path){
		Image result = null;
		FileInputStream fin = null;
		try {
			fin = new FileInputStream(path);
			result = ImageIO.read(fin);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
			return null;
		} catch (IOException e) {
			e.printStackTrace();
			return null;
		} finally{
			if(fin != null){
				try {
					fin.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
		return result;
	}
	
	/**
	 * 鏍规嵁Url璺緞鍔犺浇鍥剧墖
	 */
	public static Image getImageByURLPath(String urlPath){
		Image result = null;
		URL url = null;
		try {
			url = new URL(urlPath);
			result = ImageIO.read(url);
		} catch (MalformedURLException e) {
			e.printStackTrace();
			return null;
		} catch (IOException e) {
			e.printStackTrace();
			return null;
		}
		return result;
	}
	
	/**
	 * 璁惧畾鍥惧儚鐨勫ぇ灏?
	 */
	public static Image getScalImage(Image img, int width, int height){
		//杩囨护闈炴硶
		if( img == null || width == 0 || height == 0){
			System.out.println("ERROR: arguments is falied!");
			return null;
		}
		//鑾峰彇鍥剧墖鐨勯暱銆佸
		int imgWidth = img.getWidth(null);
		int imgHeight = img.getHeight(null);
		double imgK = imgWidth * 1.0 / imgHeight;
		double cusK = width * 1.0 / height;
		//鍑嗗缂╂斁鐨勬瘮渚?
		double scale = 1;
		//瀛樻斁鍥剧墖闇?瑕佺粯鍒剁殑澶у皬
		int imgResultWidht = 0;
		int imgResultHeight = 0;
		//瀛樻斁鍥剧墖缁樺埗鐨勫潗鏍囩偣
		int sx1 = 0;
		int sy1 = 0;
		int sx2 = 0;
		int sy2 = 0;
		if( imgK > cusK ){
			//浠ュ浘鐗囩殑楂樹负鍑?
			imgResultHeight = imgHeight;
			imgResultWidht = (int)(imgResultHeight * cusK);
			//璁$畻鍥剧墖缁樺埗鍧愭爣
			sx1 = (imgWidth - imgResultWidht) / 2;
			sy1 = 0;
			sx2 = sx1 + imgResultWidht;
			sy2 = imgHeight;
		}else{
			//浠ュ浘鐗囩殑瀹戒负鍑?
			imgResultWidht = imgWidth;
			imgResultHeight = (int)(imgResultWidht / cusK);
			//璁$畻鍥剧墖缁樺埗鍧愭爣
			sx1 = 0;
			sy1 = (imgHeight - imgResultHeight) / 2;
			sx2 = imgWidth;
			sy2 = sy1 + imgResultHeight;
		}
		
		//灏嗗浘鐗囩粯鍒跺埌鍥剧墖缂撳啿鍣ㄤ腑
		BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
		//鑾峰彇鍥剧墖缂撳啿鍣ㄧ殑鐢荤瑪
		Graphics g = bi.getGraphics();
		//缁樺埗鍥剧墖鍒扮紦鍐插櫒
		g.drawImage(img, 0, 0, width, height, sx1, sy1, sx2, sy2, null);
		g.dispose();
		
		return bi;
	}
	
	/**
	 * 寰楀埌鍥剧墖鐨刡yte[]
	 */
	public static byte[] getImageBytes(Image img, String formatName){
		//杩囨护闈炴硶
		if(img == null){
			System.out.println("ERROR: img is null");
			return null;
		}
		byte[] result = null;
		//瀹氫箟瀛楄妭鏁扮粍鐨勮緭鍑烘祦
		ByteArrayOutputStream bas = new ByteArrayOutputStream();
		//瀹氫箟BufferedImage
		BufferedImage bi = new BufferedImage(img.getWidth(null), img.getHeight(null), BufferedImage.TYPE_INT_RGB);
		Graphics g = bi.getGraphics();
		g.drawImage(img, 0, 0, null);
		g.dispose();
		try {
			ImageIO.write((RenderedImage)bi, formatName, bas);
			result = bas.toByteArray();
		} catch (IOException e) {
			e.printStackTrace();
			System.out.println("ERROR: IOException "+e.getMessage());
		}
		return result;
	}
	
	/**
	 * 鏍规嵁鍥剧墖鐨刡yte[] 寰楀埌 Image瀵硅薄
	 */
	public static Image getImageByBytes(byte[] bytes){
		if(bytes == null){
			System.out.println("ERROR: bytes is null ");
			return null;
		}
		
		Image result = null;
		
		ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
		try {
			result = ImageIO.read(bis);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return result;
	}

}

4.2创建字符串类 StringUtil.java

/**
 * 越界限制工具类
 * @author LinChi
 *
 */
public class StringUtil {
	public static boolean isEmpty(String str) {
		if(str == null || str.length()<=0 || str.trim().length()<=0) {
			return true;
		}
		return false;
	}
}

五、common公共包

5.1 创建获得文件类 FileUtil.java

/**
 * 锟侥硷拷锟斤拷锟斤拷锟斤拷
 * @author LinChi
 *
 */

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.List;
import java.util.Map;

import model.PainterShape;
import view.PainterBoard;


public class FileUtil {
	private static FileInputStream fin;
	private static FileOutputStream fout;
	private static ObjectInputStream objIn;
	private static ObjectOutputStream objOut;


	/**
	 *保存图片
	 * 
	 * @param acc
	 * @return
	 */
	public static boolean saveImg(List<PainterShape> shapeList,File saveFile) {
		try {
				fout = new FileOutputStream(saveFile);
				objOut = new ObjectOutputStream(fout);
			//灏嗘暣涓猰ap涓繚瀛樼殑杩涘害淇℃伅鍐欏叆鏂囦欢涓?
			objOut.writeObject(shapeList);
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return false;
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return false;
		} finally {
			closeAll();
		}
		return true;
	}

	/**
	 * 读取图片
	 * 
	 * @return
	 */
	public static List<PainterShape> readImg(File loadFile) {
		List<PainterShape> result = null;
		try {
			fin = new FileInputStream(loadFile);
			objIn = new ObjectInputStream(fin);
				result = (List<PainterShape>) objIn.readObject();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
			return null;
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
			return null;
		} catch (IOException e) {
			e.printStackTrace();
			return null;
		} finally {
			closeAll();
		}
		return result;
	}

	/**
	 *鍏抽棴娴?
	 */
	private static void closeAll() {
		try {
			if (objOut != null) {
				objOut.close();
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		try {
			if (fout != null) {
				fout.close();
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		try {
			if (objIn != null) {
				objIn.close();
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		try {
			if (fin != null) {
				fin.close();
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

六、主方法 app.java


import view.MainView;

public class App {
	public static void main(String[] args) {
		new MainView();
	}
}

项目截图:
在这里插入图片描述
在这里插入图片描述


小伙伴们、今天学习的小项目就分享到这了。明天继续加油哦!


发布了17 篇原创文章 · 获赞 3 · 访问量 513

猜你喜欢

转载自blog.csdn.net/qq_41986840/article/details/104449094