绘图小工具-工厂模式设计

  工厂模式:不提供一个统一的工厂类来创建所有的对象,而是针对不同的对象提供不同的工厂,每个对象都有一个与之对应的工厂 。

  绘图小工具类图:

使用工厂模式降低了类之间的耦合,可以方便地增删绘图的功能。

功能包括:画方、画圆、画折线、画曲线、绘制中和绘制后有颜色差异。

主框架:

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();
    }
}

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: [email protected]
 * 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);
    }
}

DrawCanvas

图形抽象类:

import java.awt.*;
/**
 * Author: Z&J
 * E-mail: [email protected]
 * 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);
}

Shape

工厂抽象类:

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: [email protected]
 * 版本: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);
}

ShapeFactory

图形类具体实现:

import java.awt.*;
/**
 * Author:Z&J
 * E-mail: [email protected]
 * 版本: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);
    }
}

Draw

工厂类具体实现:

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: [email protected]
 * 版本: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);
    }
}

Factory

原文地址:https://www.cnblogs.com/ZJdiem/p/11601037.html

时间: 2024-10-11 03:27:11

绘图小工具-工厂模式设计的相关文章

JavaScript高级---工厂模式设计

1 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> 2 <html> 3 <head> 4 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 5 <ti

关于工厂模式设计的思考

1.什么是工厂模式 工厂模式是我们最常用的实例化对象模式了,是用工厂方法代替new操作的一种模式,相当于创建实例化对象的new. 2.工厂模式的用处 工厂模式主要是为了创建对象提供过渡接口,将创建对象的具体过程隔离开来,达到提高灵活行的目的. 3.工厂模式介绍 意图:定义一个创建对象的接口,让其子类自己决定实例化哪一个工厂类,工厂模式使其创建过程延迟到子类进行. 主要解决:主要解决接口选择的问题. 何时使用:我们明确地计划不同条件下创建不同实例时. 如何解决:让其子类实现工厂接口,返回的也是一个

arcgis api for js 4.4 绘图小工具

目前在4.x API中还未有官方的绘图工具,而实际项目中又需要这样的绘图工具,所以自己写了一个.  奉上代码. 使用方法:1.将引入的API模块传入构造函数 var drawTools = new DrawTools(view, Graphic, Point, Polyline, Polygon, Circle);2.定义好相应的symbol后 调用draw方法开始绘制 drawTools.draw("polygon",polygonSymbol,function(graphic){

设计模式_创建型模式_简单工厂模式_案例

使用简单工厂模式设计一个可以创建不同几何形状(如圆形.方形和三角形等)的绘图工具, 每个几何图形都具有绘制draw()和擦除erase()两个方法, 要求在绘制不支持的几何图形时,提示一个UnSupportedShapeException. 结构图如下: AbstractDrawTools  所有绘图工具的基类,是个抽象工厂类,抽取了三个绘图工具的共有方法Draw() Erase()当成抽象方法 这里简化了工厂类,把工厂类中的创建对象的静态方法移植到这个类中. CaspuleTool  胶囊绘图

JAVA设计模式(01):创建型-工厂模式【工厂方法模式】(Factory Method)

简单工厂模式尽管简单,但存在一个非常严重的问题.当系统中须要引入新产品时,因为静态工厂方法通过所传入參数的不同来创建不同的产品,这必然要改动工厂类的源码,将违背"开闭原则".怎样实现添加新产品而不影响已有代码?工厂方法模式应运而生,本文将介绍另外一种工厂模式--工厂方法模式. 1 日志记录器的设计 Sunny软件公司欲开发一个系统执行日志记录器(Logger).该记录器能够通过多种途径保存系统的执行日志,如通过文件记录或数据库记录,用户能够通过改动配置文件灵活地更换日志记录方式. 在设

简单工厂模式(设计模式入门)

学习正式的设计模式前,先来个开胃菜,即简单工厂模式.下面将利用简单工厂模式设计一个计算器小程序: 一.运算基类(Operation) 1 public abstract class Operation 2 { 3 public double NumA { set; get; } 4 public double NumB { set; get; } 5 public virtual double GetResult() 6 { 7 return 0; 8 } 9 } 二.运算方法(+.-) 1 p

23种设计模式(2)-简单工厂模式

这些设计模式都是在这么多年的软件开发中,先辈对软件重构的经验总结提炼的结果,这些设计模式要遵循软件设计的六原则.每一种设计模式都有相应的需求场景的.有了这些设计模式的思想和面向对象的思想,在软件设计特定的需求中会给你解决思路. 一,需求场景 在此,我也借用书上看到的一个例子.计算器工厂给我们留了一些任务,设计一个计算器做成成品卖给买家.但是这个任务是分两个阶段让我们实现的.如下: 阶段一:买家目前只需要计算器具有加减程序的功能即可.别的功能待市场需求再做设计.也就是阶段二的任务. 阶段二:阶段一

二、设计模式总览及工厂模式详解

二.架构师内功心法之设计模式 2.架构师内功心法之设计模式 2.1.课程目标 1.通过对本章内容的学习,了解设计模式的由来. 2.介绍设计模式能帮我们解决哪些问题. 3.剖析工厂模式的历史由来及应用场景. 2.2.内容定位 不用设计模式并非不可以,但是用好设计模式能帮助我们更好地解决实际问题,设计模式最重要的 是解耦.设计模式天天都在用,但自己却无感知.我们把设计模式作为一个专题,主要是学习设计模式 是如何总结经验的,把经验为自己所用.学设计模式也是锻炼将业务需求转换技术实现的一种非常有效 的方

java设计模式--简单工厂模式

 简单工厂设计模式 工厂模式就是专门负责将大量有共同接口的类实例化,而且不必事先知道每次是要实例化哪一个类的模式.它定义一个用于创建对象的接口,由子类决定实例化哪一个类. 核心知识点如下: (1) 大量共同定义的接口. (2) 由不同的对象去实现该接口. (3) 子类(具体工厂类)决定实例化哪一个类(具体产品类)有着“一对一”的关系. 前言(也算是工厂的一个应用需求场景吧) 最近在构建自动化测试平台,公司需求是:必须在IE,火狐,Google浏览器下回归测试用例.Selenium的webdriv