命令模式--撤銷恢複
原文:https://abstractforever.iteye.com/blog/962219
該例子來自閻宏提供的例子程序,以畫線為例:
命令接口Command:
package com.javapatterns.command.drawlines; //命令接口 public interface Command { abstract public void execute();// 執行操作 abstract public void unexecute();// 取消操作 abstract public boolean canExecute();//是否允許執行操作 abstract public boolean canUnexecute();//是否允許取消操作 }
添加線命令類AddLineCommand:
/* Generated by Together */ package com.javapatterns.command.drawlines; //添加線命令類 public class AddLineCommand implements Command { private Drawing drawing;// 畫布 private Line line;//直線 public AddLineCommand(Drawing targetDrawing, Line newLine) { drawing = targetDrawing; line = newLine; } //執行將直線添加到畫布的操作 public void execute() { drawing.add(line); } //執行將直線從畫布中移除的操作 public void unexecute() { drawing.remove(line); } public boolean canExecute() { return true; } public boolean canUnexecute() { return true; } }
命令集合類CommandList:
package com.javapatterns.command.drawlines; import java.util.Stack; //命令集合類,負責存儲執行過的命令和撤銷執行的命令 public class CommandList { private Stack<Command> executedCommands = new Stack<Command>(); private Stack<Command> unexecutedCommands = new Stack<Command>(); private void _execute(Command command) { command.execute();//執行具體的命令 executedCommands.push(command);//記錄執行的命令 } //執行命令 public void execute(Command command) { unexecutedCommands.removeAllElements(); _execute(command); } //撤銷執行,每執行一次該方法,將從最近的一次操作開始撤銷 public void unexecute() { Command command = (Command) executedCommands.pop();//出棧最後一次執行命令 command.unexecute();//撤銷該命令的執行 unexecutedCommands.push(command);//記錄撤銷的命令 } //恢複執行,每執行一次該方法,將從最近的一次操作開始撤銷 public void reexecute() { Command command = (Command) unexecutedCommands.pop();//出棧最後一次撤銷命令 _execute(command);//重新執行 } //清空撤銷和恢複的緩存 public void reset() { executedCommands.removeAllElements(); unexecutedCommands.removeAllElements(); } //是否允許撤銷命令,沒有執行過命令就不存在撤銷 public boolean canUnexecuteCommand() { return !executedCommands.empty(); } //是否允許恢複命令,沒有撤銷過命令就不存在恢複 public boolean canReexecuteCommand() { return !unexecutedCommands.empty(); } }
畫布Drawing:
/* Generated by Together */ package com.javapatterns.command.drawlines; import java.awt.Canvas; import java.awt.Color; import java.awt.Graphics; import java.awt.Point; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.event.MouseMotionListener; import java.util.Enumeration; import java.util.Vector; //(接收者,負責具體實施和執行一個請求)畫布,可以在該畫布上畫任意條直線 public class Drawing extends Canvas implements MouseListener, MouseMotionListener { private static final long serialVersionUID = -4887753465176351050L; private SimpleDraw applet;//應用程序 private Vector<Line> lines;//線集合 private Point startPosition;//畫線開始位置 private Point mousePosition;//鼠標位置 private boolean mousePressed;//鼠標是否按下 //構造方法,初始化屬性信息 public Drawing(SimpleDraw owner) { applet = owner; lines = new Vector<Line>(); mousePressed = false;//默認鼠標未按下 setBackground(Color.GREEN);//設置畫布背景色 addMouseListener(this);//添加鼠標監聽器,自己實現了該接口 addMouseMotionListener(this);//添加鼠標移動事件的偵聽器,自己實現了該接口 } //添加一條線(行動方法) public void add(Line line) { lines.addElement(line); repaint(); } //刪除一條線(行動方法) public void remove(Line line) { lines.removeElement(line); repaint(); } public void paint(Graphics graphics) { Enumeration<Line> enumeration = lines.elements(); Line currentLine; while (enumeration.hasMoreElements()) { currentLine = (Line) (enumeration.nextElement()); currentLine.paint(graphics); } if (mousePressed) { graphics.drawLine(startPosition.x, startPosition.y, mousePosition.x, mousePosition.y); } } //鼠標按鍵在組件上單擊(按下並釋放)時調用 public void mouseClicked(MouseEvent event) { } //鼠標進入到組件上時調用 public void mouseEntered(MouseEvent event) { } //鼠標離開組件時調用 public void mouseExited(MouseEvent event) { } //鼠標按鍵在組件上按下時調用 public void mousePressed(MouseEvent event) { mousePressed = true;//設置鼠標為按下狀態 startPosition = event.getPoint();//記錄直線的開始位置 } //鼠標按鈕在組件上釋放時調用 public void mouseReleased(MouseEvent event) { if (!event.getPoint().equals(startPosition)) {//兩點不重合 Line line = new Line(startPosition, event.getPoint());//創建直線 AddLineCommand command = new AddLineCommand(this, line);//創建添加直線的一個命令 applet.execute(command);//請求者請求命令的執行 } mousePressed = false; } public void mouseDragged(MouseEvent event) { mousePosition = event.getPoint(); repaint(); } public void mouseMoved(MouseEvent event) { } }
直線Line:
package com.javapatterns.command.drawlines; import java.awt.Point; import java.awt.Graphics; public class Line { private Point start; private Point end; public Line( Point startPos, Point endPos ) { start = startPos; end = endPos; } public void paint( Graphics graphics ) { graphics.drawLine( start.x, start.y, end.x, end.y ); } }
容器SimpleDraw:
/* Generated by Together */ package com.javapatterns.command.drawlines; import java.applet.Applet; import java.awt.BorderLayout; import java.awt.Button; import java.awt.Panel; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; // 請求者(負責調用命令對象執行請求) public class SimpleDraw extends Applet implements ActionListener { private static final long serialVersionUID = 2317696438230972428L; private Drawing drawing;// 畫布 private CommandList commands;// 命令集合 private Button undoButton;// 撤銷按鈕 private Button redoButton;// 恢複按鈕 private Button resetButton;// 清空撤銷和恢複按鈕 public void init() { Panel panel = new Panel();// 麵板 commands = new CommandList();// 初始化命令集合 setLayout(new BorderLayout());// 設置布局 drawing = new Drawing(this);// 初始化畫布 add("Center", drawing); undoButton = new Button("撤銷");// 初始化撤銷按鈕 redoButton = new Button("恢複");// 初始化恢複按鈕 resetButton = new Button("重置"); undoButton.addActionListener(this);// 添加按鈕監聽器 redoButton.addActionListener(this);// 添加按鈕監聽器 resetButton.addActionListener(this);// 添加按鈕監聽器 panel.add(undoButton); panel.add(redoButton); panel.add(resetButton); add("South", panel); updateButtons();// 初始化按鈕狀態 } public void execute(Command command) { commands.execute(command);// 執行命令 updateButtons(); } // 更新按鈕狀態(根據是否能夠undo撤銷或者是否能夠redo恢複) private void updateButtons() { undoButton.setEnabled(commands.canUnexecuteCommand()); redoButton.setEnabled(commands.canReexecuteCommand()); } // 當點擊撤銷按鈕或者恢複按鈕時出發該方法執行 public void actionPerformed(ActionEvent event) { if (event.getSource() == undoButton) { commands.unexecute(); updateButtons(); }else if (event.getSource() == redoButton) { commands.reexecute(); updateButtons(); }else if (event.getSource() == resetButton) { commands.reset(); updateButtons(); } } }
實例下載:
https://download.csdn.net/detail/yang_hui1986527/3840789
最後更新:2017-04-02 06:52:11