这学期学习了设计模式这门课,老湿讲了9个设计模式,期末要求我们运用设计模式做一个小画板。
现在和大家分享一下这个小作业的代码,也顺便作为复习,接下来可能还会写关于每个设计模式的总结与心得。
实现这个小画板首先参考了网上的一些关于java画图的代码。具体实现了画直线、三角形、圆形,图形的组合和解除组合、改变颜色,图形的移动功能。
先来看一下所有的类。
1、单例工厂:
2、面板包含两个类:MainFrame窗口类,用于SWING界面的布局与监听器的设置。DrawingBoard是画板类继承了JPanel类。
3、迭代器:用于组合对象的遍历。
4、图形:包括具体图形类,组合图形类,抽象图形类。
因为重点是设计模式,所以画图的具体实现会一带而过。
1、首先是简单工厂模式的代码:
工厂接口
package 单例工厂;import java.awt.Color;import java.awt.Stroke;import 图形.AbstractShape;import 图形.Circle;//具体 圆形工厂public class CircleFactory implements ShapeFactory { private static CircleFactory cf = null; private CircleFactory(){ } public static CircleFactory getInstance() { if (cf == null) { cf = new CircleFactory(); } return cf; } @Override public AbstractShape createShape(Color color, Stroke stroke, int i, int j) { // TODO Auto-generated method stub return new Circle(color, stroke, i, j); }}//可以看到CircleFactory还被定义为了一个单例类。
以下为 迭代器的代码,用于遍历组合对象
package 迭代器;import java.util.ArrayList;import java.util.List;public interface AbstractProductList {List<Object> list=new ArrayList<Object>();public AbstractIterator createIterator();}
画板类
package 面板;import java.awt.BasicStroke;import java.awt.Color;import java.awt.Cursor;import java.awt.Graphics;import java.awt.Graphics2D;import java.awt.Stroke;import java.awt.event.MouseEvent;import java.awt.event.MouseListener;import java.awt.event.MouseMotionListener;import java.util.ArrayList;import javax.swing.JPanel;import 单例工厂.CircleFactory;import 单例工厂.LineFactory;import 单例工厂.RectFactory;import 图形.AbstractShape;import 图形.Circle;import 图形.Line;import 图形.Rect;//画板类,该类继承了JPanel,实现了MouseListener,MouseMotionListener接口public class DrawingBoard extends JPanel implements MouseListener, MouseMotionListener { // 定义常量 public static final int TOOL_LINE = 0; public static final int TOOL_RECT = 1; public static final int TOOL_CIRCLE = 2; private int startMoveX, startMoveY, endMoveX, endMoveY;// 用于记录鼠标移动产生的两个坐标。 public int comTag = 0;// 组合标签,用于判断当前是否处于组合模式下:组合模式下shapes中只有一个对象。(并且组合实现拖动方式的方式有些不同) private AbstractShape moveShape;// 保存当前移动对象。 private int tool;// 定义tool变量,用于指示当前使用的工具。取值为上述常量 public int moveTag = 0;// 标记是否处于移动模式。0不是,1是 private Stroke stroke;// 定义笔画类型。 private ArrayList<AbstractShape> shapes;// 定义一个容器,用于存储当前画板中要绘制的图形,然后遍历进行绘制。 private AbstractShape currentShape;// 定义当前要操作(即将被加入shapes)的图形。类型为基类类型AbstractShape private CircleFactory cfactory=CircleFactory.getInstance(); private LineFactory lfactory=LineFactory.getInstance(); private RectFactory rfactory=RectFactory.getInstance(); // 构造函数,进行一些初始化。 public DrawingBoard() { shapes = new ArrayList<AbstractShape>(); tool = 0; stroke = new BasicStroke(3.0F);// 初始化的笔画粗细。(待以后使用装饰模式)。 currentShape = null; setCursor(new Cursor(1));// 设置光标类型 setOpaque(true);// 设置为不透明 setForeground(Color.black);// 设置前景色 setBackground(Color.white); // 设置背景色 // 添加监听器。 addMouseListener(this); addMouseMotionListener(this); } public void changeMoveTag() { if (moveTag == 0) { moveTag = 1; setCursor(new Cursor(Cursor.DEFAULT_CURSOR)); return; } moveTag = 0; setCursor(new Cursor(1)); } //清除画板---- public void clearBoard() { shapes.clear();// 清除shapes repaint();// 重画panel } public ArrayList<AbstractShape> getShapeList() { return shapes; } // 用于实现组合!!!! public void add(AbstractShape s) { shapes.clear(); shapes.add(s); // System.out.println('重画'); repaint(); } public void setList(ArrayList<AbstractShape> s) { shapes.clear(); shapes.addAll(s); repaint(); } // 设置图形的方法 public void setTool(int i) { tool = i; } // paintComponent方法,当调用paint()时被调用。 protected void paintComponent(Graphics g) { super.paintComponent(g); int i = shapes.size(); Graphics2D graphics2d = (Graphics2D) g; // 通过遍历shapes对象,将当前画板索要呈现的图形全部绘制出来。 for (int j = 0; j < i; j++) {// 调用了图形对象相应的draw()方法。 ((AbstractShape) shapes.get(j)).draw(graphics2d); } } // // 鼠标点击事件。 @Override public void mousePressed(MouseEvent e) { if (moveTag == 0) { if (e.getButton() == 1) {// 如果是鼠标左键点击按钮的话。 switch (tool) { case 0: currentShape =lfactory.createShape(getForeground(), stroke, e.getX(), e.getY()); break; case 1: currentShape = rfactory.createShape(getForeground(), stroke, e.getX(), e.getY()); break; case 2: currentShape = cfactory.createShape(getForeground(), stroke, e.getX(), e.getY()); break; } shapes.add(currentShape); repaint(); } else if (e.getButton() == 3 && currentShape != null) {// 如果只是鼠标滑动的话。 currentShape.process(e, 0); repaint(); } } else { if (comTag == 0) { for (int i = 0; i < shapes.size(); i++) { if (shapes.get(i).isSelected(e)) { moveShape = shapes.get(i); moveShape.processMove(e, 0); break; } } } else if (comTag == 1) { shapes.get(0).processMove(e, 0); System.out.println(shapes.get(0)); } } } // 鼠标拖动事件。因为拖动是一个连续的过程,所以这个函数不断地被执行,图形也不断地被重画。 public void mouseDragged(MouseEvent e) { if (moveTag == 0) { if (currentShape != null) { currentShape.process(e, 2);// 为2时设置结束坐标(终点) repaint(); } } else if (comTag ==0) { if (moveShape != null) { moveShape.processMove(e, 1);//为2时设置结束坐标(终点) repaint(); } } else if (comTag== 1) { shapes.get(0).processMove(e, 1); repaint(); } } // 鼠标释放事件。 public void mouseReleased(MouseEvent e) { if (moveTag == 0) { if (e.getButton() == 1 && currentShape != null) { currentShape.process(e, 1);// 1表示不做任何操作返回。 currentShape = null;// 当前图形置为空。 repaint(); } else { if (moveShape != null) { moveShape.processMove(e, 1);// 为2时设置结束坐标(终点) repaint(); } } } } // --------------------------华丽丽的分割线----以下为空实现的方法---------------- @Override public void mouseMoved(MouseEvent e) { // TODO Auto-generated method stub } @Override public void mouseClicked(MouseEvent arg0) { // TODO Auto-generated method stub } @Override public void mouseEntered(MouseEvent arg0) { // TODO Auto-generated method stub } @Override public void mouseExited(MouseEvent arg0) { // TODO Auto-generated method stub }}主窗口类
联系客服