--------记录人生第一次博客
ps: 最近在学习设计模式,老师给了实验要求完成,本来随便做完后就准备去干别的事情了,但是看到大佬写的实验后整个人的兴趣就被调动起来了,一番请教后写出比自己原先更好的代码后就有了写博客记录的欲望。
实验要求:1、有如下场景:现有一绘图工具,能够支持圆形、三角形、正方形等的绘图,每个图形都有绘图和擦除两个方法,请结合简单工厂模式实现该工具。
写代码最好先画画图理清楚思路再开始写。
思路:(ps:每个类都是单独的!)
public class MyFrame extends JFrame{
public MyFrame() {
this.setTitle("mydemo");
this.setSize(800, 400);//窗口类宽800px,高400px
this.setVisible(true);//窗口是否开启可视化
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//设置关闭按钮关闭进程
}
}
创建面板类MyPanel,继承JPanel类。再创建创建一个Demo类给出主函数main方法,回到MyFrame类。
在MyFrame类中,创建私有的MyPanel,创建6个JButton按钮,分别是:画圆,删圆,画矩形,删矩形,画三角形,删三角形。 `
public class MyFrame extends JFrame{
private MyPanel panel = new MyPanel();
private JButton c1 = new JButton("画圆");
private JButton c2 = new JButton("删圆");
private JButton r1 = new JButton("画矩形");
private JButton r2 = new JButton("删矩形");
private JButton t1 = new JButton("画三角形");
private JButton t2 = new JButton("删三角形");
public MyFrame() {
this.setTitle("mydemo");
this.setSize(800, 400);//窗口类宽800px,高400px
this.setVisible(true);//窗口是否开启可视化
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//设置关闭按钮关闭进程
c1.setBounds(10, 10, 100, 30);//x轴10px,y轴10px开始,按钮宽100px,高30px
c2.setBounds(120, 10, 100, 30);
r1.setBounds(230, 10, 100, 30);
r2.setBounds(340, 10, 100, 30);
t1.setBounds(450, 10, 100, 30);
t2.setBounds(560, 10, 100, 30);
this.add(c1);
this.add(c2);
this.add(r1);
this.add(r2);
this.add(t1);
this.add(t2);
add(panel);
}
}
运行一下看看效果:
public class Demo {
public static void main(String[] args) {
MyFrame f=new MyFrame();
}
}
public class MyPanel extends JPanel{
public void paint(Graphics g) {//自动执行的函数
g.drawOval(100,150,150,150);//画圆
g.drawRect(300, 150, 150, 150);//画矩形
drawTriangle(g, 500,300,600,150,700,300);//画三角形
}
//画三角形,将三个点连起来
public void drawTriangle(Graphics g,int x1,int y1,int x2,int y2,int x3,int y3)
{
Polygon filledPolygon=new Polygon();
filledPolygon.addPoint(x1,y1);
filledPolygon.addPoint(x2,y2);
filledPolygon.addPoint(x3,y3);
g.drawPolygon(filledPolygon);
}
}
public class Circle {//圆形
int x,y;
int width,height;
public Circle(int x,int y,int width,int height) {//给出起始点,宽高
super();
this.x = x;
this.y = y;
this.width = width;
this.height = height;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
public int getWidth() {
return width;
}
public void setWidth(int width) {
this.width = width;
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
}
public class Rect {//矩形
int x,y,width,height;
public Rect(int x,int y,int width, int height) {
super();
this.x=x;
this.y=y;
this.width=width;
this.height=height;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
public int getWidth() {
return width;
}
public void setWidth(int width) {
this.width = width;
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
}
public class Triangle {//三角形
int x1,y1;//给出三个坐标点
int x2,y2;
int x3,y3;
public Triangle(int x1,int y1,int x2,int y2,int x3,int y3) {
super();
this.x1=x1;
this.y1=y1;
this.x2=x2;
this.y2=y2;
this.x3=x3;
this.y3=y3;
}
public int getX1() {
return x1;
}
public void setX1(int x1) {
this.x1 = x1;
}
public int getY1() {
return y1;
}
public void setY1(int y1) {
this.y1 = y1;
}
public int getX2() {
return x2;
}
public void setX2(int x2) {
this.x2 = x2;
}
public int getY2() {
return y2;
}
public void setY2(int y2) {
this.y2 = y2;
}
public int getX3() {
return x3;
}
public void setX3(int x3) {
this.x3 = x3;
}
public int getY3() {
return y3;
}
public void setY3(int y3) {
this.y3 = y3;
}
}
public class MyPanel extends JPanel{
private Circle circle = null;
private Rect rect =null;
private Triangle triangle=null;
public Circle getCircle() {
return circle;
}
public void setCircle(Circle circle) {
this.circle = circle;
}
public Rect getRect() {
return rect;
}
public void setRect(Rect rect) {
this.rect = rect;
}
public Triangle getTriangle() {
return triangle;
}
public void setTriangle(Triangle triangle) {
this.triangle = triangle;
}
public void paint(Graphics g) {//通过get方法获得各个图形参数
if(circle != null) g.drawOval(circle.getX(), circle.getY(), circle.getWidth(), circle.getHeight());
if(rect != null) g.drawRect(rect.getX(), rect.getY(), rect.getWidth(), rect.getHeight());
if(triangle != null) drawTriangle(g,triangle.getX1(),triangle.getY1(),triangle.getX2(),triangle.getY2(),triangle.getX3(),triangle.getY3());
}
//画三角形,将三个点连起来
public void drawTriangle(Graphics g,int x1,int y1,int x2,int y2,int x3,int y3)
{
Polygon filledPolygon=new Polygon();
filledPolygon.addPoint(x1,y1);
filledPolygon.addPoint(x2,y2);
filledPolygon.addPoint(x3,y3);
g.drawPolygon(filledPolygon);
}
}
然后回到MyFrame类,创建三个类,并给出参数,完善actionPerformed(ActionEvent e)方法。
public class MyFrame extends JFrame implements ActionListener{
private MyPanel panel = new MyPanel();
private JButton c1 = new JButton("画圆");
private JButton c2 = new JButton("删圆");
private JButton r1 = new JButton("画矩形");
private JButton r2 = new JButton("删矩形");
private JButton t1 = new JButton("画三角形");
private JButton t2 = new JButton("删三角形");
private Circle circle = new Circle(100,150,150,150);
private Rect rect = new Rect(300, 150, 150, 150);
private Triangle triangle= new Triangle(500,300,600,150,700,300);
public MyFrame() {
this.setTitle("mydemo");
this.setSize(800, 400);//窗口类宽800px,高400px
this.setVisible(true);//窗口是否开启可视化
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//设置关闭按钮关闭进程
//设定按钮位置以及宽高
c1.setBounds(10, 10, 100, 30);//x轴10px,y轴10px开始,按钮宽100px,高30px
c2.setBounds(120, 10, 100, 30);
r1.setBounds(230, 10, 100, 30);
r2.setBounds(340, 10, 100, 30);
t1.setBounds(450, 10, 100, 30);
t2.setBounds(560, 10, 100, 30);
c1.addActionListener(this);//添加画画监听
r1.addActionListener(this);
t1.addActionListener(this);
c2.addActionListener(this);//添加删除监听
r2.addActionListener(this);
t2.addActionListener(this);
this.add(c1);
this.add(c2);
this.add(r1);
this.add(r2);
this.add(t1);
this.add(t2);
add(panel);
}
@Override
public void actionPerformed(ActionEvent e) {
if(e.getSource() == c1) {panel.setCircle(circle);repaint(); //repaint()方法清空内容}
else if(e.getSource() == c2) {panel.setCircle(null);repaint();}
else if(e.getSource() == r1) {panel.setRect(rect);repaint();}
else if (e.getSource() == r2) {panel.setRect(null);repaint();}
else if (e.getSource() == t1) {panel.setTriangle(triangle);repaint();}
else if (e.getSource() == t2) {panel.setTriangle(null);repaint();}
else {
System.out.println("error");
}
}
}
public class Factory {
public static Circle createCircle(int x,int y,int width,int height) {
return new Circle(x, y, width, height);
}
public static Rect createRect(int x,int y,int width,int height) {
return new Rect(x, y, width, height);
}
public static Triangle createTriangle(int x1,int y1,int x2,int y2,int x3,int y3) {
return new Triangle(x1, y1, x2, y2, x3, y3);
}
public static JButton createJButton(String s) {
return new JButton(s);
}
public static MyFrame createMyFrame() {
return new MyFrame();
}
public static MyPanel createMyPanel() {
return new MyPanel();
}
}
//在MyFrame类中的new操作,调用工厂类帮你创建
private JButton c1 = Factory.createJButton("画圆");
private JButton c2 = Factory.createJButton("删圆");
private JButton r1 = Factory.createJButton("画矩形");
private JButton r2 = Factory.createJButton("删矩形");
private JButton t1 = Factory.createJButton("画三角形");
private JButton t2 = Factory.createJButton("删三角形");
private Circle circle = Factory.createCircle(100,150,150,150);
private Rect rect = Factory.createRect(300, 150, 150, 150);
private Triangle triangle = Factory.createTriangle(500,300,600,150,700,300);
//还有主函数创建的MyFrame f
MyFrame f = Factory.createMyFrame();
完成啦,<( ̄︶ ̄)>
代码其实还能更加简洁,但是懒得继续改了。
此处感谢大佬的帮助 https://blog.csdn.net/qq_39852560
如有不足,请各位大佬指正!
如果有别的思路也可以在评论区交流。
————————————————————分割线—————————————————
有博主私信说简单工厂模式里的类可以抽象出父类。所以我把代码重构了一下。
更改部分:
重构代码如下:
MyFrame类
public class MyFrame extends JFrame implements ActionListener {
private MyPanel panel = new MyPanel();
private JButton c1 = Factory.createJButton("画圆");
private JButton c2 = Factory.createJButton("删圆");
private JButton r1 = Factory.createJButton("画矩形");
private JButton r2 = Factory.createJButton("删矩形");
private JButton t1 = Factory.createJButton("画三角形");
private JButton t2 = Factory.createJButton("删三角形");
private MyGraph circle = Factory.createGraph("circle", 100, 150, 150, 150);
private MyGraph rect = Factory.createGraph("rect",300, 150, 150, 150);
private MyGraph triangle = Factory.createGraph("triangle",500,150,150,150);
public MyFrame() {
this.setTitle("mydemo");
this.setSize(800, 400);//窗口类宽800px,高400px
this.setVisible(true);//窗口是否开启可视化
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//设置关闭按钮关闭进程
//设定按钮位置以及宽高
c1.setBounds(10, 10, 100, 30);//x轴10px,y轴10px开始,按钮宽100px,高30px
c2.setBounds(120, 10, 100, 30);
r1.setBounds(230, 10, 100, 30);
r2.setBounds(340, 10, 100, 30);
t1.setBounds(450, 10, 100, 30);
t2.setBounds(560, 10, 100, 30);
c1.addActionListener(this);//添加画画监听
r1.addActionListener(this);
t1.addActionListener(this);
c2.addActionListener(this);//添加删除监听
r2.addActionListener(this);
t2.addActionListener(this);
this.add(c1);
this.add(c2);
this.add(r1);
this.add(r2);
this.add(t1);
this.add(t2);
add(panel);
}
@Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == c1) {
panel.setCircle(circle);
repaint();//repaint()方法清空内容
}
else if (e.getSource() == c2) {
panel.setCircle(null);
repaint();
} else if (e.getSource() == r1) {
panel.setRect(rect);
repaint();
} else if (e.getSource() == r2) {
panel.setRect(null);
repaint();
} else if (e.getSource() == t1) {
panel.setTriangle(triangle);
repaint();
} else if (e.getSource() == t2) {
panel.setTriangle(null);
repaint();
} else {
System.out.println("error");
}
}
}
MyPanel类
public class MyPanel extends JPanel {
private MyGraph circle = null;
private MyGraph rect =null;
private MyGraph triangle=null;
public MyGraph getCircle() {
return circle;
}
public void setCircle(MyGraph circle) {
this.circle = circle;
}
public MyGraph getRect() {
return rect;
}
public void setRect(MyGraph rect) {
this.rect = rect;
}
public MyGraph getTriangle() {
return triangle;
}
public void setTriangle(MyGraph triangle) {
this.triangle = triangle;
}
public void paint(Graphics g) {//通过get方法获得各个图形参数
if(circle != null)
g.drawOval(circle.getX(), circle.getY(), circle.getWidth(), circle.getHeight());
if(rect != null)
g.drawRect(rect.getX(), rect.getY(), rect.getWidth(), rect.getHeight());
if(triangle != null)
drawTriangle(g,triangle.getX(),triangle.getY(),triangle.getWidth(), triangle.getHeight());
}
//画三角形,将三个点连起来
public void drawTriangle(Graphics g,int x,int y,int width,int height)
{
Polygon filledPolygon=new Polygon();
filledPolygon.addPoint(x,y); //起点
filledPolygon.addPoint(width/2+x,y+height); //中间点
filledPolygon.addPoint(x+width,y); //结束点
g.drawPolygon(filledPolygon);//画三角形
}
}
父类MyGraph,子类Circle,Rect,Triangle
public abstract class MyGraph {
private int x,y;
private int width,height;
public MyGraph(){}
public MyGraph(int x, int y, int width, int height) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
public int getWidth() {
return width;
}
public void setWidth(int width) {
this.width = width;
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
}
public class Circle extends MyGraph{//圆形
public Circle() {}
public Circle(int x, int y, int width, int height) {
super(x, y, width, height);
}
}
public class Rect extends MyGraph{//矩形
public Rect() {}
public Rect(int x, int y, int width, int height) {super(x, y, width, height);}
}
public class Triangle extends MyGraph{//三角形
public Triangle() {}
public Triangle(int x, int y, int width, int height) {
super(x, y, width, height);
}
}
工厂类Factory
public class Factory {
private static MyGraph myGraph = null;
//通过参数确定图形
public static MyGraph createGraph(String graphName,int startPointX,int startPointY,int width,int height){
switch (graphName){
case "circle":
case "Circle":myGraph = new Circle(startPointX, startPointY, width, height);break;
case "rect":
case "Rect":myGraph = new Rect(startPointX, startPointY, width, height);break;
case "triangle":
case "Triangle": myGraph = new Triangle(startPointX, startPointY, width, height);break;
default:myGraph = null;
}
return myGraph;
}
public static JButton createJButton(String buttonName) {
return new JButton(buttonName);
}
public static MyFrame createMyFrame() {
return new MyFrame();
}
public static MyPanel createMyPanel() {
return new MyPanel();
}
}
运行类Demo
public class Demo {
public static void main(String[] args) {
MyFrame f = Factory.createMyFrame();
}
}
上面代码如果再继续深入考虑的话会发现,还有很多问题。
1.如果是五边形、六边形的话,父类 MyGraph 的 width 和 height 怎么搞?
2.多边形的话工厂类的参数怎么传?四个参数 x,y,width,height 可是直接把图形边数定死了!
3.使用工厂类返回想要的图形类,如果图形名字写错了或者不会写,那不是爆炸?
所以上面的代码只是提供学习使用,真正把它做成一个桌面应用还需要考虑很多的因素。