这学期学习了设计模式这门课,老湿讲了9个设计模式,期末要求我们运用设计模式做一个小画板。 现在和大家分享一下这个小作业的代码,也顺便作为复习,接下来可能还会写关于每个设计模式的总结与心得。 实现这个小画板首先参考了网上的一些关于java画图的代码。具体实现了画直线、三角形、圆形,图形的组合和解除组合、改变颜色,图形的移动功能。
先来看一下所有的类。 1、单例工厂: 2、面板包含两个类:MainFrame窗口类,用于SWING界面的布局与监听器的设置。DrawingBoard是画板类继承了JPanel类。 3、迭代器:用于组合对象的遍历。 4、图形:包括具体图形类,组合图形类,抽象图形类。 因为重点是设计模式,所以画图的具体实现会一带而过。 1、首先是简单工厂模式的代码: 工厂接口 package 单例工厂;import java.awt.Color;import java.awt.Stroke;import 图形.AbstractShape;//工厂接口interface ShapeFactory { public AbstractShape createShape(Color color, Stroke stroke, int i, int j);} 具体工厂(以CircleFactory为例) 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 图形.AbstractShape;public interface AbstractIterator {public void next();public boolean hasNext();public AbstractShape get();} package 迭代器;import java.util.ArrayList;import java.util.List;public interface AbstractProductList {List<Object> list=new ArrayList<Object>();public AbstractIterator createIterator();} package 迭代器;import java.util.ArrayList;import java.util.List;import 图形.AbstractShape;public class ComponentIterator implements AbstractIterator {private List<AbstractShape> list;int i=0; public ComponentIterator(ArrayList<AbstractShape> list){ this.list=list; } @Override public void next() { i++; } @Override public boolean hasNext() { if(i<list.size()){ return true; } return false; } @Override public AbstractShape get() { // TODO Auto-generated method stub return list.get(i); }} 画板类 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 }}主窗口类 package 面板;import java.awt.BorderLayout;import java.awt.Color;import java.awt.Cursor;import java.awt.GridLayout;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.util.ArrayList;import javax.swing.JButton;import javax.swing.JFrame;import javax.swing.JPanel;import 图形.AbstractShape;import 图形.ComponentShape;public class MainFrame extends JFrame { private JButton linebutton;//画线按钮 private JButton rectbutton;//矩形按钮 private JButton circlebutton;//圆形按钮 private JButton movebutton;// 移动按钮 private JButton combutton;// 组合按钮 private JButton decombutton;// 解除组合按钮 private JButton clearbutton;//清除按钮 private JButton redbutton; private JButton bluebutton; private JButton greenbutton; private JPanel topPanel;// 用于放置顶部button的面板 private JPanel bottomPanel;// 用于放置底部button的面板 private DrawingBoard boardPanel;// 画板的面板 private ComponentShape comshapes;//一个组合图形的类成员变量。 private JPanel middlePanel;//中间的面板 private JPanel colorPanel;//颜色面板 public MainFrame(String label) { super(label); // 初始化部件 linebutton = new JButton('直线'); rectbutton = new JButton('矩形'); circlebutton = new JButton('圆形'); movebutton = new JButton('移动'); combutton = new JButton('组合'); decombutton = new JButton('解除组合'); clearbutton = new JButton('清除'); redbutton=new JButton('红色');redbutton.setForeground(Color.red); bluebutton=new JButton('蓝色');bluebutton.setForeground(Color.blue); greenbutton=new JButton('绿色');greenbutton.setForeground(Color.green); topPanel = new JPanel(); bottomPanel = new JPanel(); boardPanel = new DrawingBoard(); middlePanel=new JPanel(); colorPanel=new JPanel(); //给button添加监听器 linebutton.addActionListener(new ActionListener(){ @Override public void actionPerformed(ActionEvent arg0) { // TODO Auto-generated method stub boardPanel.setTool(0); } }); rectbutton.addActionListener(new ActionListener(){ @Override public void actionPerformed(ActionEvent arg0) { // TODO Auto-generated method stub boardPanel.setTool(1); } }); circlebutton.addActionListener(new ActionListener(){ @Override public void actionPerformed(ActionEvent arg0) { // TODO Auto-generated method stub boardPanel.setTool(2); } }); movebutton.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent arg0) { boardPanel.changeMoveTag(); } }); combutton.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent arg0) { comshapes=new ComponentShape(Color.black, null, 0, 0) ; //System.out.println(boardPanel.getShapeList().size()); comshapes.setList(boardPanel.getShapeList());//将组合对象的内容设为当前画板中的内容。 System.out.println(boardPanel.getShapeList().size()); boardPanel.add(comshapes);//将组合对象添加到画板中(首先清除画板中原有对象)。 System.out.println(boardPanel.getShapeList().size()); boardPanel.comTag=1; //System.out.println(boardPanel.getShapeList().size()); } }); decombutton.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent arg0) { System.out.println(boardPanel.getShapeList().size()); boardPanel.setList(comshapes.desolve()); boardPanel.comTag=0; System.out.println(boardPanel.getShapeList().size()); } }); clearbutton.addActionListener(new ActionListener(){ @Override public void actionPerformed(ActionEvent arg0) { // TODO Auto-generated method stub boardPanel.clearBoard(); } }); redbutton.addActionListener(new ActionListener(){ @Override public void actionPerformed(ActionEvent arg0) { // TODO Auto-generated method stub boardPanel.setForeground(Color.red); } }); bluebutton.addActionListener(new ActionListener(){ @Override public void actionPerformed(ActionEvent arg0) { // TODO Auto-generated method stub boardPanel.setForeground(Color.blue); } }); greenbutton.addActionListener(new ActionListener(){ @Override public void actionPerformed(ActionEvent arg0) { // TODO Auto-generated method stub boardPanel.setForeground(Color.green); } }); // 设置关闭方式 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 设置部件布局 topPanel.setLayout(new GridLayout(1, 4)); bottomPanel.setLayout(new GridLayout(1, 3)); middlePanel.setLayout(new BorderLayout()); // 设置窗口布局 setLayout(new BorderLayout()); // 向面板中添加button topPanel.add(linebutton); topPanel.add(rectbutton); topPanel.add(circlebutton); topPanel.add(clearbutton); bottomPanel.add(movebutton); bottomPanel.add(combutton); bottomPanel.add(decombutton); colorPanel.setLayout(new GridLayout(1,3)); colorPanel.add(redbutton); colorPanel.add(bluebutton); colorPanel.add(greenbutton); middlePanel.add(colorPanel,BorderLayout.NORTH); middlePanel.add(boardPanel,BorderLayout.CENTER); add(topPanel, BorderLayout.NORTH); add(middlePanel, BorderLayout.CENTER); add(bottomPanel, BorderLayout.SOUTH); setSize(500, 500); } public static void main(String args[]) { /*Locale.setDefault(Locale.US); EventQueue.invokeLater(new Runnable() { public void run() { AppFrame f = new AppFrame('画板'); f.setVisible(true); } });*/ MainFrame f = new MainFrame('画板'); f.setVisible(true); }}
|
|