绘图小工具-工厂模式设计
Posted zjdiem
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了绘图小工具-工厂模式设计相关的知识,希望对你有一定的参考价值。
工厂模式:不提供一个统一的工厂类来创建所有的对象,而是针对不同的对象提供不同的工厂,每个对象都有一个与之对应的工厂 。
绘图小工具类图:
使用工厂模式降低了类之间的耦合,可以方便地增删绘图的功能。
功能包括:画方、画圆、画折线、画曲线、绘制中和绘制后有颜色差异。
主框架:
import JavaDraw.factory.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.*; public class DrawJFrame extends JFrame implements ActionListener { protected JComboBox<Integer> combox_size;//线条宽度组合框 private JRadioButton radio[]; //单选按钮数组 private DrawCanvas canvas; private String[] s; public DrawJFrame() { super("画图小工具!!!"); this.setSize(1200,900); this.setLocationRelativeTo(null); this.setDefaultCloseOperation(EXIT_ON_CLOSE); JToolBar toolbar=new JToolBar(); //工具栏,默认水平方向 this.getContentPane().add(toolbar, "North");//工具栏添加到框架北 JLabel lable=new JLabel("粗细"); toolbar.add(lable); Integer sizes[]= {1,2,3,4,5,6,}; //画线大小 this.combox_size= new JComboBox<>(sizes); this.combox_size.setMaximumSize(new Dimension(50, 30)); this.combox_size.setEditable(true); //设置组合框可编辑 this.combox_size.addActionListener(this); toolbar.add(this.combox_size); toolbar.addSeparator(new Dimension(50, 30)); s= new String[]{"直线", "矩形", "圆", "曲线","三角形"}; //单选按钮数组 ButtonGroup bgroup=new ButtonGroup(); this.radio=new JRadioButton[s.length]; for(int i=0;i<s.length;i++) { this.radio[i]=new JRadioButton(s[i]); this.radio[i].addActionListener(this); bgroup.add(this.radio[i]); toolbar.add(this.radio[i]); } this.radio[0].setSelected(true); toolbar.addSeparator(new Dimension(50, 30)); JButton color_button=new JButton("选择颜色");//颜色按钮 JButton eraser_button=new JButton("橡皮檫"); JButton new_button=new JButton("新建"); color_button.addActionListener(this); eraser_button.addActionListener(this); new_button.addActionListener(this); toolbar.add(color_button); toolbar.addSeparator(new Dimension(60, 30)); toolbar.add(eraser_button); toolbar.addSeparator(new Dimension(60, 30)); toolbar.add(new_button); this.canvas=new DrawCanvas(); canvas.setFactory(new LineFactory(canvas)); this.getContentPane().add(canvas); this.setVisible(true); } @Override public void actionPerformed(ActionEvent ae) { if(ae.getSource() instanceof JComboBox<?>) { try { Object obj=this.combox_size.getSelectedItem();//获取输入值 if(obj instanceof Integer) canvas.size=((Integer)obj).intValue(); }catch(NumberFormatException e) { JOptionPane.showMessageDialog(this, """+ this.combox_size.getSelectedItem() +"" 不能转换成整数,请重新输入!"); } } if(ae.getActionCommand().equals("选择颜色")) canvas.color=JColorChooser.showDialog(this, "选择颜色", Color.BLACK); if(ae.getActionCommand().equals("新建")) { this.dispose(); new DrawJFrame(); } if(ae.getActionCommand().equals("橡皮檫")) canvas.setFactory(new EraserFactory(canvas)); if(ae.getActionCommand().equals("直线")) canvas.setFactory(new LineFactory(canvas)); if(ae.getActionCommand().equals("曲线")) canvas.setFactory(new CurveFactory(canvas)); if(ae.getActionCommand().equals("矩形")) canvas.setFactory(new RectFactory(canvas)); if(ae.getActionCommand().equals("圆")) canvas.setFactory(new OvalFactory(canvas)); if(ae.getActionCommand().equals("三角形")) canvas.setFactory(new TriangleFactory(canvas)); } public static void main(String[] args) { new DrawJFrame(); } }
import JavaDraw.draw.Shape; import JavaDraw.factory.ShapeFactory; import javax.swing.*; import java.awt.*; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.event.MouseMotionListener; import java.util.ArrayList; import java.util.List; /** * Author: Z&J * E-mail: 320647879@qq.com * Time: 2018/12/2 16:11 * 类描述-Description: * * */ public class DrawCanvas extends JComponent implements MouseMotionListener,MouseListener { public int size; public Color color; public Point start,end; Shape shape; ShapeFactory sf; public List<JavaDraw.draw.Shape> list=new ArrayList<>();//容器类 public DrawCanvas() { start=end=null; this.size=3; this.color=Color.black; this.addMouseMotionListener(this); this.addMouseListener(this); } @Override public void mousePressed(MouseEvent e) { sf.mousePressed(e);//调用ShapeFactory对象的mousePressed()方法,具体画什么由其子类实现 } @Override public void mouseReleased(MouseEvent e) //鼠标释放 { sf.mouseReleased(e); } @Override public void mouseDragged(MouseEvent e) { sf.mouseDragged(e); } @Override public void mouseClicked(MouseEvent e){} //单击鼠标 @Override public void mouseEntered(MouseEvent e){} //鼠标进入 @Override public void mouseExited(MouseEvent e){} //鼠标离开 @Override public void mouseMoved(MouseEvent e){} //移动鼠标,实现MouseMotionListener接口 //通过函数传参的形式将shape和工厂对象传入canvas中 public void setShape(JavaDraw.draw.Shape shape) { this.shape=shape; } public void setFactory(ShapeFactory sf) { this.sf=sf; } public void paint(Graphics g) { Graphics2D g2 = (Graphics2D)g;//Graphics2D才能设置画笔粗细。 for(Shape d: list) { if(d!=null) d.draw(g2);//每次更新时,会清空画布,所以把list中的图形全部重绘一遍 } if(shape!=null) shape.draw(g2);//绘图 } public void update(Graphics g) { paint(g); } }
图形抽象类:
import java.awt.*; /** * Author: Z&J * E-mail: 320647879@qq.com * Time: 2018/12/1 0:37 * 类描述-Description: * * */ public abstract class Shape { Point start,end; public Color color; public int size; public Shape(Point start, Point end, Color color,int size) { this.start = start; this.end = end; this.color = color; this.size = size; } public abstract void draw(Graphics2D g); }
工厂抽象类:
import JavaDraw.DrawCanvas; import java.awt.*; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.event.MouseMotionListener; /** * Author:Z&J * E-mail: 320647879@qq.com * 版本:1.0 * 创建日期:2019年09月20日 20:52 * 类描述-Description: */ public abstract class ShapeFactory implements MouseListener, MouseMotionListener { DrawCanvas canvas; public ShapeFactory(DrawCanvas canvas) { this.canvas = canvas; } @Override public abstract void mouseClicked(MouseEvent e); @Override public abstract void mouseEntered(MouseEvent e); @Override public abstract void mouseExited(MouseEvent e); @Override public abstract void mouseMoved(MouseEvent e); @Override public abstract void mousePressed(MouseEvent e); @Override public abstract void mouseDragged(MouseEvent e); @Override public abstract void mouseReleased(MouseEvent e); public abstract void setProduct(Color color); }
图形类具体实现:
import java.awt.*; /** * Author:Z&J * E-mail: 320647879@qq.com * 版本:1.0 * 创建日期:2019年09月17日 1:03 * 类描述-Description: */ public class DrawLine extends Shape { public DrawLine(Point start, Point end, Color color, int size) { super(start, end, color, size); } public void draw(Graphics2D g) { g.setStroke(new BasicStroke(size));//设置画笔粗细 g.setColor(color); g.drawLine(start.x, start.y, end.x, end.y); } } public class DrawOval extends Shape { public DrawOval(Point start, Point end, Color color, int size) { super(start, end, color, size); } @Override public void draw(Graphics2D g) { g.setStroke(new BasicStroke(size));//设置画笔粗细 g.setColor(color); g.drawOval(start.x, start.y, Math.abs(end.x-start.x), Math.abs(end.y-start.y)); } } public class DrawRect extends Shape { public DrawRect(Point start, Point end, Color color, int size) { super(start, end, color, size); } @Override public void draw(Graphics2D g) { g.setStroke(new BasicStroke(size));//设置画笔粗细 g.setColor(color); g.drawRect(start.x, start.y, Math.abs(end.x-start.x), Math.abs(end.y-start.y)); } } public class DrawTriangle extends Shape { public DrawTriangle(Point start, Point end, Color color, int size) { super(start, end, color, size); } @Override public void draw(Graphics2D g) { g.setStroke(new BasicStroke(size)); g.setColor(color); g.drawLine(start.x,start.y,end.x,end.y); g.drawLine(start.x,start.y,2*start.x-end.x,end.y); g.drawLine(2*start.x-end.x,end.y,end.x,end.y); } }
工厂类具体实现:
package JavaDraw.factory; import JavaDraw.DrawCanvas; import JavaDraw.draw.DrawLine; import java.awt.*; import java.awt.event.MouseEvent; import java.util.ArrayList; import java.util.List; /** * Author:Z&J * E-mail: 320647879@qq.com * 版本:5.0 * 创建日期:2019年09月22日 12:00 * 类描述-Description:工厂模式,每生产一个对象,先创建一个生产该对象的工厂。 */ public class CurveFactory extends ShapeFactory { DrawLine line; private List<DrawLine> temp=new ArrayList<>(); public CurveFactory(DrawCanvas canvas) { super(canvas); } @Override public void mousePressed(MouseEvent e) { canvas.start=e.getPoint(); } @Override public void mouseReleased(MouseEvent e) { canvas.end=e.getPoint(); for (DrawLine curve:temp) { curve.color=canvas.color; canvas.setShape(curve); } canvas.repaint(); temp.clear(); } @Override public void mouseDragged(MouseEvent e) { canvas.end=e.getPoint(); this.setProduct(Color.lightGray);//鼠标每次一移动,就生成一个新的产品 canvas.repaint();//更新画布 canvas.list.add(line);//由于是画曲线,所以需要把鼠标移动的时候产生的对象放到容器里去 temp.add(line);//用一个临时容器保存画的点,在鼠标释放的时候好重绘该曲线 canvas.start=canvas.end;//不断更新开始的点,才能画出曲线 } @Override public void setProduct(Color color)//生产具体的产品 { line=new DrawLine(canvas.start,canvas.end,color,canvas.size); canvas.setShape(line);//告诉画布要画什么图形 } } public class EraserFactory extends ShapeFactory { DrawLine eraser; public EraserFactory(DrawCanvas canvas) { super(canvas); } @Override public void mousePressed(MouseEvent e) { canvas.start=e.getPoint(); } @Override public void mouseDragged(MouseEvent e) { canvas.end=e.getPoint(); this.setProduct(canvas.getBackground()); canvas.repaint(); canvas.list.add(eraser); canvas.start=canvas.end; } @Override public void mouseReleased(MouseEvent e) { canvas.end=e.getPoint(); canvas.repaint(); } @Override public void setProduct(Color color) { eraser=new DrawLine(canvas.start,canvas.end, color,canvas.size); canvas.setShape(eraser); } } public class LineFactory extends ShapeFactory { DrawLine line; public LineFactory(DrawCanvas canvas) { super(canvas); } @Override public void mousePressed(MouseEvent e) { canvas.start=e.getPoint();//记录点击鼠标的坐标 } @Override public void mouseDragged(MouseEvent e) { canvas.end=e.getPoint();//鼠标移动的坐标 this.setProduct(Color.lightGray);//鼠标移动时,画出具体的图形 canvas.repaint();//canvas对象更新 } @Override public void mouseReleased(MouseEvent e) { canvas.end=e.getPoint();//鼠标释放时的坐标 this.setProduct(canvas.color); canvas.repaint(); canvas.list.add(line);//将绘出的图形放到canvas的容器中 } @Override public void setProduct(Color color)//生产具体的产品 { line=new DrawLine(canvas.start,canvas.end, color,canvas.size); canvas.setShape(line);//将line对象传回canvas画布中绘图。 } } public class OvalFactory extends ShapeFactory { DrawOval oval; public OvalFactory(DrawCanvas canvas) { super(canvas); } @Override public void mouseDragged(MouseEvent e) { canvas.end=e.getPoint(); this.setProduct(Color.lightGray); canvas.repaint(); } @Override public void mouseReleased(MouseEvent e) { canvas.end=e.getPoint(); this.setProduct(canvas.color); canvas.repaint(); canvas.list.add(oval); } @Override public void setProduct(Color color) { oval=new DrawOval(canvas.start,canvas.end,color,canvas.size); canvas.setShape(oval); } } public class RectFactory extends ShapeFactory { DrawRect rect; public RectFactory(DrawCanvas canvas) { super(canvas); } @Override public void mousePressed(MouseEvent e) { canvas.start=e.getPoint(); } @Override public void mouseDragged(MouseEvent e) { canvas.end=e.getPoint(); this.setProduct(Color.lightGray); canvas.repaint(); } @Override public void mouseReleased(MouseEvent e) { canvas.end=e.getPoint(); this.setProduct(canvas.color); canvas.repaint(); canvas.list.add(rect); } @Override public void setProduct(Color color) { rect=new DrawRect(canvas.start,canvas.end,color,canvas.size); canvas.setShape(rect); } } public class TriangleFactory extends ShapeFactory { DrawTriangle triangle; public TriangleFactory(DrawCanvas canvas) { super(canvas); } @Override public void mousePressed(MouseEvent e) { canvas.start=e.getPoint();//记录点击鼠标的坐标 } @Override public void mouseDragged(MouseEvent e) { canvas.end=e.getPoint();//鼠标移动的坐标 this.setProduct(Color.lightGray);//鼠标移动时,画出具体的图形 canvas.repaint();//canvas对象更新 } @Override public void mouseReleased(MouseEvent e) { canvas.end=e.getPoint();//鼠标释放时的坐标 this.setProduct(canvas.color); canvas.repaint(); canvas.list.add(triangle);//将绘出的图形放到canvas的容器中 } @Override public void setProduct(Color color)//生产具体的产品 { triangle=new DrawTriangle(canvas.start,canvas.end, color,canvas.size); canvas.setShape(triangle); } }
以上是关于绘图小工具-工厂模式设计的主要内容,如果未能解决你的问题,请参考以下文章